├── .build
├── .k.rev
├── .kevm.rev
└── concrete-rules.txt
├── .editorconfig
├── .gitignore
├── .gitmodules
├── .travis.yml
├── Dockerfile
├── Jenkinsfile
├── LICENSE.md
├── Makefile
├── README.md
├── bihu
├── Makefile
├── README.md
├── bihu-contracts-verification-report.pdf
├── collectToken-spec.ini
├── collectToken-spec.k
├── collectToken
│ ├── KeyRewardPool.inlined.gist
│ ├── KeyRewardPool.inlined.sol
│ ├── KeyRewardPool.modified.inlined.bytes
│ ├── KeyRewardPool.modified.inlined.evm
│ ├── KeyRewardPool.modified.inlined.gist
│ └── KeyRewardPool.modified.inlined.sol
├── forwardToHotWallet-spec.ini
├── forwardToHotWallet
│ ├── WarmWallet.inlined.gist
│ ├── WarmWallet.inlined.sol
│ ├── WarmWallet.modified.inlined.bytes
│ ├── WarmWallet.modified.inlined.evm
│ ├── WarmWallet.modified.inlined.gist
│ └── WarmWallet.modified.inlined.sol
├── module-tmpl.k
├── spec-tmpl.k
└── verification.k
├── casper
├── Makefile
├── README.md
├── abstract-casper.k
├── abstract-semantics.k
├── casper-spec.ini
├── casper.k
├── casper.lll
├── module-tmpl.k
├── protocol-verification.md
├── real.k
├── reward-penalty-model.pdf
├── reward-penalty-model.tex
├── simple_casper.v.py
├── spec-tmpl.k
└── verification.k
├── deposit
├── README.md
├── algorithm-correctness
│ ├── README.md
│ ├── deposit-spec.k
│ ├── deposit-spec.k.out
│ ├── deposit-symbolic.k
│ ├── deposit.k
│ ├── imap.k
│ ├── imap.smt2
│ ├── run.sh
│ ├── test.deposit
│ └── test.deposit.out
├── bytecode-verification
│ ├── .build
│ │ ├── .kevm.rev
│ │ └── concrete-rules.txt
│ ├── Makefile
│ ├── README.md
│ ├── abstract-semantics.k
│ ├── deposit-spec-full.ini
│ ├── deposit-spec.ini
│ ├── deposit-spec.ini.md
│ ├── evm.smt2
│ ├── lemmas.k
│ ├── module-tmpl.k
│ ├── spec-tmpl.k
│ └── verification.k
├── deposit-formal-verification.pdf
└── formal-incremental-merkle-tree-algorithm.pdf
├── erc20
├── .build
│ ├── .kevm.rev
│ └── concrete-rules.txt
├── README.md
├── all
│ ├── contracts
│ │ ├── 01_tether.sol
│ │ ├── 02_bnb.sol
│ │ ├── 03_bitfinex.sol
│ │ ├── 04_chainlink.sol
│ │ ├── 05_huobi.sol
│ │ ├── 06_maker.sol
│ │ ├── 07_usdc.sol
│ │ ├── 08_crypto.sol
│ │ ├── 09_ino.sol
│ │ ├── 10_bat.sol
│ │ ├── 11_insight.sol
│ │ ├── 12_paxos.sol
│ │ ├── 13_hedg.sol
│ │ ├── 14_zrx.sol
│ │ ├── 15.1_vechain.sol
│ │ ├── 15.2_trueusd.sol
│ │ ├── 17_holo.sol
│ │ ├── 18_omisego.sol
│ │ ├── 20_centrality.sol
│ │ ├── 21_bytom.sol
│ │ ├── 22_kucoin.sol
│ │ ├── 23_ekt.sol
│ │ ├── 24_synthetix.sol
│ │ ├── 25_reputation.sol
│ │ ├── 26_theta.sol
│ │ ├── 27_swipe.sol
│ │ ├── 28_dai.sol
│ │ ├── 29_icon.sol
│ │ ├── 30_karat.sol
│ │ ├── 31_mixin.sol
│ │ ├── 33_ios.sol
│ │ ├── 34_quant.sol
│ │ ├── 35_mco.sol
│ │ ├── 36_aeternity.sol
│ │ ├── 39_nexo.sol
│ │ ├── 40_clipper.sol
│ │ ├── 41_rlc.sol
│ │ ├── 44_noah.sol
│ │ ├── 45_kyber.sol
│ │ ├── 46_BitMax.sol
│ │ ├── 47_DxChain.sol
│ │ ├── 48_matic.sol
│ │ ├── 49_snt.sol
│ │ ├── 51_cryptoindex.sol
│ │ ├── 52_banker.sol
│ │ ├── 53_golem.sol
│ │ ├── 54_mana.sol
│ │ ├── 55_elf.sol
│ │ ├── 56_aion.sol
│ │ ├── 57_republic.sol
│ │ └── code review.md
│ ├── demo-specs
│ │ ├── Makefile
│ │ ├── certora-buggy.ini
│ │ ├── certora-fixed.ini
│ │ ├── consensys.ini
│ │ ├── hkg.ini
│ │ ├── hobby.ini
│ │ ├── vyper.ini
│ │ ├── zeppelin-new.ini
│ │ └── zeppelin.ini
│ ├── fragments-solar
│ │ ├── allowance.ini
│ │ ├── approve.ini
│ │ ├── balanceOf.ini
│ │ ├── root.ini
│ │ ├── totalSupply.ini
│ │ ├── transfer.ini
│ │ └── transferFrom.ini
│ ├── fragments
│ │ ├── allowance.ini
│ │ ├── approve.ini
│ │ ├── balanceOf.ini
│ │ ├── root.ini
│ │ ├── totalSupply.ini
│ │ ├── transfer.ini
│ │ └── transferFrom.ini
│ ├── mainnet-solar-specs
│ │ ├── 01_tether.ini.disable
│ │ ├── 02_bnb.ini
│ │ ├── 04_chainlink.ini
│ │ ├── 05_huobi.ini
│ │ ├── 06_maker.ini
│ │ ├── 08_crypto.ini
│ │ ├── 09_ino.ini
│ │ ├── 10_bat.ini
│ │ ├── 11_insight.ini
│ │ ├── 13_hedg.ini
│ │ ├── 14_zrx.ini
│ │ └── Makefile
│ ├── mainnet-solar-test
│ │ ├── 14_zrx.ini
│ │ └── Makefile
│ ├── mainnet-specs
│ │ ├── 01_tether.ini.disable
│ │ ├── 02_bnb.ini
│ │ ├── 04_chainlink.ini
│ │ ├── 05_huobi.ini
│ │ ├── 06_maker.ini
│ │ ├── 08_crypto.ini
│ │ ├── 09_ino.ini
│ │ ├── 10_bat.ini
│ │ ├── 11_insight.ini
│ │ ├── 13_hedg.ini
│ │ ├── 14_zrx.ini
│ │ └── Makefile
│ ├── mainnet-test
│ │ ├── 14_zrx.ini
│ │ └── Makefile
│ └── resources
│ │ ├── get-bytecode.py
│ │ ├── kprove-erc20-group.mak
│ │ ├── kprove-erc20-solar.mak
│ │ ├── kprove-erc20.mak
│ │ └── spec-tmpl.k
├── ds-token
│ ├── Makefile
│ ├── README.md
│ ├── base.sol
│ ├── ds-token-erc20-spec.ini
│ ├── spec-diff.patch
│ ├── token.bytes
│ ├── token.evm
│ └── token.sol
├── evm-data-map-symbolic.k
├── gno
│ ├── Makefile
│ ├── README.md
│ ├── gno-erc20-spec.ini
│ ├── gno-erc20.bytes
│ ├── program.k
│ └── spec-tmpl.k
├── hkg
│ ├── Makefile
│ ├── README.md
│ ├── StandardToken.inlined.buggy.sol
│ ├── StandardToken.inlined.bytes
│ ├── StandardToken.inlined.evm
│ ├── StandardToken.inlined.gist
│ ├── StandardToken.inlined.json
│ ├── StandardToken.inlined.sol
│ ├── hkg-erc20-spec.ini
│ └── spec-diff.patch
├── hobby
│ ├── Makefile
│ ├── MyKidsEducationToken.buggy.sol
│ ├── MyKidsEducationToken.fixed.bytes
│ ├── MyKidsEducationToken.fixed.evm
│ ├── MyKidsEducationToken.fixed.gist
│ ├── MyKidsEducationToken.fixed.sol
│ ├── README.md
│ ├── hobby-erc20-spec.ini
│ └── spec-diff.patch
├── module-tmpl.k
├── resources-concrete
│ └── verification.k
├── solar
│ ├── Makefile
│ ├── module-tmpl.k
│ ├── solar-abstract-semantics.k
│ ├── solar-erc20-spec.ini
│ ├── spec-tmpl.k
│ └── verification-solar.k
├── spec-tmpl.k
├── verification.k
├── vyper
│ ├── .build
│ │ └── .kevm.rev
│ ├── ERC20.v.bytes
│ ├── ERC20.v.evm
│ ├── ERC20.v.py
│ ├── Makefile
│ ├── README.md
│ ├── lemmas-buf.md
│ ├── module-tmpl.k
│ ├── spec-tmpl.k
│ ├── vyper-erc20-spec.ini
│ └── vyper-verification.k
└── zeppelin
│ ├── Makefile
│ ├── README.md
│ ├── StandardToken.inlined.bytes
│ ├── StandardToken.inlined.evm
│ ├── StandardToken.inlined.gist
│ ├── StandardToken.inlined.sol
│ ├── spec-diff.patch
│ └── zeppelin-erc20-spec.ini
├── gnosis
├── .build
│ └── .kevm.rev
├── GnosisSafe_RuntimeVerification.pdf
├── GnosisSafe_RuntimeVerification_Audit.pdf
├── Makefile
├── abstract-semantics-segmented-gas.k
├── abstract-semantics.k
├── bmc
│ ├── Makefile
│ ├── generated-external-contract
│ │ ├── ExternalContract.sol
│ │ └── gnosis-testing-ExternalContract.hex
│ └── gnosis-bmc-spec.ini
├── evm.smt2
├── generated
│ ├── Proxy.evm
│ ├── gnosis-GnosisSafe-0.1.0.evm
│ ├── gnosis-GnosisSafe-0.1.0.hex
│ ├── gnosis-GnosisSafe-program-cell.txt
│ ├── gnosis-Proxy-0.1.0.hex
│ ├── rv-GnosisSafe-0.1.0-solc-0.5.1.evm
│ ├── rv-GnosisSafe-0.1.0-solc-0.5.1.hex
│ └── solidity compilation instructions.txt
├── gnosis-spec.ini
├── module-tmpl.k
├── old
│ ├── PROPOSAL.md
│ ├── issues.md
│ ├── old-issues.md
│ └── pseudo-spec.md
├── scripts
│ └── hex_to_decimal.py
├── spec-tmpl.k
├── test
│ ├── ApiTest.hex
│ ├── ApiTest.sol
│ ├── Makefile
│ └── api-test-spec.ini
└── verification.k
├── k-test
├── KTest.sol
├── Makefile
├── abstract-semantics.k
├── k-test-spec.ini
├── smt-prelude.smt2
├── spec-tmpl.k
└── verification.k
├── proxied-token
├── Makefile
├── README.md
├── deployed.sol
├── module-tmpl.k
├── proxied-token-spec.ini
├── spec-tmpl.k
└── verification.k
├── resources
├── Makefile
├── abstract-semantics-direct-gas.k
├── abstract-semantics-segmented-gas.k
├── balanceOf-spec.k
├── build-html.sh
├── debugging.md
├── ecrec-symbolic.k
├── edsl-notations.md
├── edsl-spec.md
├── edsl.md
├── erc20-evm.md
├── evm-data-map-concrete.k
├── evm-data-map-symbolic.k
├── evm-direct-gas.k
├── evm-symbolic.k
├── evm.smt2
├── gen-spec.py
├── instructions.md
├── kprove-group.mak
├── kprove-tutorial.md
├── kprove.mak
├── lemmas-buf.md
├── lemmas.md
├── not-KLabel.k
├── pdf-icon.png
├── relink.lua
└── sum-to-n.md
├── run-proofs.sh
├── script
├── dkprove.sh
└── kprove_log.py
└── uniswap
├── .build
└── .kevm.rev
├── Makefile
├── README.md
├── abstract-semantics.k
├── code
├── bytes.txt
├── lll.txt
└── uniswap_exchange.vy
├── issues.md
├── lemmas.md
├── module-tmpl.k
├── results
├── README.md
├── addLiquidity-1.txt
├── addLiquidity-2.txt
├── ethToTokenSwapInput.txt
├── ethToTokenSwapOutput.txt
└── removeLiquidity.txt
├── spec-tmpl.k
├── uniswap-spec.ini
├── verification.k
└── x-y-k.pdf
/.build/.k.rev:
--------------------------------------------------------------------------------
1 | a61af7e96e94e83485ada3f5ebaf22277f972cbb
2 |
--------------------------------------------------------------------------------
/.build/.kevm.rev:
--------------------------------------------------------------------------------
1 | 004de7f6ef8b8509f033ef846fc81517c4980134
2 |
--------------------------------------------------------------------------------
/.build/concrete-rules.txt:
--------------------------------------------------------------------------------
1 | EDSL.#ceil32
2 | EDSL.keccakIntList
3 | EVM-TYPES.#signed.positive
4 | EVM-TYPES.#signed.negative
5 | EVM-TYPES.#unsigned.positive
6 | EVM-TYPES.#unsigned.negative
7 | EVM-TYPES.powmod.nonzero
8 | EVM-TYPES.powmod.zero
9 | EVM-TYPES.signextend.invalid
10 | EVM-TYPES.signextend.negative
11 | EVM-TYPES.signextend.positive
12 | SERIALIZATION.keccak
13 | EVM-TYPES.#take.zero-pad
14 | EVM-TYPES.#asWord.recursive
15 | EVM-TYPES.#asByteStack
16 | EVM-TYPES.#asByteStackAux.recursive
17 | EVM-TYPES.#padToWidth
18 | EVM-TYPES.#padRightToWidth
19 | SERIALIZATION.#newAddr
20 | SERIALIZATION.#newAddrCreate2
21 | EVM-TYPES.mapWriteBytes.recursive
22 | EVM-TYPES.#range
23 | EVM-TYPES.#lookup.some
24 | EVM-TYPES.#lookup.none
25 | EVM.#memoryUsageUpdate.some
26 | EVM.Cgascap
27 | EVM.Csstore.new
28 | EVM.Csstore.old
29 | EVM.Rsstore.new
30 | EVM.Rsstore.old
31 | EVM.Cextra
32 | EVM.Cmem
33 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Root-level editorconfig.
2 | root = true
3 |
4 | # Applies to every file:
5 | # - make sure newlines are unix-stile
6 | # - remove whitespace at the end of lines
7 | [*]
8 | end_of_line = lf
9 | trim_trailing_whitespace = true
10 |
11 | # Applies to ini, k, md and smt2 files:
12 | # - indent using 4 spaces
13 | [*.{ini,k,md,smt2}]
14 | indent_style = space
15 | indent_size = 4
16 |
17 | [*.{patch,diff}]
18 | trim_trailing_whitespace = false
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | /.build/*
4 | !/.build/pandoc-tangle
5 |
6 | /specs/*
7 |
8 | *.html
9 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule ".build/pandoc-tangle"]
2 | path = .build/pandoc-tangle
3 | url = https://github.com/ehildenb/pandoc-tangle
4 | ignore = untracked
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 |
3 | before_install:
4 | - wget https://github.com/jgm/pandoc/releases/download/2.1.1/pandoc-2.1.1-1-amd64.deb
5 | - sudo dpkg -i pandoc-2.1.1-1-amd64.deb
6 | - pandoc --version
7 | - wget https://github.com/Z3Prover/z3/releases/download/z3-4.6.0/z3-4.6.0-x64-ubuntu-14.04.zip
8 | - unzip z3-4.6.0-x64-ubuntu-14.04.zip
9 | - export PATH=$PATH:$PWD/z3-4.6.0-x64-ubuntu-14.04/bin
10 | - z3 --version
11 | - nproc
12 | - cat /proc/meminfo
13 | - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
14 | - echo ${BRANCH#travis-test-}
15 | - export EXT_KPROVE_OPTS=--log-progress
16 | # - export K_OPTS=-Xmx6g
17 | # - travis_wait 30 sleep 1800 &
18 |
19 | language: java
20 | script: make all test MODE=${BRANCH#travis-test-}
21 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:bionic
2 |
3 | ENV TZ=America/Chicago
4 | RUN ln --symbolic --no-dereference --force /usr/share/zoneinfo/$TZ /etc/localtime \
5 | && echo $TZ > /etc/timezone
6 |
7 | RUN apt update \
8 | && apt upgrade --yes \
9 | && apt install --yes \
10 | autoconf bison build-essential clang++-6.0 clang-6.0 cmake coreutils \
11 | curl diffutils flex gcc git gnupg libboost-test-dev libffi-dev \
12 | libgmp-dev libjemalloc-dev libmpfr-dev libstdc++6 libtool libxml2 \
13 | libyaml-cpp-dev llvm-6.0 m4 make maven opam openjdk-8-jdk pandoc \
14 | pkg-config python3 python-jinja2 python-pygments python-recommonmark \
15 | python-sphinx scala time unifdef zlib1g-dev
16 |
17 | RUN update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
18 |
19 | RUN curl -sSL https://get.haskellstack.org/ | sh
20 |
21 | RUN git clone 'https://github.com/z3prover/z3' --branch=z3-4.6.0 \
22 | && cd z3 \
23 | && python scripts/mk_make.py \
24 | && cd build \
25 | && make -j8 \
26 | && make install \
27 | && cd ../.. \
28 | && rm -rf z3
29 |
30 | ARG USER_ID=1000
31 | ARG GROUP_ID=1000
32 | RUN groupadd --gid $GROUP_ID user \
33 | && useradd --create-home --uid $USER_ID --shell /bin/sh --gid user user
34 |
35 | USER $USER_ID:$GROUP_ID
36 |
37 | RUN cd /home/user \
38 | && git clone 'https://github.com/kframework/k' --branch=nightly-0f3835d3a \
39 | && ./k/k-distribution/src/main/scripts/bin/k-configure-opam-dev \
40 | && rm -rf k
41 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # Reproducibility License 1.1.0
2 |
3 | ## Acceptance
4 |
5 | In order to get any license under these terms, you must
6 | agree to their rules. Those rules are both obligations
7 | under your agreement and conditions to all your licenses.
8 |
9 | ## Reproducibility
10 |
11 | These terms license you _only_ for the following purposes:
12 |
13 | 1. You may reproduce published research results that the
14 | licensor achieved using this software.
15 |
16 | 2. You may produce and reproduce research results of your
17 | own, and of others, only for noncommercial purposes.
18 |
19 | These terms do _not_ license you for any other purpose,
20 | such as producing or reproducing new research results for
21 | commercial purposes.
22 |
23 | ## Copyright
24 |
25 | The licensor grants you a copyright license for
26 | the software. That license covers everything you
27 | might do with the software that would infringe the
28 | licensor's copyright in it, for the purposes permitted
29 | in [Reproducibility](#reproducibility). That license
30 | does _not_ cover making changes or new work based on the
31 | software or removing this license from the software.
32 |
33 | ## Patent
34 |
35 | The licensor grants you a patent license for the software.
36 | That license covers patent claims the licensor can
37 | license, or becomes able to license, that you would have to
38 | infringe to use the software for the purposes permitted in
39 | [Reproducibility](#reproducibility). That license does
40 | _not_ cover selling the software.
41 |
42 | ## Patent Defense
43 |
44 | If you or any affiliated company makes any written claim
45 | alleging that the software infringes or contributes to
46 | infringement of a patent, your patent license under these
47 | terms ends immediately.
48 |
49 | ## No Other Rights
50 |
51 | These terms do not allow you to sublicense or transfer
52 | any licenses to anyone else, or prevent the licensor from
53 | granting licenses to anyone else. These terms do not
54 | imply any other licenses.
55 |
56 | ## Reliability
57 |
58 | The licensor may not revoke any license under these terms.
59 |
60 | ## No Liability
61 |
62 | ***As far as the law allows, this software comes as is,
63 | without any warranty or condition, and the licensor will
64 | not be liable to anyone for any damages related to this
65 | software or this license, under any kind of legal claim.***
66 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .NOTPARALLEL:
2 |
3 | MINIMAL_DIRS:= resources erc20/vyper erc20/zeppelin
4 | KTEST_DIRS:= k-test
5 | ERC20_DIRS:= erc20/hkg erc20/hobby erc20/ds-token
6 | SOLAR_DIRS:= erc20/solar
7 | DEPOSIT_DIRS:= deposit/bytecode-verification
8 | GNOSIS_DIRS:= gnosis gnosis/test
9 | GNOSIS_BMC_DIRS:=gnosis/bmc
10 | BIHU_DIRS:= bihu
11 | DOM_DIRS:= erc20/gno proxied-token
12 | # fails - needs updates in verification.k
13 | CASPER_DIRS:= casper
14 | # fails - has to get rid of custom lemmas.md
15 | UNISWAP_DIRS:= uniswap
16 |
17 | JENKINS_DIRS:=$(MINIMAL_DIRS) $(KTEST_DIRS) $(ERC20_DIRS) $(GNOSIS_DIRS) $(BIHU_DIRS)
18 | ALL_DIRS:= $(JENKINS_DIRS) $(DEPOSIT_DIRS) $(GNOSIS_BMC_DIRS) $(DOM_DIRS) $(CASPER_DIRS) $(UNISWAP_DIRS)
19 |
20 | # For MODE=foo, SUBDIRS will be FOO_DIRS
21 | SUBDIRS:=$($(shell echo $(MODE) | tr a-z A-Z)_DIRS)
22 |
23 | include resources/kprove-group.mak
24 |
--------------------------------------------------------------------------------
/bihu/Makefile:
--------------------------------------------------------------------------------
1 | #BUILD_DIR:=../erc20/.build
2 |
3 | SPEC_INI:=forwardToHotWallet-spec.ini
4 |
5 | SPEC_NAMES:=collectToken \
6 | forwardToHotWallet-success-1 \
7 | forwardToHotWallet-success-2 \
8 | forwardToHotWallet-failure-1 \
9 | forwardToHotWallet-failure-2 \
10 | forwardToHotWallet-failure-3 \
11 | forwardToHotWallet-failure-4
12 |
13 | include ../resources/kprove.mak
14 |
15 | COLLECTION_TOKEN_INI:=collectToken-spec.ini
16 |
17 | # non-standard spec generation
18 | $(SPECS_DIR)/$(SPEC_GROUP)/collectToken-spec.k: $(TMPLS) $(COLLECTION_TOKEN_INI) $(LEMMAS)
19 | python3 $(RESOURCES)/gen-spec.py $(TMPLS) $(COLLECTION_TOKEN_INI) collectToken collectToken loop ds-math-mul > $@
20 |
--------------------------------------------------------------------------------
/bihu/bihu-contracts-verification-report.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runtimeverification/verified-smart-contracts/e61ef57de99d07d7182436490f152a14621c5a82/bihu/bihu-contracts-verification-report.pdf
--------------------------------------------------------------------------------
/bihu/collectToken/KeyRewardPool.inlined.gist:
--------------------------------------------------------------------------------
1 | https://gist.github.com/anonymous/08052033a247f241c9519e41d6fcd27d
2 |
--------------------------------------------------------------------------------
/bihu/collectToken/KeyRewardPool.modified.inlined.bytes:
--------------------------------------------------------------------------------
1 | 0x60606040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630e4aed3f1461007257806340ba126b1461009b578063787e9137146100db578063b69ef8a814610104578063b93e2cdb1461012d575b600080fd5b341561007d57600080fd5b610085610171565b6040518082815260200191505060405180910390f35b34156100a657600080fd5b6100c56004808035906020019091908035906020019091905050610176565b6040518082815260200191505060405180910390f35b34156100e657600080fd5b6100ee6101a8565b6040518082815260200191505060405180910390f35b341561010f57600080fd5b6101176101ae565b6040518082815260200191505060405180910390f35b341561013857600080fd5b61015760048080359060200190919080359060200190919050506101b4565b604051808215151515815260200191505060405180910390f35b600a81565b600081831061019d576301e1338061018e84846102bc565b81151561019757fe5b046101a0565b60005b905092915050565b60005481565b60015481565b600080600080600080600080888a1115156101ce57600080fd5b6101dc6000546001546102d5565b96508695506101eb8a8a610176565b9450600093505b848410156102215761021261020b87600a6064036102ee565b606461031c565b955083806001019450506101f2565b61023661022f87600a6102ee565b606461031c565b9250610260610256846301e133808c8e0381151561025057fe5b066102ee565b6301e1338061031c565b915085870382019050610275816000546102bc565b90506001548111156102875760015490505b610293600054826102d5565b6000819055506102a5600154826102bc565b600181905550600197505050505050505092915050565b600082828403915081111515156102cf57fe5b92915050565b600082828401915081101515156102e857fe5b92915050565b60008183029050600083148061030e575081838281151561030b57fe5b04145b151561031657fe5b92915050565b6000818381151561032957fe5b049050929150505600a165627a7a72305820d8edeeb44c8346eca139385cfaecddeb8b02fcc380c3b54473746e8103ff62e70029
2 |
--------------------------------------------------------------------------------
/bihu/collectToken/KeyRewardPool.modified.inlined.gist:
--------------------------------------------------------------------------------
1 | https://gist.github.com/anonymous/61b969d0f7af252a54f48f4b50f2c3f5
2 |
--------------------------------------------------------------------------------
/bihu/forwardToHotWallet/WarmWallet.inlined.gist:
--------------------------------------------------------------------------------
1 | https://gist.github.com/anonymous/c95f67810dff2af73b240c78aab4e3b9
2 |
--------------------------------------------------------------------------------
/bihu/forwardToHotWallet/WarmWallet.modified.inlined.gist:
--------------------------------------------------------------------------------
1 | https://gist.github.com/anonymous/b7773008aa9dc75815f1c6ecfb7224a0
2 |
--------------------------------------------------------------------------------
/bihu/module-tmpl.k:
--------------------------------------------------------------------------------
1 | requires "abstract-semantics-direct-gas.k"
2 | requires "verification.k"
3 |
4 | module {MODULE}-SPEC
5 | imports ABSTRACT-SEMANTICS-DIRECT-GAS
6 | imports VERIFICATION
7 |
8 | {RULES}
9 |
10 | endmodule
11 |
--------------------------------------------------------------------------------
/bihu/spec-tmpl.k:
--------------------------------------------------------------------------------
1 | // {RULENAME}
2 | rule
3 | {K}
4 | 1
5 | NORMAL
6 | BYZANTIUM
7 |
8 |
9 |
10 |
11 | {STATUSCODE}
12 | _ => _
13 | _
14 | _ => _
15 |
16 |
17 | #parseByteStack({CODE})
18 | #computeValidJumpDests(#parseByteStack({CODE}))
19 |
20 | ACCT_ID // contract owner
21 | CALLER_ID // who called this contract; in the begining, origin // msg.sender
22 |
23 | {CALLDATA}
24 |
25 | 0
26 | {WORDSTACK}
27 | {LOCALMEM}
28 | {PC}
29 | {GAS}
30 | {MEMORYUSED}
31 | _ => _
32 |
33 | false // NOTE: non-static call
34 | CALL_DEPTH
35 |
36 |
37 |
38 | _
39 | {LOG}
40 | {REFUND} // TODO: more detail
41 |
42 |
43 | _
44 | ORIGIN_ID // who fires tx
45 | _
46 |
47 | _
48 | _
49 | _
50 | _
51 | _
52 | _
53 | _
54 | _
55 | _
56 | _
57 | _
58 | NOW // block.timestamp // now
59 | _
60 | _
61 | _
62 |
63 | _
64 |
65 |
66 |
67 |
68 | 0
69 | SetItem(ACCT_ID) _:Set
70 |
71 |
72 |
73 | ACCT_ID
74 | _
75 | #parseByteStack({CODE})
76 |
77 | {STORAGE}
78 |
79 | _
80 | _
81 |
82 | // ... // TODO: fix
83 |
84 |
85 | _
86 | _
87 | _
88 |
89 |
90 | requires 0 <=Int ACCT_ID andBool ACCT_ID LT W0 W1 => bool2Word(W0 #push ... [trusted]
5 |
6 | rule GT W0 W1 => bool2Word(W0 >Int W1) ~> #push ... [trusted]
7 |
8 | rule EQ W0 W1 => bool2Word(W0 ==Int W1) ~> #push ... [trusted]
9 |
10 | rule ISZERO W => bool2Word(W ==Int 0 ) ~> #push ... [trusted]
11 |
12 | rule SLT W0 W1 => W0 s #push ... [trusted]
13 | rule SGT W0 W1 => W1 s #push ... [trusted]*/
14 |
15 | rule #gasExec(SCHED, EXP W0 W1) => Gexp < SCHED > +Int (Gexpbyte < SCHED > *Int 32) ...
16 | requires W1 =/=K 0 [trusted]
17 |
18 | rule #gasExec(SCHED, SSTORE INDEX VALUE) => Gsstoreset < SCHED > ... [trusted]
19 |
20 | rule Ccallgas(SCHED, ISEMPTY:Bool, GCAP, GAVAIL, 0) => Cgascap(SCHED, GCAP, GAVAIL, Cextra(SCHED, 0, ISEMPTY)) ... [trusted]
21 |
22 | rule Ccallgas(SCHED, ISEMPTY:Bool, GCAP, GAVAIL, VALUE)
23 | => Cgascap(SCHED, GCAP, GAVAIL, Cextra(SCHED, VALUE, ISEMPTY)) +Int Gcallstipend < SCHED > ...
24 | requires VALUE =/=Int 0 [trusted]
25 |
26 | endmodule
27 |
--------------------------------------------------------------------------------
/casper/module-tmpl.k:
--------------------------------------------------------------------------------
1 | requires "abstract-semantics.k"
2 | requires "verification.k"
3 |
4 | module {MODULE}-SPEC
5 | imports ABSTRACT-SEMANTICS
6 | imports VERIFICATION
7 |
8 | {RULES}
9 |
10 | endmodule
11 |
--------------------------------------------------------------------------------
/casper/real.k:
--------------------------------------------------------------------------------
1 | requires "domains.k"
2 |
3 | module REAL-SYNTAX
4 | syntax Real [hook(REAL.Real)]
5 | syntax Real ::= r"[\\+-]?[0-9]+\\.[0-9]+" [prefer, token, prec(2)] // [token, prec(1)]
6 | endmodule
7 |
8 | module REAL
9 | imports REAL-SYNTAX
10 | imports BOOL
11 | imports INT-SYNTAX
12 |
13 | syntax Real ::= "--Real" Real [function, smtlib(-), hook(REAL.neg)]
14 | > Real "^Real" Real [function, left, hook(REAL.pow)]
15 | > left:
16 | Real "*Real" Real [function, left, smtlib(*), hook(REAL.mul)]
17 | | Real "/Real" Real [function, left, smtlib(div), hook(REAL.div)]
18 | > left:
19 | Real "+Real" Real [function, left, smtlib(+), hook(REAL.add)]
20 | | Real "-Real" Real [function, left, smtlib(-), hook(REAL.sub)]
21 |
22 | syntax Bool ::= Real "<=Real" Real [function, left, smtlib(<=), hook(REAL.le)]
23 | | Real "=Real" Real [function, left, smtlib(>=), hook(REAL.ge)]
25 | | Real ">Real" Real [function, left, smtlib(>), hook(REAL.gt)]
26 | | Real "==Real" Real [function, left, smtlib(==), hook(REAL.eq), klabel(_==Real_)]
27 | | Real "=/=Real" Real [function, left, smtlib((not (== #1 #2)))]
28 |
29 | rule F1:Real =/=Real F2:Real => notBool (F1 ==Real F2)
30 |
31 | syntax Real ::= rootReal(Real, Int) [function, hook(REAL.root)]
32 | | sqrtReal(Real) [function]
33 | | absReal(Real) [function, smtlib(abs), hook(REAL.abs)]
34 | | floorReal(Real) [function, hook(REAL.floor)]
35 | | ceilReal(Real) [function, hook(REAL.ceil)]
36 | | expReal(Real) [function, hook(REAL.exp)]
37 | | logReal(Real) [function, hook(REAL.log)]
38 | | sinReal(Real) [function, hook(REAL.sin)]
39 | | cosReal(Real) [function, hook(REAL.cos)]
40 | | tanReal(Real) [function, hook(REAL.tan)]
41 | | asinReal(Real) [function, hook(REAL.asin)]
42 | | acosReal(Real) [function, hook(REAL.acos)]
43 | | atanReal(Real) [function, hook(REAL.atan)]
44 | | atan2Real(Real, Real) [function, hook(REAL.atan2)]
45 | | maxReal(Real, Real) [function, smtlib(max), hook(REAL.max)]
46 | | minReal(Real, Real) [function, smtlib(min), hook(REAL.min)]
47 |
48 | rule sqrtReal(R:Real) => rootReal(R, 2)
49 |
50 | syntax Real ::= Int2Real(Int) [function, hook(REAL.int2real)]
51 | syntax Int ::= Real2Int(Real) [function, hook(REAL.real2int)]
52 |
53 | endmodule
54 |
55 |
--------------------------------------------------------------------------------
/casper/reward-penalty-model.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runtimeverification/verified-smart-contracts/e61ef57de99d07d7182436490f152a14621c5a82/casper/reward-penalty-model.pdf
--------------------------------------------------------------------------------
/casper/reward-penalty-model.tex:
--------------------------------------------------------------------------------
1 | \section{Reward-Penalty Model}
2 |
3 | Let $V \in \V$ be a validator.
4 | Let $D^V_i$ be the deposit (in \t{ether}) of $V$ in epoch $i$.
5 | Let $\D_i \defeq \Sigma_{V \in \V} D^V_i$ be the total amount of deposits (in \t{ether}) in epoch $i$.
6 | Let $\RF_i$ be a reward-penalty factor in epoch $i$.
7 |
8 | In each epoch $i$, validator $V$ gets reward and/or penalty as follows.
9 | \lst{
10 | \i $V$ pays a fee for each epoch whether or not he votes.
11 | \i $V$ gets a reward, if he votes ``correctly'' --- the source epoch of the vote is equal to the recommended one.
12 | \i $V$ gets another reward, if epoch $i-1$ is finalized at the end of epoch $i$.
13 | }
14 | Given $D^V_i$ and $\RF_i$, $D^V_{i+1}$ is defined for each case as follows.
15 | Note that ``incorrect vote'' entails ``no vote''.
16 | \[
17 | D^V_{i+1} \defeq
18 | \begin{cases}
19 | D^V_i \cdot \dfrac{1}{1 + \RF_i} & \m{if $V$ does \emph{not} vote (correctly), and epoch $i-1$ is \emph{not} finalized}
20 | \\[11pt] D^V_i \cdot \dfrac{1}{1 + \RF_i} \cdot (1 + \dfrac{\alpha}{2} \RF_i) & \m{if $V$ does \emph{not} vote (correctly), but epoch $i-1$ is finalized}
21 | \\[11pt] D^V_i \cdot \dfrac{1}{1 + \RF_i} \cdot (1 + \RF_i) & \m{if $V$ votes correctly, but epoch $i-1$ is \emph{not} finalized}
22 | \\[11pt] D^V_i \cdot \dfrac{1}{1 + \RF_i} \cdot (1 + \RF_i) \cdot (1 + \dfrac{\alpha}{2} \RF_i) & \m{if $V$ votes correctly, and epoch $i-1$ is finalized}
23 | \end{cases}
24 | \]
25 | Here, $\alpha$ is the fraction of the correct votes in the total deposit $\D_i$.
26 | Since $\alpha$ is used only when epoch $i-1$ is finalized (which implies the current epoch $i$ is justified),
27 | we have $\frac{2}{3} \le \alpha \le 1$.
28 |
29 | At the beginning of the next epoch $i+1$,
30 | the reward factor $\RF_{i+1}$ is also adjusted based on the current total deposit and the history of finalization as follows:
31 | \[
32 | \RF_{i+1} \defeq \dfrac{\beta}{\sqrt{\D_{i}}} + \gamma \cdot (\ESF - 2)
33 | \]
34 | where $\beta$ is a fixed base interest factor,
35 | and $\gamma$ is a fixed base penalty factor.
36 | \ESF is the number of epochs since the last finalized epoch.
37 | We have $\ESF \ge 2$,
38 | at the beginning of epoch $i+1$,
39 | since the latest possible finalized epoch is $i-1$.
40 |
41 | \begin{lemma}
42 | We have the followings:
43 | \lst{
44 | \i If $V$ votes correctly, his deposit \emph{never} decrease, i.e., $D^V_{i+1} \ge D^V_{i}$.
45 | \i If $V$ does not votes correctly (or does not vote at all), his deposit strictly decreases, i.e., $D^V_{i+1} < D^V_i$.
46 | \i In an ideal situation (all validators vote correctly and every epoch is finalized),
47 | each validator's deposit strictly increases for each epoch, i.e., $D^V_{i+1} > D^V_{i}$,
48 | and the reward factor strictly decreases for each epoch, i.e., $\RF_{i+1} < \RF_i$.
49 | % where the rate of increase is reduced, i.e.,
50 | % \[
51 | % 0 ~<~ D^V_{i+2} - D^V_{i+1} ~<~ D^V_{i+1} - D^V_{i} ~\le~ \frac{D^V_i \cdot \RF_i}{2}
52 | % \]
53 | \i The above holds for both positive and negative $\gamma$.
54 | }
55 | \end{lemma}
56 |
57 | \paragraph{Relationship to the contract source code}
58 |
59 | In the \verb|initialize_epoch| function\footnote{\url{https://github.com/ethereum/casper/blob/b2a1189506710c37bbdbbf3dc79ff383dbe13875/casper/contracts/simple_casper.v.py}}:
60 | \begin{itemize}
61 | \i $D^V_{i+1} \times 10^{18} \simeq \t{self.validators[$V$].deposit} \times \verb|self.deposit_scale_factor[epoch]|$ at line 273.
62 | \i $R_{i+1} \simeq \verb|self.reward_factor|$ at line 284.
63 | \i $i + 1 = \t{epoch}$ at line 266.
64 | \i $\sqrt{\D_{i}} \simeq \verb|self.sqrt_of_total_deposits()|$ at line 276.
65 | \i \ESF = \t{self.esp()} at line 277.
66 | \i $\alpha \simeq \verb|vote_frac|$ at line 231 of the \verb|collective_reward| function (called at line 270).
67 | \i $\beta$ = \verb|self.BASE_INTEREST_FACTOR|
68 | \i $\gamma$ = \verb|self.BASE_PENALTY_FACTOR|
69 | \end{itemize}
70 |
--------------------------------------------------------------------------------
/casper/spec-tmpl.k:
--------------------------------------------------------------------------------
1 | // {RULENAME} {COMMENT}
2 | rule
3 | {K}
4 | 1
5 | NORMAL
6 | BYZANTIUM
7 |
8 |
9 |
10 | {STATUSCODE}
11 | {CALLSTACK}
12 | _
13 | _ => _
14 |
15 | #parseByteStack({CODE})
16 | #computeValidJumpDests(#parseByteStack({CODE}))
17 |
18 | CASPER_ACCT_ID // this
19 | CALLER_ID // msg.sender
20 | {CALLDATA} // msg.data
21 | {CALLVALUE} // msg.value
22 | {WORDSTACK}
23 | {LOCALMEM}
24 | {PC}
25 | {GAS}
26 | {MEMORYUSED}
27 | _ => _
28 | false // NOTE: non-static call
29 | {CALLDEPTH}
30 |
31 |
32 | _
33 | {LOG}
34 | {REFUND}
35 |
36 | _
37 | ORIGIN_ID // tx.origin
38 | BLOCK_HASHES // block.blockhash
39 |
40 | _
41 | _
42 | {COINBASE} // block.coinbase
43 | _
44 | _
45 | _
46 | _
47 | _
48 | BLOCK_NUM // block.number
49 | _
50 | _
51 | NOW // now = block.timestamp
52 | _
53 | _
54 | _
55 | _
56 |
57 |
58 |
59 | {ACTIVEACCOUNTS}
60 |
61 |
62 | CASPER_ACCT_ID
63 | {CASPERBALANCE}
64 | #parseByteStack({CODE})
65 |
66 | {STORAGE}
67 |
68 | _
69 | _
70 |
71 | {ACCOUNTS}
72 | ...
73 |
74 | _
75 | _
76 | _
77 |
78 |
79 | requires #rangeAddress(CASPER_ACCT_ID)
80 | andBool #rangeAddress(CALLER_ID)
81 | andBool #rangeAddress(ORIGIN_ID)
82 | andBool #rangeUInt(256, NOW)
83 | // andBool #rangeUInt(128, BLOCK_NUM) // Solidity
84 | andBool #range(0 <= BLOCK_NUM <= maxSInt128) // Vyper (for now)
85 | // Account address normality
86 | andBool CASPER_ACCT_ID >Int 0 andBool (notBool CASPER_ACCT_ID in #precompiledAccounts(BYZANTIUM))
87 | {REQUIRES}
88 | {ENSURES}
89 | {ATTRIBUTE}
90 |
--------------------------------------------------------------------------------
/deposit/README.md:
--------------------------------------------------------------------------------
1 | _**[DEPRECATED: The result in this directory is outdated. The deposit contract has been reimplemented in Solidity and reverified. The latest result can be found at https://github.com/runtimeverification/deposit-contract-verification.]**_
2 |
3 | *2020-01-21*
4 |
5 | # End-to-End Formal Verification of Ethereum 2.0 Deposit Contract _(Vyper Implementation)_
6 |
7 | This directory provides the result of our end-to-end formal verification of the Ethereum 2.0 [deposit contract].
8 |
9 | Documents:
10 | * Final report: [`deposit-formal-verification.pdf`](deposit-formal-verification.pdf)
11 | * Blog post: https://runtimeverification.com/blog/end-to-end-formal-verification-of-ethereum-2-0-deposit-smart-contract/
12 |
13 | Verification artifacts:
14 | * [`algorithm-correctness/`](algorithm-correctness): Formalization and correctness proof of incremental Merkle tree algorithm
15 | * [`bytecode-verification/`](bytecode-verification): Bytecode verification of the deposit contract
16 |
17 | ## [Resources](/README.md#resources)
18 |
19 | ## [Disclaimer](/README.md#disclaimer)
20 |
21 | [deposit contract]:
22 |
--------------------------------------------------------------------------------
/deposit/algorithm-correctness/README.md:
--------------------------------------------------------------------------------
1 | _**[DEPRECATED: The result in this directory is outdated. The deposit contract has been reimplemented in Solidity and reverified. The latest result can be found at https://github.com/runtimeverification/deposit-contract-verification.]**_
2 |
3 | # Formalization and Correctness Proof of Incremental Merkle Tree Algorithm of Deposit Contract
4 |
5 | This directory presents our formalization of the [incremental Merkle tree algorithm], especially the one employed in the [deposit contract], and prove its correctness w.r.t. the [original full-construction Merkle tree algorithm].
6 |
7 | Documents:
8 | * [Formalization of the incremental Merkle tree algorithm and its correctness proof](../formal-incremental-merkle-tree-algorithm.pdf)
9 | * [Blog post](https://runtimeverification.com/blog/formal-verification-of-ethereum-2-0-deposit-contract-part-1)
10 |
11 | Mechanized specifications and proofs in K:
12 | * [deposit.k](deposit.k): Formal model of the incremental Merkle tree algorithm
13 | * [deposit-spec.k](deposit-spec.k): Correctness specifications
14 | * [deposit-symbolic.k](deposit-symbolic.k): Lemmas (trusted)
15 |
16 | To prove the specifications:
17 | ```
18 | $ ./run.sh
19 | ```
20 | Prerequisites:
21 | * Install K: https://github.com/kframework/k/releases
22 |
23 | ## [Resources](/README.md#resources)
24 |
25 | ## [Disclaimer](/README.md#disclaimer)
26 |
27 | [deposit contract]:
28 | [incremental Merkle tree algorithm]:
29 | [original full-construction Merkle tree algorithm]:
30 |
--------------------------------------------------------------------------------
/deposit/algorithm-correctness/deposit-spec.k:
--------------------------------------------------------------------------------
1 | require "deposit-symbolic.k"
2 |
3 | module DEPOSIT-SPEC
4 |
5 | imports DEPOSIT-SYMBOLIC
6 |
7 | // Lemma 7 (deposit).
8 |
9 | rule deposit(V) => . ...
10 | M => M +Int 1
11 | TREE_HEIGHT
12 | Branch1 => Branch2
13 | requires V ==Int tn(M +Int 1, 0, M +Int 1)
14 | andBool M =Int 1
17 | andBool isValidBranch(Branch1, M)
18 | ensures isValidBranch(Branch2, M +Int 1)
19 |
20 | rule depositLoop(I, TREE_HEIGHT -Int 1, down(I, M), tn(M, I, down(I, M))) => . ...
21 | M // M = m + 1
22 | TREE_HEIGHT
23 | Branch1 => Branch2
24 | requires I <=Int TREE_HEIGHT -Int 1
25 | andBool (2 ^Int I) *Int down(I, M) ==Int M
26 | andBool 1 <=Int M andBool M =Int 1
29 | andBool isValidBranch(Branch1, M -Int 1)
30 | ensures isValidBranch(Branch2, M)
31 |
32 | // Lemma 9 (get_deposit_root).
33 |
34 | rule getDepositRoot => tn(M, TREE_HEIGHT, 1) ...
35 | M
36 | TREE_HEIGHT
37 | Branch
38 | Zeros
39 | requires M getDepositRootLoop(K, TREE_HEIGHT, down(K, M), tn(M, K, up(K, M +Int 1))) => tn(M, TREE_HEIGHT, 1) ...
45 | M
46 | TREE_HEIGHT
47 | Branch
48 | Zeros
49 | requires K <=Int TREE_HEIGHT
50 | andBool M V requires K0 ==Int K
12 | rule M [ K0 <- V ] [ K ] => M [ K ] requires K0 =/=Int K
13 | // rule .IMap [ _ ] => 0
14 |
15 | // syntax IntMap
16 | // rule isInt( M:Map [ _ ] ) => isIntMap(M)
17 | // rule isInt( M:Map [ _ <- V:Int ] ) => isIntMap(M)
18 | endmodule
19 |
20 | module IMAP
21 | imports IMAP-SYNTAX
22 | imports IMAP-SYMBOLIC
23 | endmodule
24 |
--------------------------------------------------------------------------------
/deposit/algorithm-correctness/imap.smt2:
--------------------------------------------------------------------------------
1 | (define-sort IMap () (Array Int Int))
2 |
--------------------------------------------------------------------------------
/deposit/algorithm-correctness/run.sh:
--------------------------------------------------------------------------------
1 | set -e
2 |
3 | # concrete test
4 | rm -rf deposit-test
5 | kompile --backend java -d deposit-test deposit.k
6 | krun --smt none -cTREEHEIGHT=3 -d deposit-test test.deposit | diff - test.deposit.out
7 |
8 | # proof
9 | rm -rf deposit-symbolic-kompiled
10 | kompile --backend java deposit-symbolic.k --syntax-module DEPOSIT-SYMBOLIC
11 | kprove deposit-spec.k --smt-prelude imap.smt2 | diff - deposit-spec.k.out
12 | # kprove deposit-spec.k --smt-prelude imap.smt2 -v --debug --log --log-rules --debug-z3-queries --log-cells k,depositCount,branch,zerohashes,#pc,#result >/tmp/x 2>&1
13 |
--------------------------------------------------------------------------------
/deposit/algorithm-correctness/test.deposit:
--------------------------------------------------------------------------------
1 | deposit 1
2 | deposit 2
3 | deposit 3
4 | deposit 4
5 | deposit 5
6 | deposit 6
7 | deposit 7
8 | //deposit 8
9 | getDepositRoot
10 |
--------------------------------------------------------------------------------
/deposit/algorithm-correctness/test.deposit.out:
--------------------------------------------------------------------------------
1 |
2 |
3 | hash ( hash ( hash ( 1 , 2 ) , hash ( 3 , 4 ) ) , hash ( hash ( 5 , 6 ) , hash ( 7 , 0 ) ) )
4 |
5 |
6 | .IMap [ 0 <- 0 ] [ 1 <- 0 ] [ 2 <- 0 ] [ 1 <- hash ( 0 , 0 ) ] [ 2 <- hash ( hash ( 0 , 0 ) , hash ( 0 , 0 ) ) ]
7 |
8 |
9 | .IMap [ 0 <- 0 ] [ 1 <- 0 ] [ 2 <- 0 ] [ 0 <- 1 ] [ 1 <- hash ( 1 , 2 ) ] [ 0 <- 3 ] [ 2 <- hash ( hash ( 1 , 2 ) , hash ( 3 , 4 ) ) ] [ 0 <- 5 ] [ 1 <- hash ( 5 , 6 ) ] [ 0 <- 7 ]
10 |
11 |
12 | 7
13 |
14 |
15 | 3
16 |
17 |
18 |
--------------------------------------------------------------------------------
/deposit/bytecode-verification/.build/.kevm.rev:
--------------------------------------------------------------------------------
1 | 652576cb753656da51a25cea754d38c3d59470cd
2 |
--------------------------------------------------------------------------------
/deposit/bytecode-verification/.build/concrete-rules.txt:
--------------------------------------------------------------------------------
1 | EDSL.#ceil32
2 | EDSL.keccakIntList
3 | EVM-DATA.#signed.positive
4 | EVM-DATA.#signed.negative
5 | EVM-DATA.#unsigned.positive
6 | EVM-DATA.#unsigned.negative
7 | EVM-DATA.powmod.nonzero
8 | EVM-DATA.powmod.zero
9 | EVM-DATA.signextend.invalid
10 | EVM-DATA.signextend.negative
11 | EVM-DATA.signextend.positive
12 | EVM-DATA.keccak
13 | EVM-DATA.#take.zero-pad
14 | EVM-DATA.#asWord.recursive
15 | EVM-DATA.#asByteStack
16 | EVM-DATA.#asByteStackAux.recursive
17 | EVM-DATA.#padToWidth
18 | EVM-DATA.#padRightToWidth
19 | EVM-DATA.#newAddr
20 | EVM-DATA.#newAddrCreate2
21 | EVM-DATA.mapWriteBytes.recursive
22 | EVM-DATA.#range
23 | EVM-DATA.#lookup.some
24 | EVM-DATA.#lookup.none
25 | EVM.#memoryUsageUpdate.some
26 | EVM.Cgascap
27 | EVM.Csstore.new
28 | EVM.Csstore.old
29 | EVM.Rsstore.new
30 | EVM.Rsstore.old
31 | EVM.Cextra
32 | EVM.Cmem
33 |
--------------------------------------------------------------------------------
/deposit/bytecode-verification/Makefile:
--------------------------------------------------------------------------------
1 | KEVM_VERSION_FILE:=.build/.kevm.rev
2 |
3 | LOCAL_LEMMAS:=verification.k \
4 | abstract-semantics.k \
5 | lemmas.k
6 | TMPLS:=module-tmpl.k spec-tmpl.k
7 |
8 | SPEC_GROUP:=deposit
9 | SPEC_INI:=deposit-spec.ini
10 |
11 | KPROVE_OPTS:=--smt-prelude $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/evm.smt2) \
12 | --branching-allowed 0 \
13 | --z3-cnstr-timeout 100
14 |
15 | SPEC_NAMES:=
16 |
17 | SPEC_NAMES += init-success
18 | SPEC_NAMES += init-revert
19 |
20 | SPEC_NAMES += get_deposit_root-success-init-then
21 | SPEC_NAMES += get_deposit_root-success-init-else
22 | SPEC_NAMES += get_deposit_root-success-loop-enter-then
23 | SPEC_NAMES += get_deposit_root-success-loop-enter-else
24 | SPEC_NAMES += get_deposit_root-success-loop-exit
25 | SPEC_NAMES += get_deposit_root-revert
26 |
27 | SPEC_NAMES += get_deposit_count-success
28 | SPEC_NAMES += get_deposit_count-revert
29 |
30 | SPEC_NAMES += deposit-success-data
31 | SPEC_NAMES += deposit-success-insert-init-then
32 | SPEC_NAMES += deposit-success-insert-init-else
33 | SPEC_NAMES += deposit-success-insert-loop-enter-then
34 | SPEC_NAMES += deposit-success-insert-loop-enter-else
35 | SPEC_NAMES += deposit-success-insert-loop-exit
36 |
37 | SPEC_NAMES += deposit-revert-1
38 | SPEC_NAMES += deposit-revert-2
39 | SPEC_NAMES += deposit-revert-3
40 |
41 | SPEC_NAMES += deposit-calldata-decoding-success
42 | SPEC_NAMES += deposit-calldata-decoding-revert-1
43 | SPEC_NAMES += deposit-calldata-decoding-revert-2
44 | SPEC_NAMES += deposit-calldata-decoding-revert-3
45 | SPEC_NAMES += deposit-calldata-decoding-revert-4
46 | SPEC_NAMES += deposit-calldata-decoding-revert-5
47 | SPEC_NAMES += deposit-calldata-decoding-revert-6
48 |
49 | SPEC_NAMES += revert-invalid_function_identifier-lt_4
50 | SPEC_NAMES += revert-invalid_function_identifier-ge_4-lt_32
51 | SPEC_NAMES += revert-invalid_function_identifier-ge_4-ge_32
52 |
53 | export K_OPTS=-Xmx16g
54 |
55 | include ../../resources/kprove.mak
56 |
--------------------------------------------------------------------------------
/deposit/bytecode-verification/abstract-semantics.k:
--------------------------------------------------------------------------------
1 | requires "verification.k"
2 |
3 | module ABSTRACT-SEMANTICS
4 | imports VERIFICATION
5 |
6 | // to avoid unnecessary case analyses
7 | rule LT W0 W1 => bool2Word(W0 #push ... [trusted]
8 | rule GT W0 W1 => bool2Word(W0 >Int W1) ~> #push ... [trusted]
9 | rule EQ W0 W1 => bool2Word(W0 ==Int W1) ~> #push ... [trusted]
10 | rule ISZERO W => bool2Word(W ==Int 0 ) ~> #push ... [trusted]
11 |
12 | rule SHA256 => #end EVMC_SUCCESS ...
13 | DATA
14 |
15 | requires notBool #isConcrete(DATA)
16 | [trusted]
17 |
18 | // gas abstraction
19 |
20 | // see also verification.k
21 |
22 | rule G':Int ~> #deductGas => . ...
23 | G => G -Gas G'
24 | requires notBool (#isConcrete(G) andBool #isConcrete(G'))
25 | [trusted]
26 |
27 | rule MU':Int ~> #deductMemory => . ...
28 | #symGas(_, _, _, _, CMEM => Cmem(SCHED, MU'))
29 | MU => MU'
30 | SCHED
31 | requires CMEM ==Int Cmem(SCHED, MU)
32 | [trusted, matching(#symGas)]
33 |
34 | rule GCALL:Int ~> #allocateCallGas => . ...
35 | _ => #symGas(GCALL, 0, 0, .List, 0)
36 | [trusted]
37 |
38 | rule #refund G:Int => . ...
39 | GAVAIL => GAVAIL +Gas G
40 | [trusted]
41 |
42 | /* NOTE:
43 | These abstractions are over-approximation, except that out-of-gas exceptions are ignored.
44 | The out-of-gas exception is not harmful when it comes to safety properties, and it can be avoided by simply providing enough gas.
45 | The only problematic case is to call sub-functions with a specific amount of gas (instead of all available gas at that point).
46 | In this case, additional analyses need to be made to ensure that the specific amount of gas is sufficient, for liveness properties.
47 | See the lemmas over `+Gas` for the analysis, which checks the remaining (i.e., refuned) gas is positive when returning to the caller.
48 |
49 | In particular, the deposit contract involves precompiled contract calls (i.e., SHA256 and ID), where ID calls are fed a specific amount of gas.
50 | That is, the amount of gas provided to ID calls is "18 + floor(CALLDATASIZE / 10)",
51 | which is greater than the actual gas cost of ID calls, "15 + 3 * ceil(CALLDATASIZE / 32)".
52 | Indeed, the sufficiency is not trivial to show, but the former is simpler (thus more gas-efficient) to compute at runtime than the latter.
53 | Other calls are either private calls or calls with all available gas.
54 | */
55 |
56 | endmodule
57 |
--------------------------------------------------------------------------------
/deposit/bytecode-verification/evm.smt2:
--------------------------------------------------------------------------------
1 | ; (set-option :auto-config false)
2 | ; (set-option :smt.mbqi false)
3 | ; (set-option :smt.array.extensional false)
4 |
5 | ; int extra
6 | (define-fun int_max ((x Int) (y Int)) Int (ite (< x y) y x))
7 | (define-fun int_min ((x Int) (y Int)) Int (ite (< x y) x y))
8 | (define-fun int_abs ((x Int)) Int (ite (< x 0) (- 0 x) x))
9 |
10 | ; bool to int
11 | (define-fun smt_bool2int ((b Bool)) Int (ite b 1 0))
12 |
13 | ; IMap
14 | (define-sort IMap () (Array Int Int))
15 | (define-fun emptyIMap () IMap ((as const IMap) 0))
16 |
17 | ; ceil32
18 | (define-fun ceil32 ((x Int)) Int ( * ( div ( + x 31 ) 32 ) 32 ) )
19 |
20 | ; 0 <=Int select(M, K)
21 | ;(assert (forall ((m Map) (k Int)) (<= 0 (selectInt m k))))
22 |
23 | ; (declare-fun gas ((x Int)) Int)
24 | ; (assert (forall ((i Int) (j Int)) (=> (i > j) (< (gas i) (gas j)))))
25 |
--------------------------------------------------------------------------------
/deposit/bytecode-verification/module-tmpl.k:
--------------------------------------------------------------------------------
1 | requires "abstract-semantics.k"
2 | requires "verification.k"
3 |
4 | module {MODULE}-SPEC
5 |
6 | imports ABSTRACT-SEMANTICS
7 | imports VERIFICATION
8 |
9 | {RULES}
10 |
11 | endmodule
12 |
--------------------------------------------------------------------------------
/deposit/bytecode-verification/spec-tmpl.k:
--------------------------------------------------------------------------------
1 | // {RULENAME} {COMMENT}
2 | rule
3 |
4 | {K}
5 | NORMAL
6 | {SCHEDULE}
7 |
8 |
9 |
10 | {STATUS_CODE}
11 | _ => _
12 |
13 | #parseByteStack({CODE})
14 | #computeValidJumpDests(#parseByteStack({CODE}))
15 | {THIS} // this
16 | {MSG_SENDER} // msg.sender
17 | {CALL_DATA} // msg.data
18 | {CALL_VALUE} // msg.value
19 | {WORD_STACK}
20 | {LOCAL_MEM}
21 | {PC}
22 | {GAS}
23 | {MEMORY_USED}
24 | _ => _
25 | false // NOTE: non-static call
26 | {CALL_DEPTH}
27 |
28 |
29 | {LOG}
30 | {REFUND}
31 | ...
32 |
33 | ...
34 |
35 |
36 | {ACTIVE_ACCOUNTS} SetItem({THIS}) SetItem(2) SetItem(4) _:Set
37 |
38 |
39 | {THIS}
40 | {BALANCE}
41 | #parseByteStack({CODE})
42 | {STORAGE}
43 | {ORIG_STORAGE}
44 | {NONCE}
45 |
46 |
47 | // precompiled account for SHA256
48 | 2
49 | 0
50 | .WordStack
51 | .Map
52 | .Map
53 | 0
54 |
55 |
56 | // precompiled account for ID
57 | 4
58 | 0
59 | .WordStack
60 | .Map
61 | .Map
62 | 0
63 |
64 | {ACCOUNTS}
65 | ...
66 |
67 | ...
68 |
69 |
70 | ...
71 |
72 | requires true
73 | {REQUIRES}
74 | ensures true
75 | {ENSURES}
76 | {ATTRIBUTE}
77 |
--------------------------------------------------------------------------------
/deposit/deposit-formal-verification.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runtimeverification/verified-smart-contracts/e61ef57de99d07d7182436490f152a14621c5a82/deposit/deposit-formal-verification.pdf
--------------------------------------------------------------------------------
/deposit/formal-incremental-merkle-tree-algorithm.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runtimeverification/verified-smart-contracts/e61ef57de99d07d7182436490f152a14621c5a82/deposit/formal-incremental-merkle-tree-algorithm.pdf
--------------------------------------------------------------------------------
/erc20/.build/.kevm.rev:
--------------------------------------------------------------------------------
1 | 06f1d2f88c6c2769ef9ac86e26477c718c29e14c
2 |
--------------------------------------------------------------------------------
/erc20/.build/concrete-rules.txt:
--------------------------------------------------------------------------------
1 | EDSL.#ceil32
2 | EDSL.keccakIntList
3 | EVM-TYPES.#signed.positive
4 | EVM-TYPES.#signed.negative
5 | EVM-TYPES.#unsigned.positive
6 | EVM-TYPES.#unsigned.negative
7 | EVM-TYPES.powmod.nonzero
8 | EVM-TYPES.powmod.zero
9 | EVM-TYPES.signextend.invalid
10 | EVM-TYPES.signextend.negative
11 | EVM-TYPES.signextend.positive
12 | SERIALIZATION.keccak
13 | EVM-TYPES.#take.zero-pad
14 | EVM-TYPES.#asWord.recursive
15 | EVM-TYPES.#asByteStack
16 | EVM-TYPES.#asByteStackAux.recursive
17 | EVM-TYPES.#padToWidth
18 | EVM-TYPES.#padRightToWidth
19 | SERIALIZATION.#newAddr
20 | SERIALIZATION.#newAddrCreate2
21 | EVM-TYPES.mapWriteBytes.recursive
22 | EVM-TYPES.#range
23 | EVM-TYPES.#lookup.some
24 | EVM-TYPES.#lookup.none
25 | EVM.#memoryUsageUpdate.some
26 | EVM.Cgascap
27 | EVM.Csstore.new
28 | EVM.Csstore.old
29 | EVM.Rsstore.new
30 | EVM.Rsstore.old
31 | EVM.Cextra
32 | EVM.Cmem
33 |
--------------------------------------------------------------------------------
/erc20/README.md:
--------------------------------------------------------------------------------
1 | # Formally Verified ERC20 Token Contracts
2 |
3 | This directory contains ERC20 token contracts that have been formally verified by [Runtime Verification] and/or collaborators.
4 |
5 | Refer to the main [README] file for more details and the complete list of formally verified smart contracts.
6 |
7 | ## List of Verified ERC20 Token Contracts
8 |
9 | * **2018-03-12** [DappSys DSToken ERC20 token contract](/erc20/ds-token/README.md)
10 | * **2018-01-30** [MyKidsEducationToken ERC20 token contract](/erc20/hobby/README.md)
11 | * **2018-01-26** [OpenZeppelin ERC20 token contract](/erc20/zeppelin/README.md)
12 | * **2018-01-16** [HackerGold (HKG) ERC20 token contract](/erc20/hkg/README.md)
13 | * **2017-12-23** [Philip Daian's Vyper ERC20 token contract](/erc20/vyper/README.md)
14 |
15 | ## [Resources](/README.md#resources)
16 |
17 | ## [Disclaimer](/README.md#disclaimer)
18 |
19 |
20 | [Runtime Verification]:
21 | [README]:
22 |
--------------------------------------------------------------------------------
/erc20/all/contracts/22_kucoin.sol:
--------------------------------------------------------------------------------
1 | /**
2 | *Submitted for verification at Etherscan.io on 2019-04-02
3 | */
4 |
5 | pragma solidity ^0.4.13;
6 |
7 |
8 |
9 | contract MyToken {
10 | /* Public variables of the token */
11 | string public name;
12 | string public symbol;
13 | uint8 public decimals;
14 | uint256 public totalSupply;
15 |
16 | /* This creates an array with all balances */
17 | mapping (address => uint256) public balanceOf;
18 | mapping (address => mapping (address => uint256)) public allowance;
19 |
20 | /* This generates a public event on the blockchain that will notify clients */
21 | event Transfer(address indexed from, address indexed to, uint256 value);
22 |
23 | /* This notifies clients about the amount burnt */
24 | event Burn(address indexed from, uint256 value);
25 |
26 | /* Initializes contract with initial supply tokens to the creator of the contract */
27 | function MyToken(
28 | uint256 initialSupply,
29 | string tokenName,
30 | uint8 decimalUnits,
31 | string tokenSymbol
32 | ) {
33 | balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens
34 | totalSupply = initialSupply; // Update total supply
35 | name = tokenName; // Set the name for display purposes
36 | symbol = tokenSymbol; // Set the symbol for display purposes
37 | decimals = decimalUnits; // Amount of decimals for display purposes
38 | }
39 |
40 | /* Internal transfer, only can be called by this contract */
41 | function _transfer(address _from, address _to, uint _value) internal {
42 | require (_to != 0x0); // Prevent transfer to 0x0 address. Use burn() instead
43 | require (balanceOf[_from] > _value); // Check if the sender has enough
44 | require (balanceOf[_to] + _value > balanceOf[_to]); // Check for overflows
45 | balanceOf[_from] -= _value; // Subtract from the sender
46 | balanceOf[_to] += _value; // Add the same to the recipient
47 | Transfer(_from, _to, _value);
48 | }
49 |
50 | /// @notice Send `_value` tokens to `_to` from your account
51 | /// @param _to The address of the recipient
52 | /// @param _value the amount to send
53 | function transfer(address _to, uint256 _value) {
54 | _transfer(msg.sender, _to, _value);
55 | }
56 |
57 |
58 | /// @notice Remove `_value` tokens from the system irreversibly
59 | /// @param _value the amount of money to burn
60 | function burn(uint256 _value) returns (bool success) {
61 | require (balanceOf[msg.sender] > _value); // Check if the sender has enough
62 | balanceOf[msg.sender] -= _value; // Subtract from the sender
63 | totalSupply -= _value; // Updates totalSupply
64 | Burn(msg.sender, _value);
65 | return true;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/erc20/all/contracts/23_ekt.sol:
--------------------------------------------------------------------------------
1 | /**
2 | *Submitted for verification at Etherscan.io on 2019-07-12
3 | */
4 |
5 | pragma solidity ^0.4.24;
6 |
7 | contract SafeMath {
8 | function safeMul(uint256 a, uint256 b) internal pure returns (uint256) {
9 | uint256 c = a * b;
10 | _assert(a == 0 || c / a == b);
11 | return c;
12 | }
13 |
14 | function safeDiv(uint256 a, uint256 b) internal pure returns (uint256) {
15 | _assert(b > 0);
16 | uint256 c = a / b;
17 | _assert(a == b * c + a % b);
18 | return c;
19 | }
20 |
21 | function safeSub(uint256 a, uint256 b) internal pure returns (uint256) {
22 | _assert(b <= a);
23 | return a - b;
24 | }
25 |
26 | function safeAdd(uint256 a, uint256 b) internal pure returns (uint256) {
27 | uint256 c = a + b;
28 | _assert(c >= a && c >= b);
29 | return c;
30 | }
31 |
32 | function _assert(bool assertion) internal pure {
33 | if (!assertion) {
34 | revert();
35 | }
36 | }
37 | }
38 |
39 | contract EKT is SafeMath {
40 | string public name = "EKT";
41 | string public symbol = "EKT";
42 | uint8 constant public decimals = 8;
43 | mapping(address => uint256) _balances;
44 | mapping(address => mapping(address => uint256)) public _allowed;
45 |
46 | uint256 public totalSupply = 10 * 100000000 * 100000000;
47 |
48 |
49 | constructor () public{
50 | _balances[msg.sender] = totalSupply;
51 | emit Transfer(0x0, msg.sender, totalSupply);
52 | }
53 |
54 | function balanceOf(address addr) public view returns (uint256) {
55 | return _balances[addr];
56 | }
57 |
58 |
59 | function transfer(address _to, uint256 _value) public returns (bool) {
60 | // require(_to != address(0));
61 | if (_to == address(0)) {
62 | return burn(_value);
63 | } else {
64 | require(_balances[msg.sender] >= _value && _value > 0);
65 | require(_balances[_to] + _value >= _balances[_to]);
66 |
67 | _balances[msg.sender] = safeSub(_balances[msg.sender], _value);
68 | _balances[_to] = safeAdd(_balances[_to], _value);
69 | emit Transfer(msg.sender, _to, _value);
70 | return true;
71 | }
72 | }
73 |
74 | function burn(uint256 _value) public returns (bool) {
75 | require(_balances[msg.sender] >= _value && _value > 0);
76 | require(totalSupply >= _value);
77 | _balances[msg.sender] = safeSub(_balances[msg.sender], _value);
78 | totalSupply = safeSub(totalSupply, _value);
79 | emit Burn(msg.sender, _value);
80 | return true;
81 | }
82 |
83 | function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
84 | require(_to != address(0));
85 | require(_balances[_from] >= _value && _value > 0);
86 | require(_balances[_to] + _value >= _balances[_to]);
87 |
88 | require(_allowed[_from][msg.sender] >= _value);
89 |
90 | _balances[_to] = safeAdd(_balances[_to], _value);
91 | _balances[_from] = safeSub(_balances[_from], _value);
92 | _allowed[_from][msg.sender] = safeSub(_allowed[_from][msg.sender], _value);
93 | emit Transfer(_from, _to, _value);
94 | return true;
95 | }
96 |
97 | function approve(address spender, uint256 value) public returns (bool) {
98 | require(spender != address(0));
99 | _allowed[msg.sender][spender] = value;
100 | emit Approval(msg.sender, spender, value);
101 | return true;
102 | }
103 |
104 | function allowance(address _master, address _spender) public view returns (uint256) {
105 | return _allowed[_master][_spender];
106 | }
107 |
108 | event Approval(address indexed _owner, address indexed _spender, uint256 _value);
109 | event Transfer(address indexed _from, address indexed _to, uint256 value);
110 | event Burn(address indexed _from, uint256 value);
111 | }
112 |
--------------------------------------------------------------------------------
/erc20/all/demo-specs/Makefile:
--------------------------------------------------------------------------------
1 | include ../resources/kprove-erc20-group.mak
2 |
--------------------------------------------------------------------------------
/erc20/all/demo-specs/certora-buggy.ini:
--------------------------------------------------------------------------------
1 | [pgm]
2 | compiler: "Solidity"
3 | _balances: 0
4 | _totalSupply: 1
5 | _allowances: 2
6 | code: "0x606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a9059cbb14610046575b600080fd5b341561005157600080fd5b610086600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506100a0565b604051808215151515815260200191505060405180910390f35b600080600080339250846000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151561017b57846000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054039150846000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054019050610180565b600080fd5b816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550806000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508573ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040518082815260200191505060405180910390a360019350505050929150505600a165627a7a723058200aac233736bb57132e4693d151f7765295b29ae9aa3212f10a706abdd994efed0029"
7 |
--------------------------------------------------------------------------------
/erc20/all/demo-specs/certora-fixed.ini:
--------------------------------------------------------------------------------
1 | [pgm]
2 | compiler: "Solidity"
3 | _balances: 0
4 | _totalSupply: 1
5 | _allowances: 2
6 | code: "0x606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a9059cbb14610046575b600080fd5b341561005157600080fd5b610086600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506100a0565b604051808215151515815260200191505060405180910390f35b6000806000803392506000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205491506000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050846000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515610233578573ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151561022e57846000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054039150846000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540190505b610238565b600080fd5b816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550806000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508573ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040518082815260200191505060405180910390a360019350505050929150505600a165627a7a723058207d1f2e94dd2380aa2394b4643f49b8b0c6898ace7be8838ea219638d91f89d0a0029"
7 |
--------------------------------------------------------------------------------
/erc20/all/demo-specs/hkg.ini:
--------------------------------------------------------------------------------
1 | [pgm]
2 | compiler: "Solidity"
3 | _totalSupply: 0
4 | _balances: 1
5 | _allowances: 2
6 | code: "0x60606040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063095ea7b31461007257806323b872dd146100cc57806370a0823114610145578063a9059cbb14610192578063dd62ed3e146101ec575b600080fd5b341561007d57600080fd5b6100b2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610258565b604051808215151515815260200191505060405180910390f35b34156100d757600080fd5b61012b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061034a565b604051808215151515815260200191505060405180910390f35b341561015057600080fd5b61017c600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506105c6565b6040518082815260200191505060405180910390f35b341561019d57600080fd5b6101d2600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061060f565b604051808215151515815260200191505060405180910390f35b34156101f757600080fd5b610242600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610778565b6040518082815260200191505060405180910390f35b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b600081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610417575081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b80156104235750600082115b156105ba5781600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190506105bf565b600090505b9392505050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101580156106605750600082115b1561076d5781600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050610772565b600090505b92915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a165627a7a723058206cb5284e8795f7d1c570318732bc1cb8add2222946156c0ba28c946531c4a2f50029"
7 |
--------------------------------------------------------------------------------
/erc20/all/demo-specs/vyper.ini:
--------------------------------------------------------------------------------
1 | [pgm]
2 | compiler: "Vyper"
3 | _balances: 0
4 | _allowances: 1
5 | _totalSupply: 2
6 | code: "0x600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a05263d0e30db06000511415610168573460008112585761014052336101605261016051600060c052602060c02001546101405161016051600060c052602060c020015401116101405115176100e657600080fd5b6101405161016051600060c052602060c02001540161016051600060c052602060c020015560025461014051600254011161014051151761012657600080fd5b610140516002540160025561014051610180526101605160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020610180a3005b632e1a7d4d6000511415610260576020600461014037341561018957600080fd5b33610160526101405161016051600060c052602060c020015410156101ad57600080fd5b6101405161016051600060c052602060c02001540361016051600060c052602060c02001556101405160025410156101e457600080fd5b61014051600254036002556000600060006000600160605161014051806040519013585780919012585702610160516000f161021f57600080fd5b61014051610180526000610160517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020610180a3600160005260206000f3005b6318160ddd600051141561028657341561027957600080fd5b60025460005260206000f3005b6370a0823160005114156102cd57602060046101403734156102a757600080fd5b60043560205181101558575061014051600060c052602060c020015460005260206000f3005b63a9059cbb60005114156103e057604060046101403734156102ee57600080fd5b60043560205181101558575033610180526101605161018051600060c052602060c0200154101561031e57600080fd5b6101605161018051600060c052602060c02001540361018051600060c052602060c020015561014051600060c052602060c02001546101605161014051600060c052602060c0200154011161016051151761037857600080fd5b6101605161014051600060c052602060c02001540161014051600060c052602060c0200155610160516101a05261014051610180517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206101a0a3600160005260206000f3005b6323b872dd6000511415610559576060600461014037341561040157600080fd5b600435602051811015585750602435602051811015585750336101a0526101a05161014051600160c052602060c0200160c052602060c02001546101c0526101805161014051600060c052602060c0200154101561045e57600080fd5b6101805161014051600060c052602060c02001540361014051600060c052602060c020015561016051600060c052602060c02001546101805161016051600060c052602060c020015401116101805115176104b857600080fd5b6101805161016051600060c052602060c02001540161016051600060c052602060c0200155610180516101c05110156104f057600080fd5b610180516101c051036101a05161014051600160c052602060c0200160c052602060c0200155610180516101e05261016051610140517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206101e0a3600160005260206000f3005b63095ea7b360005114156105ef576040600461014037341561057a57600080fd5b6004356020518110155857503361018052610160516101405161018051600160c052602060c0200160c052602060c0200155610160516101a05261014051610180517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560206101a0a3600160005260206000f3005b63dd62ed3e600051141561064f576040600461014037341561061057600080fd5b6004356020518110155857506024356020518110155857506101605161014051600160c052602060c0200160c052602060c020015460005260206000f3005b"
7 |
--------------------------------------------------------------------------------
/erc20/all/fragments-solar/allowance.ini:
--------------------------------------------------------------------------------
1 | [allowance]
2 | +k: ~> #assume {FULL_REQUIRES}
3 | ; spec script
4 | ~> #mkCallShortcut V_CONF_BEFORE CALLER_ID ACCT_ID
5 | #abiCallData("allowance", #address(OWNER), #address(SPENDER)) V_OUT
6 | ~> #assert {FULL_ENSURES}
7 | => .
8 | FULL_REQUIRES: true
9 | andBool V_OUT ==K String2Id("V_OUT")
10 | ; types
11 | andBool #rangeAddress(OWNER)
12 | andBool #rangeAddress(SPENDER)
13 | FULL_ENSURES: true
14 | &&S (#var(V_OLD_STORAGE) ==S #getStorage(ACCT_ID))
15 | &&S (#var(V_OLD_LOG) ==S #getLog)
16 | &&S (#var(V_OLD_REFUND) ==S #getRefund)
17 | &&S (#getStatusCode ==S EVMC_SUCCESS)
18 | &&S (#sizeByteArrayExp(#var(V_OUT)) ==S 32)
19 |
--------------------------------------------------------------------------------
/erc20/all/fragments-solar/balanceOf.ini:
--------------------------------------------------------------------------------
1 | [balanceOf]
2 | +k: ~> #assume {FULL_REQUIRES}
3 | ~> #mkCallShortcut V_CONF_BEFORE CALLER_ID ACCT_ID
4 | #abiCallData("balanceOf", #address(OWNER)) V_OUT
5 | ~> #assert {FULL_ENSURES}
6 | => .
7 | FULL_REQUIRES: true
8 | andBool V_OUT ==K String2Id("V_OUT")
9 | ; types
10 | andBool #rangeAddress(OWNER)
11 | FULL_ENSURES: true
12 | &&S (#var(V_OLD_STORAGE) ==S #getStorage(ACCT_ID))
13 | &&S (#var(V_OLD_LOG) ==S #getLog)
14 | &&S (#var(V_OLD_REFUND) ==S #getRefund)
15 | &&S (#getStatusCode ==S EVMC_SUCCESS)
16 | &&S (#sizeByteArrayExp(#var(V_OUT)) ==S 32)
17 |
--------------------------------------------------------------------------------
/erc20/all/fragments-solar/root.ini:
--------------------------------------------------------------------------------
1 | [root]
2 | k: #dummy
3 | ~> #assume V_CONF_BEFORE ==K String2Id("V_CONF_BEFORE")
4 | ~> #assume V_OLD_STORAGE ==K String2Id("V_OLD_STORAGE")
5 | ~> #assume V_OLD_LOG ==K String2Id("V_OLD_LOG")
6 | ~> #assume V_OLD_REFUND ==K String2Id("V_OLD_REFUND")
7 | ~> #saveEthereum V_CONF_BEFORE
8 | ~> #saveStorage ACCT_ID V_OLD_STORAGE
9 | ~> #saveLog V_OLD_LOG
10 | ~> #saveRefund V_OLD_REFUND
11 | schedule: PETERSBURG
12 | output: _ => _
13 | statusCode: _ => _
14 | gas: #gas(INITGAS, 0, 0) => _
15 | callData: _ => _
16 | ; for view functions tested that is unchanged
17 | storage: S => _
18 | origStorage: S
19 | ; for view functions tested that is unchanged
20 | log: _ => _
21 | refund: _ => _
22 | commandVars: .Map => _
23 | requires:
24 | ensures:
25 | comment:
26 | attribute:
27 |
--------------------------------------------------------------------------------
/erc20/all/fragments-solar/totalSupply.ini:
--------------------------------------------------------------------------------
1 | [totalSupply]
2 | +k: ~> #assume V_OUT ==K String2Id("V_OUT")
3 | ~> #mkCallShortcut V_CONF_BEFORE CALLER_ID ACCT_ID
4 | #abiCallData("totalSupply", .TypedArgs) V_OUT
5 | ~> #assert {FULL_ENSURES}
6 | => .
7 | FULL_ENSURES: true
8 | &&S (#var(V_OLD_STORAGE) ==S #getStorage(ACCT_ID))
9 | &&S (#var(V_OLD_LOG) ==S #getLog)
10 | &&S (#var(V_OLD_REFUND) ==S #getRefund)
11 | &&S (#getStatusCode ==S EVMC_SUCCESS)
12 | &&S (#sizeByteArrayExp(#var(V_OUT)) ==S 32)
13 |
--------------------------------------------------------------------------------
/erc20/all/fragments/allowance.ini:
--------------------------------------------------------------------------------
1 | [allowance]
2 | statusCode: _ => EVMC_SUCCESS
3 | output: _ => #buf(32, ALLOWANCE)
4 | callData: #abiCallData("allowance", #address(OWNER), #address(SPENDER))
5 | log: _
6 | refund: _
7 | storage: M
8 | origStorage: _
9 | requires:
10 | // types
11 | andBool #rangeAddress(OWNER)
12 | andBool #rangeAddress(SPENDER)
13 | andBool #rangeUInt(256, ALLOWANCE)
14 | // let-bindings
15 | andBool ALLOWANCE ==Int select(M, #hashedLocation({COMPILER}, {_ALLOWANCES}, OWNER SPENDER))
16 |
--------------------------------------------------------------------------------
/erc20/all/fragments/approve.ini:
--------------------------------------------------------------------------------
1 | [approve]
2 | statusCode: _ => SC
3 | output: _ => NEW_OUTPUT
4 | callData: #abiCallData("approve", #address(SPENDER), #uint256(VALUE))
5 | log: OLD_LOG => NEW_LOG
6 | refund: _ => _
7 | storage: M1 => M2
8 | origStorage: M1
9 | requires:
10 | // types
11 | andBool #rangeAddress(SPENDER)
12 | andBool #rangeUInt(256, VALUE)
13 | // let-bindings
14 | andBool OLD_ALLOWANCE ==Int select(M1, #hashedLocation({COMPILER}, {_ALLOWANCES}, CALLER_ID SPENDER))
15 | ensures:
16 | andBool (
17 | (
18 | // return true
19 | SC ==K EVMC_SUCCESS
20 | andBool NEW_OUTPUT ==K #buf(32, 1)
21 | andBool NEW_LOG ==K OLD_LOG ListItem(#abiEventLog(ACCT_ID, "Approval", #indexed(#address(CALLER_ID)), #indexed(#address(SPENDER)), #uint256(VALUE)))
22 | andBool M2 ==IMap M1 [ #hashedLocation({COMPILER}, {_ALLOWANCES}, CALLER_ID SPENDER) <- VALUE ]
23 | ) orBool (
24 | // revert
25 | SC =/=K EVMC_SUCCESS
26 | // pre-conditions
27 | {EXTRA_PRE_CONDITIONS}
28 | ) orBool (
29 | // return false
30 | SC ==K EVMC_SUCCESS andBool NEW_OUTPUT ==K #buf(32, 0)
31 | andBool OLD_LOG ==K NEW_LOG
32 | andBool M1 ==IMap M2
33 | // pre-conditions
34 | {EXTRA_PRE_CONDITIONS}
35 | )
36 | )
37 | EXTRA_PRE_CONDITIONS:
38 | andBool (
39 | (
40 | CALLER_ID ==Int 0
41 | ) orBool (
42 | SPENDER ==Int 0
43 | ) orBool (
44 | VALUE ==Int 0
45 | ) orBool (
46 | VALUE =/=Int 0 andBool OLD_ALLOWANCE =/=Int 0 /* mitigates the ERC20 spend/approval race condition */
47 | ) orBool (
48 | ACCT_ID ==Int SPENDER /* 04_chainlink, non-ERC20-compliant */
49 | )
50 | )
51 |
--------------------------------------------------------------------------------
/erc20/all/fragments/balanceOf.ini:
--------------------------------------------------------------------------------
1 | [balanceOf]
2 | statusCode: _ => EVMC_SUCCESS
3 | output: _ => #buf(32, BAL)
4 | callData: #abiCallData("balanceOf", #address(OWNER))
5 | log: _
6 | refund: _
7 | storage: M
8 | origStorage: _
9 | requires:
10 | // types
11 | andBool #rangeAddress(OWNER)
12 | andBool #rangeUInt(256, BAL)
13 | // let-bindings
14 | andBool BAL ==Int select(M, #hashedLocation({COMPILER}, {_BALANCES}, OWNER))
15 |
--------------------------------------------------------------------------------
/erc20/all/fragments/root.ini:
--------------------------------------------------------------------------------
1 | [root]
2 | k: #execute => #halt
3 | schedule: PETERSBURG
4 | gas: #gas(INITGAS, 0, 0) => _
5 | ensures:
6 | comment:
7 | attribute:
8 |
--------------------------------------------------------------------------------
/erc20/all/fragments/totalSupply.ini:
--------------------------------------------------------------------------------
1 | [totalSupply]
2 | statusCode: _ => EVMC_SUCCESS
3 | output: _ => #buf(32, TOTAL)
4 | callData: #abiCallData("totalSupply", .TypedArgs)
5 | log: _
6 | refund: _
7 | storage: M
8 | origStorage: _
9 | requires:
10 | // types
11 | andBool #rangeUInt(256, TOTAL)
12 | // let-bindings
13 | andBool TOTAL ==Int select(M, #hashedLocation({COMPILER}, {_TOTALSUPPLY}, .IntList))
14 |
--------------------------------------------------------------------------------
/erc20/all/fragments/transfer.ini:
--------------------------------------------------------------------------------
1 | [transfer]
2 | callData: #abiCallData("transfer", #address(TO_ID), #uint256(VALUE))
3 | refund: _ => _
4 | requires:
5 | // types
6 | andBool #rangeAddress(TO_ID)
7 | andBool #rangeUInt(256, VALUE)
8 | andBool #rangeUInt(256, BAL_FROM)
9 | andBool #rangeUInt(256, BAL_TO)
10 | // let-bindings
11 | andBool BAL_FROM ==Int select(M1, #hashedLocation({COMPILER}, {_BALANCES}, CALLER_ID))
12 | andBool BAL_TO ==Int select(M1, #hashedLocation({COMPILER}, {_BALANCES}, TO_ID))
13 |
14 | [transfer-success]
15 | statusCode: _ => SC
16 | output: _ => NEW_OUTPUT
17 | log: OLD_LOG => NEW_LOG
18 | storage: M1 => M2
19 | origStorage: M1
20 | +requires:
21 | andBool VALUE <=Int BAL_FROM
22 | ensures:
23 | andBool (
24 | (
25 | // return true
26 | SC ==K EVMC_SUCCESS
27 | andBool NEW_OUTPUT ==K #buf(32, 1)
28 | andBool NEW_LOG ==K OLD_LOG ListItem(#abiEventLog(ACCT_ID, "Transfer", #indexed(#address(CALLER_ID)), #indexed(#address(TO_ID)), #uint256(VALUE)))
29 | {STORAGE_UPDATE}
30 | ) orBool (
31 | // revert
32 | SC =/=K EVMC_SUCCESS
33 | // pre-conditions
34 | {EXTRA_PRE_CONDITIONS}
35 | ) orBool (
36 | // return false
37 | SC ==K EVMC_SUCCESS andBool NEW_OUTPUT ==K #buf(32, 0)
38 | andBool OLD_LOG ==K NEW_LOG
39 | andBool M1 ==IMap M2
40 | // pre-conditions
41 | {EXTRA_PRE_CONDITIONS}
42 | )
43 | )
44 | EXTRA_PRE_CONDITIONS:
45 | andBool (
46 | (
47 | CALLER_ID ==Int 0
48 | ) orBool (
49 | TO_ID ==Int 0
50 | ) orBool (
51 | VALUE ==Int 0 /* hkg, non-ERC20-compliant */
52 | ) orBool (
53 | BAL_TO +Int VALUE >=Int (2 ^Int 256)
54 | ) orBool (
55 | ACCT_ID ==Int TO_ID /* 04_chainlink, non-ERC20-compliant */
56 | )
57 | )
58 |
59 | [transfer-success-regular]
60 | +requires:
61 | // conditions
62 | andBool CALLER_ID =/=Int TO_ID
63 | STORAGE_UPDATE:
64 | andBool select(M2, #hashedLocation({COMPILER}, {_BALANCES}, CALLER_ID)) ==Int BAL_FROM -Int VALUE
65 | andBool select(M2, #hashedLocation({COMPILER}, {_BALANCES}, TO_ID)) ==Int BAL_TO +Int VALUE
66 | andBool M1 ==IMap M2 except
67 | (SetItem(#hashedLocation({COMPILER}, {_BALANCES}, CALLER_ID))
68 | SetItem(#hashedLocation({COMPILER}, {_BALANCES}, TO_ID)) .Set)
69 |
70 | [transfer-success-regular-overflow]
71 | +requires:
72 | // conditions
73 | andBool BAL_TO +Int VALUE SC
84 | output: _ => NEW_OUTPUT
85 | log: OLD_LOG => NEW_LOG
86 | storage: M1 => M2
87 | origStorage: M1
88 | +requires:
89 | andBool VALUE >Int BAL_FROM
90 | ensures:
91 | andBool (
92 | (
93 | // revert
94 | SC =/=K EVMC_SUCCESS
95 | ) orBool (
96 | // return false
97 | SC ==K EVMC_SUCCESS andBool NEW_OUTPUT ==K #buf(32, 0)
98 | andBool OLD_LOG ==K NEW_LOG
99 | andBool M1 ==IMap M2
100 | )
101 | )
102 |
--------------------------------------------------------------------------------
/erc20/all/mainnet-solar-specs/05_huobi.ini:
--------------------------------------------------------------------------------
1 | [pgm]
2 | code: "0x6060604052600436106100985763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461009d578063095ea7b31461012757806318160ddd1461015d57806323b872dd14610182578063313ce567146101aa57806370a08231146101d357806395d89b41146101f2578063a9059cbb14610205578063dd62ed3e14610227575b600080fd5b34156100a857600080fd5b6100b061024c565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156100ec5780820151838201526020016100d4565b50505050905090810190601f1680156101195780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561013257600080fd5b610149600160a060020a0360043516602435610283565b604051901515815260200160405180910390f35b341561016857600080fd5b6101706102f0565b60405190815260200160405180910390f35b341561018d57600080fd5b610149600160a060020a03600435811690602435166044356102f6565b34156101b557600080fd5b6101bd610426565b60405160ff909116815260200160405180910390f35b34156101de57600080fd5b610170600160a060020a036004351661042b565b34156101fd57600080fd5b6100b0610446565b341561021057600080fd5b610149600160a060020a036004351660243561047d565b341561023257600080fd5b610170600160a060020a036004358116906024351661053a565b60408051908101604052600a81527f48756f6269546f6b656e00000000000000000000000000000000000000000000602082015281565b600160a060020a03338116600081815260016020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35060015b92915050565b60035481565b600160a060020a03808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906103395750828110155b801561035f5750600160a060020a03841660009081526020819052604090205483810110155b1561041957600160a060020a03808516600090815260208190526040808220805487019055918716815220805484900390556000198110156103c957600160a060020a03808616600090815260016020908152604080832033909416835292905220805484900390555b83600160a060020a031685600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405190815260200160405180910390a36001915061041e565b600091505b509392505050565b601281565b600160a060020a031660009081526020819052604090205490565b60408051908101604052600281527f4854000000000000000000000000000000000000000000000000000000000000602082015281565b600160a060020a0333166000908152602081905260408120548290108015906104c05750600160a060020a03831660009081526020819052604090205482810110155b1561053257600160a060020a033381166000818152602081905260408082208054879003905592861680825290839020805486019055917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060016102ea565b5060006102ea565b600160a060020a039182166000908152600160209081526040808320939094168252919091522054905600a165627a7a72305820c129bd269d0adfb45f74a1d569e7170c49140570d880849318201de68509f99d0029"
3 |
--------------------------------------------------------------------------------
/erc20/all/mainnet-solar-specs/09_ino.ini:
--------------------------------------------------------------------------------
1 | [pgm]
2 | code: "0x6060604052600436106100b95763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100be578063095ea7b31461014857806318160ddd1461017e57806323b872dd146101a3578063313ce567146101cb57806342966c68146101f457806370a082311461020a57806379cc67901461022957806395d89b411461024b578063a9059cbb1461025e578063cae9ca5114610282578063dd62ed3e146102e7575b600080fd5b34156100c957600080fd5b6100d161030c565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561010d5780820151838201526020016100f5565b50505050905090810190601f16801561013a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015357600080fd5b61016a600160a060020a03600435166024356103aa565b604051901515815260200160405180910390f35b341561018957600080fd5b6101916103da565b60405190815260200160405180910390f35b34156101ae57600080fd5b61016a600160a060020a03600435811690602435166044356103e0565b34156101d657600080fd5b6101de610457565b60405160ff909116815260200160405180910390f35b34156101ff57600080fd5b61016a600435610460565b341561021557600080fd5b610191600160a060020a03600435166104eb565b341561023457600080fd5b61016a600160a060020a03600435166024356104fd565b341561025657600080fd5b6100d16105d9565b341561026957600080fd5b610280600160a060020a0360043516602435610644565b005b341561028d57600080fd5b61016a60048035600160a060020a03169060248035919060649060443590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061065395505050505050565b34156102f257600080fd5b610191600160a060020a0360043581169060243516610785565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b820191906000526020600020905b81548152906001019060200180831161038557829003601f168201915b505050505081565b600160a060020a033381166000908152600560209081526040808320938616835292905220819055600192915050565b60035481565b600160a060020a0380841660009081526005602090815260408083203390941683529290529081205482111561041557600080fd5b600160a060020a038085166000908152600560209081526040808320339094168352929052208054839003905561044d8484846107a2565b5060019392505050565b60025460ff1681565b600160a060020a0333166000908152600460205260408120548290101561048657600080fd5b600160a060020a03331660008181526004602052604090819020805485900390556003805485900390557fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a2506001919050565b60046020526000908152604090205481565b600160a060020a0382166000908152600460205260408120548290101561052357600080fd5b600160a060020a038084166000908152600560209081526040808320339094168352929052205482111561055657600080fd5b600160a060020a038084166000818152600460209081526040808320805488900390556005825280832033909516835293905282902080548590039055600380548590039055907fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a250600192915050565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b61064f3383836107a2565b5050565b60008361066081856103aa565b1561077d5780600160a060020a0316638f4ffcb1338630876040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600160a060020a0316600160a060020a0316815260200184815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107165780820151838201526020016106fe565b50505050905090810190601f1680156107435780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b151561076457600080fd5b6102c65a03f1151561077557600080fd5b505050600191505b509392505050565b600560209081526000928352604080842090915290825290205481565b6000600160a060020a03831615156107b957600080fd5b600160a060020a038416600090815260046020526040902054829010156107df57600080fd5b600160a060020a0383166000908152600460205260409020548281011161080557600080fd5b50600160a060020a0380831660008181526004602052604080822080549488168084528284208054888103909155938590528154870190915591909301927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a3600160a060020a038084166000908152600460205260408082205492871682529020540181146108a257fe5b505050505600a165627a7a72305820481e18755cb30fe23e13dc47857a7a81f01d1cceeccdb4e3c669a72b7b4633310029"
3 |
--------------------------------------------------------------------------------
/erc20/all/mainnet-solar-specs/Makefile:
--------------------------------------------------------------------------------
1 | FRAGMENT_INI_DIR=$(abspath $(THIS_FILE_DIR)/../fragments-solar)
2 | KPROVE_MAK_FILE=$(LOCAL_RESOURCES_DIR)/kprove-erc20-solar.mak
3 |
4 | include ../resources/kprove-erc20-group.mak
5 |
--------------------------------------------------------------------------------
/erc20/all/mainnet-solar-test/Makefile:
--------------------------------------------------------------------------------
1 | override IGNORE_ERRORS_OPT:=
2 | FRAGMENT_INI_DIR=$(abspath $(THIS_FILE_DIR)/../fragments-solar)
3 | KPROVE_MAK_FILE=$(LOCAL_RESOURCES_DIR)/kprove-erc20-solar.mak
4 |
5 | include ../resources/kprove-erc20-group.mak
6 |
--------------------------------------------------------------------------------
/erc20/all/mainnet-specs/05_huobi.ini:
--------------------------------------------------------------------------------
1 | [pgm]
2 | compiler: "Solidity"
3 | _totalSupply: 2
4 | _balances: 0
5 | _allowances: 1
6 | code: "0x6060604052600436106100985763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461009d578063095ea7b31461012757806318160ddd1461015d57806323b872dd14610182578063313ce567146101aa57806370a08231146101d357806395d89b41146101f2578063a9059cbb14610205578063dd62ed3e14610227575b600080fd5b34156100a857600080fd5b6100b061024c565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156100ec5780820151838201526020016100d4565b50505050905090810190601f1680156101195780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561013257600080fd5b610149600160a060020a0360043516602435610283565b604051901515815260200160405180910390f35b341561016857600080fd5b6101706102f0565b60405190815260200160405180910390f35b341561018d57600080fd5b610149600160a060020a03600435811690602435166044356102f6565b34156101b557600080fd5b6101bd610426565b60405160ff909116815260200160405180910390f35b34156101de57600080fd5b610170600160a060020a036004351661042b565b34156101fd57600080fd5b6100b0610446565b341561021057600080fd5b610149600160a060020a036004351660243561047d565b341561023257600080fd5b610170600160a060020a036004358116906024351661053a565b60408051908101604052600a81527f48756f6269546f6b656e00000000000000000000000000000000000000000000602082015281565b600160a060020a03338116600081815260016020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35060015b92915050565b60035481565b600160a060020a03808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906103395750828110155b801561035f5750600160a060020a03841660009081526020819052604090205483810110155b1561041957600160a060020a03808516600090815260208190526040808220805487019055918716815220805484900390556000198110156103c957600160a060020a03808616600090815260016020908152604080832033909416835292905220805484900390555b83600160a060020a031685600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405190815260200160405180910390a36001915061041e565b600091505b509392505050565b601281565b600160a060020a031660009081526020819052604090205490565b60408051908101604052600281527f4854000000000000000000000000000000000000000000000000000000000000602082015281565b600160a060020a0333166000908152602081905260408120548290108015906104c05750600160a060020a03831660009081526020819052604090205482810110155b1561053257600160a060020a033381166000818152602081905260408082208054879003905592861680825290839020805486019055917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060016102ea565b5060006102ea565b600160a060020a039182166000908152600160209081526040808320939094168252919091522054905600a165627a7a72305820c129bd269d0adfb45f74a1d569e7170c49140570d880849318201de68509f99d0029"
7 |
--------------------------------------------------------------------------------
/erc20/all/mainnet-specs/Makefile:
--------------------------------------------------------------------------------
1 | include ../resources/kprove-erc20-group.mak
2 |
--------------------------------------------------------------------------------
/erc20/all/mainnet-test/Makefile:
--------------------------------------------------------------------------------
1 | override IGNORE_ERRORS_OPT:=
2 |
3 | include ../resources/kprove-erc20-group.mak
4 |
--------------------------------------------------------------------------------
/erc20/all/resources/get-bytecode.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # Prerequisites: pip install pyetherchain
4 | #
5 | # usage: python3 get-bytecode.py
6 |
7 | import sys
8 | from pyetherchain.pyetherchain import EtherChain
9 |
10 |
11 | def main():
12 | address = sys.argv[1]
13 | print(EtherChain().account(address).code)
14 |
15 |
16 | if __name__ == '__main__':
17 | main()
18 |
--------------------------------------------------------------------------------
/erc20/all/resources/kprove-erc20-group.mak:
--------------------------------------------------------------------------------
1 | THIS_FILE_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
2 |
3 | #
4 | # Parameters
5 |
6 | NPROCS?=2
7 | TIMEOUT?=
8 | FRAGMENT_INI_DIR?=$(abspath $(THIS_FILE_DIR)/../fragments)
9 | KPROVE_MAK_FILE?=$(LOCAL_RESOURCES_DIR)/kprove-erc20.mak
10 |
11 | #
12 | # Settings
13 |
14 | # java or haskell
15 | K_BACKEND?=java
16 |
17 | IGNORE_ERRORS_OPT:=--ignore-errors
18 | LOCAL_RESOURCES_DIR:=$(THIS_FILE_DIR)
19 | ROOT:=$(abspath $(THIS_FILE_DIR)/../../..)
20 | RELATIVE_CURDIR:=$(strip $(patsubst $(ROOT)/%, %, $(filter $(ROOT)/%, $(CURDIR))))
21 | SPECS_DIR:=$(ROOT)/specs/$(K_BACKEND)
22 | FRAGMENT_INI_FILES:=$(sort $(wildcard $(FRAGMENT_INI_DIR)/*.ini))
23 | MAIN_INI_FILES:=$(sort $(wildcard *.ini))
24 | SPEC_INI_FILES:=$(patsubst %.ini, $(SPECS_DIR)/$(RELATIVE_CURDIR)/%/erc20-spec.ini, $(MAIN_INI_FILES))
25 |
26 | #
27 | # Tasks
28 |
29 | .PHONY: test concat split-proof-tests clean deps clean-deps
30 |
31 | test: $(SPEC_INI_FILES:=.test)
32 |
33 | # Makes $(SPEC_INI_FILES) non-intermediary
34 | concat: $(SPEC_INI_FILES)
35 |
36 | split-proof-tests: $(SPEC_INI_FILES:=.split-proof-tests)
37 |
38 | clean:
39 | rm -rf $(SPECS_DIR)
40 |
41 | deps:
42 | $(MAKE) -f $(KPROVE_MAK_FILE) deps SPEC_GROUP=resources SPEC_INI=mock.ini
43 |
44 | clean-deps:
45 | $(MAKE) -f $(KPROVE_MAK_FILE) clean-deps SPEC_GROUP=resources SPEC_INI=mock.ini
46 |
47 | .SECONDEXPANSION:
48 | $(SPECS_DIR)/%/erc20-spec.ini: $$(notdir $$*).ini $(FRAGMENT_INI_FILES)
49 | mkdir -p $(dir $@)
50 | cat $(FRAGMENT_INI_FILES) $(CURDIR)/$(notdir $*).ini > $@
51 |
52 | # Calling "clean-kevm-cache all" here leads to very long parse times on Jenkins, 30m+ on some specs, doesn't finish in 12+ hours.
53 | $(SPECS_DIR)/%/erc20-spec.ini.split-proof-tests: $(SPECS_DIR)/%/erc20-spec.ini
54 | $(MAKE) -f $(KPROVE_MAK_FILE) all SPEC_GROUP=$* SPEC_INI=$(basename $@)
55 |
56 | $(SPECS_DIR)/%/erc20-spec.ini.test: $(SPECS_DIR)/%/erc20-spec.ini.split-proof-tests
57 | $(MAKE) -f $(KPROVE_MAK_FILE) test SPEC_GROUP=$* SPEC_INI=$(basename $@) TIMEOUT=$(TIMEOUT) $(IGNORE_ERRORS_OPT) -j$(NPROCS)
58 |
59 | # Command to run just one spec. Argument: .test
60 | # patsubst below needed because $(dir ...) leaves a trailing slash.
61 | # TODO define function mydir - same as dir but without trailing slash
62 | .SECONDEXPANSION:
63 | $(SPECS_DIR)/%-spec.k.test: $$(dir $$@)erc20-spec.ini
64 | $(MAKE) -f $(KPROVE_MAK_FILE) $@ SPEC_GROUP=$(patsubst %/,%,$(dir $*)) SPEC_INI=$(dir $@)erc20-spec.ini TIMEOUT=$(TIMEOUT)
65 |
--------------------------------------------------------------------------------
/erc20/all/resources/kprove-erc20-solar.mak:
--------------------------------------------------------------------------------
1 | THIS_FILE_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
2 | SOLAR_DIR=$(ROOT_DIR)/erc20/solar
3 |
4 | KEVM_VERSION_FILE=$(ROOT_DIR)/erc20/.build/.kevm.rev
5 | KOMPILE_COMMAND=make build-specs K_BIN=$(K_BIN)
6 | override KEVM_BUILD_LAST_DIR=specs
7 |
8 | DEFINITION_MODULE:=VERIFICATION-SOLAR
9 | override LOCAL_LEMMAS=$(SOLAR_DIR)/verification-solar.k \
10 | $(ROOT_DIR)/erc20/verification.k \
11 | $(RESOURCES_DIR)/abstract-semantics-segmented-gas.k \
12 | $(RESOURCES_DIR)/evm-symbolic.k \
13 | $(ROOT_DIR)/erc20/evm-data-map-symbolic.k \
14 | $(SOLAR_DIR)/solar-abstract-semantics.k
15 | override TMPLS=$(SOLAR_DIR)/module-tmpl.k $(SOLAR_DIR)/spec-tmpl.k
16 |
17 | include $(THIS_FILE_DIR)/kprove-erc20.mak
18 |
--------------------------------------------------------------------------------
/erc20/all/resources/kprove-erc20.mak:
--------------------------------------------------------------------------------
1 | THIS_FILE_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
2 | ROOT_DIR:=$(abspath $(THIS_FILE_DIR)/../../..)
3 | RESOURCES_DIR:=$(ROOT_DIR)/resources
4 | LOCAL_RESOURCES_DIR:=$(THIS_FILE_DIR)
5 |
6 | KEVM_VERSION_FILE:=$(ROOT_DIR)/erc20/.build/.kevm.rev
7 | BASEDIR_LEMMAS=$(RESOURCES)/lemmas-buf.md
8 | LOCAL_LEMMAS:=$(ROOT_DIR)/erc20/verification.k \
9 | $(RESOURCES_DIR)/abstract-semantics-segmented-gas.k \
10 | $(RESOURCES_DIR)/evm-symbolic.k \
11 | $(ROOT_DIR)/erc20/evm-data-map-symbolic.k
12 | TMPLS:=../../module-tmpl.k $(LOCAL_RESOURCES_DIR)/spec-tmpl.k
13 |
14 | SPEC_NAMES:=totalSupply \
15 | balanceOf \
16 | allowance \
17 | approve \
18 | transfer-success-regular \
19 | transfer-success-regular-overflow \
20 | transfer-success-self \
21 | transfer-failure \
22 | transferFrom-success-regular \
23 | transferFrom-success-regular-overflow \
24 | transferFrom-success-self \
25 | transferFrom-failure
26 |
27 | KPROVE_OPTS:=--smt-prelude $(ROOT_DIR)/resources/evm.smt2
28 |
29 | include $(RESOURCES_DIR)/kprove.mak
30 |
--------------------------------------------------------------------------------
/erc20/all/resources/spec-tmpl.k:
--------------------------------------------------------------------------------
1 | // {RULENAME} {COMMENT}
2 | rule
3 | {K}
4 | 1
5 | NORMAL
6 | {SCHEDULE}
7 |
8 |
9 |
10 |
11 | {STATUSCODE}
12 | _
13 | _
14 | _ => _
15 |
16 | #parseByteStack({CODE})
17 | #computeValidJumpDests(#parseByteStack({CODE}))
18 | ACCT_ID // this
19 | CALLER_ID // msg.sender
20 | {CALLDATA} // msg.data
21 | 0 // msg.value
22 | .WordStack => _
23 | .Map => _
24 | 0 => _
25 | {GAS}
26 | 0 => _
27 | _ => _
28 | false // NOTE: non-static call
29 | CALL_DEPTH
30 |
31 |
32 | _
33 | {LOG}
34 | {REFUND}
35 |
36 | _
37 | ORIGIN_ID // tx.origin
38 | _
39 |
40 | _
41 | _
42 | _
43 | _
44 | _
45 | _
46 | _
47 | _
48 | _
49 | _
50 | _
51 | _
52 | _
53 | _
54 | _
55 |
56 | _
57 |
58 |
59 |
60 | 0
61 | SetItem(ACCT_ID) _:Set
62 |
63 |
64 | ACCT_ID
65 | _
66 | #parseByteStack({CODE})
67 | {STORAGE}
68 | {ORIGSTORAGE}
69 | _
70 |
71 | ...
72 |
73 | _
74 | _
75 | _
76 |
77 |
78 | requires #rangeAddress(ACCT_ID)
79 | andBool #rangeAddress(CALLER_ID)
80 | andBool #rangeAddress(ORIGIN_ID)
81 | andBool #range(0 <= CALL_DEPTH < 1024)
82 | {REQUIRES}
83 | ensures true
84 | {ENSURES}
85 | {ATTRIBUTE}
86 |
--------------------------------------------------------------------------------
/erc20/ds-token/Makefile:
--------------------------------------------------------------------------------
1 | #BUILD_DIR:=../.build
2 |
3 | LOCAL_LEMMAS:=../resources-concrete/verification.k \
4 | ../../resources/abstract-semantics-segmented-gas.k \
5 | ../../resources/evm-symbolic.k \
6 | ../../resources/evm-data-map-concrete.k
7 | TMPLS:=../module-tmpl.k ../spec-tmpl.k
8 |
9 | SPEC_NAMES:=totalSupply \
10 | balanceOf \
11 | allowance \
12 | approve-success \
13 | approve-failure \
14 | transfer-success-1 \
15 | transfer-success-2 \
16 | transfer-failure-1-a \
17 | transfer-failure-1-b \
18 | transfer-failure-1-c \
19 | transfer-failure-2-a \
20 | transfer-failure-2-b \
21 | transferFrom-success-1 \
22 | transferFrom-success-2 \
23 | transferFrom-failure-1-a \
24 | transferFrom-failure-1-b \
25 | transferFrom-failure-1-c \
26 | transferFrom-failure-1-d \
27 | transferFrom-failure-2-a \
28 | transferFrom-failure-2-b \
29 | transferFrom-failure-2-c
30 |
31 | include ../../resources/kprove.mak
32 |
--------------------------------------------------------------------------------
/erc20/ds-token/base.sol:
--------------------------------------------------------------------------------
1 | /// base.sol -- basic ERC20 implementation
2 |
3 | // Copyright (C) 2015, 2016, 2017 DappHub, LLC
4 |
5 | // Licensed under the Apache License, Version 2.0 (the "License").
6 | // You may not use this file except in compliance with the License.
7 |
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND (express or implied).
11 |
12 | pragma solidity ^0.4.10;
13 |
14 | import "erc20/erc20.sol";
15 | import "ds-math/math.sol";
16 |
17 | contract DSTokenBase is ERC20, DSMath {
18 | uint256 _supply;
19 | mapping (address => uint256) _balances;
20 | mapping (address => mapping (address => uint256)) _approvals;
21 |
22 | function DSTokenBase(uint256 supply) {
23 | _balances[msg.sender] = supply;
24 | _supply = supply;
25 | }
26 |
27 | function totalSupply() constant returns (uint256) {
28 | return _supply;
29 | }
30 | function balanceOf(address src) constant returns (uint256) {
31 | return _balances[src];
32 | }
33 | function allowance(address src, address guy) constant returns (uint256) {
34 | return _approvals[src][guy];
35 | }
36 |
37 | function transfer(address dst, uint wad) returns (bool) {
38 | assert(_balances[msg.sender] >= wad);
39 |
40 | _balances[msg.sender] = sub(_balances[msg.sender], wad);
41 | _balances[dst] = add(_balances[dst], wad);
42 |
43 | Transfer(msg.sender, dst, wad);
44 |
45 | return true;
46 | }
47 |
48 | function transferFrom(address src, address dst, uint wad) returns (bool) {
49 | assert(_balances[src] >= wad);
50 | assert(_approvals[src][msg.sender] >= wad);
51 |
52 | _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
53 | _balances[src] = sub(_balances[src], wad);
54 | _balances[dst] = add(_balances[dst], wad);
55 |
56 | Transfer(src, dst, wad);
57 |
58 | return true;
59 | }
60 |
61 | function approve(address guy, uint256 wad) returns (bool) {
62 | _approvals[msg.sender][guy] = wad;
63 |
64 | Approval(msg.sender, guy, wad);
65 |
66 | return true;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/erc20/ds-token/token.sol:
--------------------------------------------------------------------------------
1 | /// token.sol -- ERC20 implementation with minting and burning
2 |
3 | // Copyright (C) 2015, 2016, 2017 DappHub, LLC
4 |
5 | // Licensed under the Apache License, Version 2.0 (the "License").
6 | // You may not use this file except in compliance with the License.
7 |
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND (express or implied).
11 |
12 | pragma solidity ^0.4.10;
13 |
14 | import "ds-stop/stop.sol";
15 |
16 | import "./base.sol";
17 |
18 | contract DSToken is DSTokenBase(0), DSStop {
19 |
20 | bytes32 public symbol;
21 | uint256 public decimals = 18; // standard token precision. override to customize
22 |
23 | function DSToken(bytes32 symbol_) {
24 | symbol = symbol_;
25 | }
26 |
27 | function transfer(address dst, uint wad) stoppable note returns (bool) {
28 | return super.transfer(dst, wad);
29 | }
30 | function transferFrom(
31 | address src, address dst, uint wad
32 | ) stoppable note returns (bool) {
33 | return super.transferFrom(src, dst, wad);
34 | }
35 | function approve(address guy, uint wad) stoppable note returns (bool) {
36 | return super.approve(guy, wad);
37 | }
38 |
39 | function push(address dst, uint128 wad) returns (bool) {
40 | return transfer(dst, wad);
41 | }
42 | function pull(address src, uint128 wad) returns (bool) {
43 | return transferFrom(src, msg.sender, wad);
44 | }
45 |
46 | function mint(uint128 wad) auth stoppable note {
47 | _balances[msg.sender] = add(_balances[msg.sender], wad);
48 | _supply = add(_supply, wad);
49 | }
50 | function burn(uint128 wad) auth stoppable note {
51 | _balances[msg.sender] = sub(_balances[msg.sender], wad);
52 | _supply = sub(_supply, wad);
53 | }
54 |
55 | // Optional token name
56 |
57 | bytes32 public name = "";
58 |
59 | function setName(bytes32 name_) auth {
60 | name = name_;
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/erc20/gno/Makefile:
--------------------------------------------------------------------------------
1 | #BUILD_DIR:=../.build
2 |
3 | LOCAL_LEMMAS:=../resources-concrete/verification.k \
4 | ../../resources/abstract-semantics-segmented-gas.k \
5 | ../../resources/evm-symbolic.k \
6 | ../../resources/evm-data-map-concrete.k
7 | TMPLS:=../module-tmpl.k spec-tmpl.k
8 |
9 | SPEC_NAMES:=totalSupply-success \
10 | totalSupply-failure \
11 | balanceOf-success \
12 | balanceOf-failure \
13 | allowance-success \
14 | allowance-failure \
15 | approve-success \
16 | approve-failure \
17 | transfer-success-1 \
18 | transfer-success-2 \
19 | transfer-failure-1 \
20 | transfer-failure-2 \
21 | transfer-failure-3 \
22 | transferFrom-success-1 \
23 | transferFrom-success-2 \
24 | transferFrom-failure-1 \
25 | transferFrom-failure-2 \
26 | transferFrom-failure-3
27 |
28 | include ../../resources/kprove.mak
29 |
--------------------------------------------------------------------------------
/erc20/gno/README.md:
--------------------------------------------------------------------------------
1 | # Formal Verification of GNO ERC20 Token
2 |
3 | By Dominik Teiml (dominik@gnosis.pm), [Gnosis](https://www.gnosis.pm)
4 |
5 | We formally verified the GNO ERC20 token contract [runtime bytecode](./gno-erc20.bytes).
6 |
7 | We found the following deviations from [ERC20-EVM](../vyper/vyper-erc20-spec.ini):
8 |
9 | - In the [high-level Solidity code](https://etherscan.io/address/0x6810e776880c02933d47db1b9fc05908e5386b96#code), mapping of users' allowances is called `allowed`, hence we use that in our [spec template](./gno-erc20-spec.ini).
10 | - To verify full security, we have added failure cases to every function for when the `callValue` is not 0.
11 | - In `transfer-failure-1` and `transferFrom-failure-1`, `BAL_TO +Int VALUE >=Int (2 ^Int 256)` was removed from the constraint. The reason is the GNO was constructed with a fixed supply of 10 M. We present a pen & paper proof that the sum will always be 10 M below.
12 | - A new lemma was added to be added to [lemmas.md](../../resources/lemmas.md) to help K tool with the reduction of a specific term. We present the lemma as well as its soundness proof:
13 |
14 | ## Token Balances Sum Invariant
15 |
16 | Proposition:
17 |
18 | Except during a tx execution, sum of all token balances will always be 10 M.
19 |
20 | Proof:
21 |
22 | In the [spec](./gno-erc20-spec.ini), the `` term is always of the form `Location_i |-> Expr_i _:Map` for $0\leq i \leq 3$, where `Expr_i` is either a variable or a rewrite rules.
23 |
24 | Due to the way K framework works, the only storage locations that can be different after execution will be `Location_i` for $0 \leq i \leq 3$. It follows that the invariance must be checked only on the `Expr_i` terms for all function cases. We present such a proof:
25 |
26 | - totalSupply, balanceOf, allowances - do not modify storage
27 | - approve - does not modify `balances`
28 | - transfer-success-1 & transferFrom-success-1
29 | - sum of expressions before: `BAL_FROM + BAL_TO`
30 | - sum of expressions after: `(BAL_FROM - VALUE) + (BAL_TO + VALUE)` = `BAL_FROM + BAL_TO` since we are assuming neither expression overflows
31 | - transfer-success-2 & transferFrom-success-2 - do not modify storage
32 | - transfer-failure & transferFrom-failure - all 3 cases lead to either EVMC_REVERT or EVMC_INVALID_INSTRUCTION, reverting all state changes
33 |
34 | QED
35 |
36 |
37 | ## Lemma
38 |
39 | Lemma:
40 | ```
41 | rule chop ( W0:Int +Int W1:Int ) -Word W1:Int => chop ( W0 )
42 | ```
43 |
44 | Proof:
45 | We start with the definition of chop:
46 |
47 | ```
48 | rule chop ( I:Int ) => I modInt pow256
49 | ```
50 |
51 | where modInt is java's `mod` operator on BigIntegers.
52 |
53 | Hence:
54 |
55 | chop ( X ) = chop ( Y ) iff X ≡ Y (mod 2^256), and
56 |
57 | chop ( X ) ≡ X (mod 2^256)
58 |
59 | -Word is defined:
60 |
61 | ```
62 | rule W0 -Word W1 => chop( W0 -Int W1 ) requires W0 >=Int W1
63 | rule W0 -Word W1 => chop( (W0 +Int pow256) -Int W1 ) requires W0 = b
67 |
68 | Then LHS = chop ( chop ( a + b) - b)
69 |
70 | Now chop ( a + b ) ≡ a + b (mod 2^256),
71 |
72 | so chop ( a + b ) - b ≡ a,
73 |
74 | so chop ( chop ( a + b) - b) = chop ( a )
75 |
76 |
77 | When chop ( a + b ) < b, we get
78 |
79 | LHS = chop ( chop ( a + b) + 2^256 - b) and the rest is analogous.
80 |
81 | QED
82 |
83 | ## Conlusion
84 |
85 | In conclusion, the contract adheres to the desired behavior & our formal specification.
86 |
--------------------------------------------------------------------------------
/erc20/gno/spec-tmpl.k:
--------------------------------------------------------------------------------
1 | // {RULENAME}
2 | rule
3 | {K}
4 | 1
5 | NORMAL
6 | BYZANTIUM
7 |
8 |
9 |
10 |
11 | {STATUSCODE}
12 | _
13 | _
14 | _ => _
15 |
16 |
17 | #parseByteStack({CODE})
18 | #computeValidJumpDests(#parseByteStack({CODE}))
19 |
20 | ACCT_ID // contract owner
21 | CALLER_ID // who called this contract; in the begining, origin // msg.sender
22 |
23 | {CALLDATA}
24 |
25 | {CALLVALUE}
26 | .WordStack => _
27 | .Map => _
28 | 0 => _
29 | {GAS}
30 | 0 => _
31 | _ => _
32 |
33 | false // NOTE: non-static call
34 | CALL_DEPTH
35 |
36 |
37 |
38 | _
39 | {LOG}
40 | {REFUND} // TODO: more detail
41 |
42 |
43 | _
44 | ORIGIN_ID // who fires tx
45 | _
46 |
47 | _
48 | _
49 | _
50 | _
51 | _
52 | _
53 | _
54 | _
55 | _
56 | _
57 | _
58 | _
59 | _
60 | _
61 | _
62 |
63 | _
64 |
65 |
66 |
67 |
68 | 0
69 | SetItem(ACCT_ID) _:Set
70 |
71 |
72 |
73 | ACCT_ID
74 | _
75 | #parseByteStack({CODE})
76 |
77 | {STORAGE}
78 |
79 | _
80 | _
81 |
82 | ...
83 |
84 |
85 | _
86 | _
87 | _
88 |
89 |
90 | requires 0 <=Int ACCT_ID andBool ACCT_ID (RETURN RET_ADDR:Int 32 ~> _)
6 | +k: #execute => #exception
7 | callData: #abiCallData("totalSupply", .TypedArgs)
8 | -localMem: .Map => ( .Map[ RET_ADDR := #asByteStackInWidth(TOTAL, 32) ] _:Map )
9 | +localMem: .Map => _:Map
10 | gas: {GASCAP} => _
11 | log: _
12 | refund: _
13 | -storage:
14 | - #hashedLocation({COMPILER}, {_TOTALSUPPLY}, .IntList) |-> TOTAL
15 | - _:Map
16 | +storage: _:Map
17 | requires:
18 | - andBool 0 <=Int TOTAL andBool TOTAL (RETURN RET_ADDR:Int 32 ~> _)
22 | @@ -75,12 +72,12 @@
23 | [transfer-success-1]
24 | storage:
25 | #hashedLocation({COMPILER}, {_BALANCES}, CALLER_ID) |-> (BAL_FROM => BAL_FROM -Int VALUE)
26 | - #hashedLocation({COMPILER}, {_BALANCES}, TO_ID) |-> (BAL_TO => BAL_TO +Int VALUE)
27 | + #hashedLocation({COMPILER}, {_BALANCES}, TO_ID) |-> (BAL_TO => BAL_TO +Word VALUE)
28 | _:Map
29 | +requires:
30 | andBool CALLER_ID =/=Int TO_ID
31 | andBool VALUE <=Int BAL_FROM
32 | - andBool BAL_TO +Int VALUE Int 0
34 |
35 | [transfer-success-2]
36 | storage:
37 | @@ -89,10 +86,11 @@
38 | +requires:
39 | andBool CALLER_ID ==Int TO_ID
40 | andBool VALUE <=Int BAL_FROM
41 | + andBool VALUE >Int 0
42 |
43 | [transfer-failure]
44 | -k: #execute => #exception
45 | -localMem: .Map => _:Map
46 | +k: #execute => (RETURN RET_ADDR:Int 32 ~> _)
47 | +localMem: .Map => ( .Map[ RET_ADDR := #asByteStackInWidth(0, 32) ] _:Map )
48 | log: _
49 |
50 | [transfer-failure-1]
51 | @@ -103,7 +101,7 @@
52 | +requires:
53 | andBool CALLER_ID =/=Int TO_ID
54 | andBool ( VALUE >Int BAL_FROM
55 | - orBool BAL_TO +Int VALUE >=Int (2 ^Int 256) )
56 | + orBool VALUE <=Int 0 )
57 |
58 | [transfer-failure-2]
59 | storage:
60 | @@ -111,7 +109,8 @@
61 | _:Map
62 | +requires:
63 | andBool CALLER_ID ==Int TO_ID
64 | - andBool VALUE >Int BAL_FROM
65 | + andBool ( VALUE >Int BAL_FROM
66 | + orBool VALUE <=Int 0 )
67 |
68 | [transferFrom]
69 | callData: #abiCallData("transferFrom", #address(FROM_ID), #address(TO_ID), #uint256(VALUE))
70 | @@ -133,14 +132,14 @@
71 | [transferFrom-success-1]
72 | storage:
73 | #hashedLocation({COMPILER}, {_BALANCES}, FROM_ID) |-> (BAL_FROM => BAL_FROM -Int VALUE)
74 | - #hashedLocation({COMPILER}, {_BALANCES}, TO_ID) |-> (BAL_TO => BAL_TO +Int VALUE)
75 | + #hashedLocation({COMPILER}, {_BALANCES}, TO_ID) |-> (BAL_TO => BAL_TO +Word VALUE)
76 | #hashedLocation({COMPILER}, {_ALLOWANCES}, FROM_ID CALLER_ID) |-> (ALLOW => ALLOW -Int VALUE)
77 | _:Map
78 | +requires:
79 | andBool FROM_ID =/=Int TO_ID
80 | andBool VALUE <=Int BAL_FROM
81 | - andBool BAL_TO +Int VALUE Int 0
84 |
85 | [transferFrom-success-2]
86 | storage:
87 | @@ -151,10 +150,11 @@
88 | andBool FROM_ID ==Int TO_ID
89 | andBool VALUE <=Int BAL_FROM
90 | andBool VALUE <=Int ALLOW
91 | + andBool VALUE >Int 0
92 |
93 | [transferFrom-failure]
94 | -k: #execute => #exception
95 | -localMem: .Map => _:Map
96 | +k: #execute => (RETURN RET_ADDR:Int 32 ~> _)
97 | +localMem: .Map => ( .Map[ RET_ADDR := #asByteStackInWidth(0, 32) ] _:Map )
98 | log: _
99 |
100 | [transferFrom-failure-1]
101 | @@ -166,8 +166,8 @@
102 | +requires:
103 | andBool FROM_ID =/=Int TO_ID
104 | andBool ( VALUE >Int BAL_FROM
105 | - orBool BAL_TO +Int VALUE >=Int (2 ^Int 256)
106 | - orBool VALUE >Int ALLOW )
107 | + orBool VALUE >Int ALLOW
108 | + orBool VALUE <=Int 0 )
109 |
110 | [transferFrom-failure-2]
111 | storage:
112 | @@ -177,12 +177,14 @@
113 | +requires:
114 | andBool FROM_ID ==Int TO_ID
115 | andBool ( VALUE >Int BAL_FROM
116 | - orBool VALUE >Int ALLOW )
117 | + orBool VALUE >Int ALLOW
118 | + orBool VALUE <=Int 0 )
119 |
--------------------------------------------------------------------------------
/erc20/hobby/Makefile:
--------------------------------------------------------------------------------
1 | #BUILD_DIR:=../.build
2 |
3 | LOCAL_LEMMAS:=../resources-concrete/verification.k \
4 | ../../resources/abstract-semantics-segmented-gas.k \
5 | ../../resources/evm-symbolic.k \
6 | ../../resources/evm-data-map-concrete.k
7 | TMPLS:=../module-tmpl.k ../spec-tmpl.k
8 |
9 | SPEC_NAMES:=totalSupply \
10 | balanceOf \
11 | allowance \
12 | approve-success \
13 | approve-failure \
14 | transfer-success-1 \
15 | transfer-success-2 \
16 | transfer-failure-1 \
17 | transfer-failure-2 \
18 | transferFrom-success-1 \
19 | transferFrom-success-2 \
20 | transferFrom-failure-1 \
21 | transferFrom-failure-2
22 |
23 | include ../../resources/kprove.mak
24 |
--------------------------------------------------------------------------------
/erc20/hobby/MyKidsEducationToken.fixed.gist:
--------------------------------------------------------------------------------
1 | https://gist.github.com/anonymous/06f04e32f80583b4db3dffb9cb341830
2 |
--------------------------------------------------------------------------------
/erc20/module-tmpl.k:
--------------------------------------------------------------------------------
1 | requires "abstract-semantics-segmented-gas.k"
2 | requires "verification.k"
3 |
4 | module {MODULE}-SPEC
5 | imports ABSTRACT-SEMANTICS-SEGMENTED-GAS
6 | imports VERIFICATION
7 |
8 | {RULES}
9 |
10 | endmodule
11 |
--------------------------------------------------------------------------------
/erc20/resources-concrete/verification.k:
--------------------------------------------------------------------------------
1 | requires "evm-symbolic.k"
2 | requires "evm-data-map-concrete.k"
3 | requires "edsl.k"
4 | requires "../lemmas.k"
5 |
6 | module VERIFICATION
7 | imports EVM-SYMBOLIC
8 | imports EVM-DATA-MAP-CONCRETE
9 | imports EDSL
10 | imports LEMMAS
11 |
12 | //Rules for #padToWidth with non-regular symbolic arguments.
13 | rule #padToWidth(32, #asByteStack(V)) => #asByteStackInWidth(V, 32)
14 | requires 0 <=Int V andBool V WS
17 | requires #noOverflow(WS) andBool N ==Int #sizeWordStack(WS)
18 |
19 | rule chop ( W0:Int +Int W1:Int ) -Word W1:Int => chop ( W0 )
20 | requires #rangeUInt(256, W0) andBool #rangeUInt(256, W1)
21 | endmodule
22 |
--------------------------------------------------------------------------------
/erc20/solar/Makefile:
--------------------------------------------------------------------------------
1 | KEVM_VERSION_FILE:=../.build/.kevm.rev
2 | KOMPILE_COMMAND=make build-specs K_BIN=$(K_BIN)
3 | override KEVM_BUILD_LAST_DIR=specs
4 |
5 | # Required to have different lemmas dir from non-#buf ERC20 specs.
6 | SPEC_GROUP:=erc20/buf/solar
7 |
8 | DEFINITION_MODULE:=VERIFICATION-SOLAR
9 |
10 | BASEDIR_LEMMAS=$(RESOURCES)/lemmas-buf.md
11 | LOCAL_LEMMAS:=verification-solar.k \
12 | ../verification.k \
13 | ../../resources/abstract-semantics-segmented-gas.k \
14 | ../../resources/evm-symbolic.k \
15 | ../evm-data-map-symbolic.k \
16 | solar-abstract-semantics.k
17 | TMPLS:=module-tmpl.k spec-tmpl.k
18 |
19 | KPROVE_OPTS:=--smt-prelude $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../resources/evm.smt2)
20 |
21 | SPEC_NAMES:=totalSupply \
22 | balanceOf \
23 | allowance \
24 | approve \
25 | transfer-success-1 \
26 | transfer-success-2 \
27 | transfer-failure-1-a \
28 | transfer-failure-1-b \
29 | transfer-failure-2 \
30 | transferFrom-success-1 \
31 | transferFrom-success-2 \
32 | transferFrom-failure-1-a \
33 | transferFrom-failure-1-b \
34 | transferFrom-failure-2
35 |
36 | include ../../resources/kprove.mak
37 |
--------------------------------------------------------------------------------
/erc20/solar/module-tmpl.k:
--------------------------------------------------------------------------------
1 | requires "abstract-semantics-segmented-gas.k"
2 | requires "solar-abstract-semantics.k"
3 | requires "verification-solar.k"
4 |
5 | module {MODULE}-SPEC
6 | imports ABSTRACT-SEMANTICS-SEGMENTED-GAS
7 | imports SOLAR-ABSTRACT-SEMANTICS
8 | imports VERIFICATION-SOLAR
9 |
10 | {RULES}
11 |
12 | endmodule
13 |
--------------------------------------------------------------------------------
/erc20/solar/solar-abstract-semantics.k:
--------------------------------------------------------------------------------
1 | requires "evm-imp-specs.k"
2 |
3 | module SOLAR-ABSTRACT-SEMANTICS
4 | imports EVM-IMP-SPECS
5 |
6 | rule #assume R:Bool => .
7 | ensures R
8 | [trusted]
9 |
10 | endmodule
11 |
--------------------------------------------------------------------------------
/erc20/solar/spec-tmpl.k:
--------------------------------------------------------------------------------
1 | // {RULENAME}
2 | rule
3 | {K}
4 | 1
5 | NORMAL
6 | {SCHEDULE}
7 |
8 |
9 |
10 |
11 | {STATUSCODE}
12 | _
13 | _
14 | _ => _
15 |
16 |
17 | _ => _
18 | _ => _
19 |
20 | _ => _ // contract owner
21 | _ => _ // who called this contract; in the begining, origin // msg.sender
22 |
23 | _ => _
24 |
25 | 0
26 | .WordStack => _
27 | .Map => _
28 | 0 => _
29 | _ => _
30 | 0 => _
31 | {GAS}
32 |
33 | false // NOTE: non-static call
34 | CALL_DEPTH => _
35 |
36 |
37 |
38 | _
39 | {LOG}
40 | {REFUND} // TODO: more detail
41 |
42 |
43 | _
44 | ORIGIN_ID // who fires tx
45 | _
46 |
47 | _
48 | _
49 | _
50 | _
51 | _
52 | _
53 | _
54 | _
55 | _
56 | _
57 | _
58 | _
59 | _
60 | _
61 | _
62 |
63 | _
64 |
65 |
66 |
67 |
68 | 0
69 | SetItem(ACCT_ID) _:Set
70 |
71 |
72 |
73 | ACCT_ID
74 | _
75 | #parseByteStack({CODE})
76 | {STORAGE}
77 | {ORIGSTORAGE}
78 | _
79 |
80 | ...
81 |
82 |
83 | _
84 | _
85 | _
86 |
87 |
88 | {COMMANDVARS}
89 | requires #rangeAddress(ACCT_ID)
90 | andBool #rangeAddress(CALLER_ID)
91 | andBool #rangeAddress(ORIGIN_ID)
92 | andBool #range(0 <= CALL_DEPTH < 1020) // providing enough room for 4 calls, including test calls
93 | andBool notBool (ACCT_ID in #precompiledAccounts({SCHEDULE}))
94 | {REQUIRES}
95 | ensures true
96 | {ENSURES}
--------------------------------------------------------------------------------
/erc20/solar/verification-solar.k:
--------------------------------------------------------------------------------
1 | requires "verification.k"
2 | requires "evm-imp-specs.k"
3 |
4 | module VERIFICATION-SOLAR
5 | imports VERIFICATION
6 | imports EVM-IMP-SPECS
7 |
8 | rule #sizeWordStack(#padToWidth(N1, _), N2) => N1 +Int N2
9 |
10 | // #buf unification when size is equal
11 | rule #buf(SIZE, DATA1) ==K #buf(SIZE, DATA2) => DATA1 ==K DATA2
12 | //todo is requires needed? Would require lemmas that ensure: rangeUInt(256, select(STORAGE, _))
13 | /*requires #range(0 <= DATA1 < (2 ^Int (SIZE *Int 8)))
14 | andBool #range(0 <= DATA2 < (2 ^Int (SIZE *Int 8)))*/
15 |
16 | endmodule
17 |
--------------------------------------------------------------------------------
/erc20/spec-tmpl.k:
--------------------------------------------------------------------------------
1 | // {RULENAME}
2 | rule
3 | {K}
4 | 1
5 | NORMAL
6 | {SCHEDULE}
7 |
8 |
9 |
10 |
11 | {STATUSCODE}
12 | _
13 | _
14 | _ => _
15 |
16 |
17 | #parseByteStack({CODE})
18 | #computeValidJumpDests(#parseByteStack({CODE}))
19 |
20 | ACCT_ID // contract owner
21 | CALLER_ID // who called this contract; in the begining, origin // msg.sender
22 |
23 | {CALLDATA}
24 |
25 | 0
26 | .WordStack => _
27 | .Map => _
28 | 0 => _
29 | {GAS}
30 | 0 => _
31 | _ => _
32 |
33 | false // NOTE: non-static call
34 | CALL_DEPTH
35 |
36 |
37 |
38 | _
39 | {LOG}
40 | {REFUND} // TODO: more detail
41 |
42 |
43 | _
44 | ORIGIN_ID // who fires tx
45 | _
46 |
47 | _
48 | _
49 | _
50 | _
51 | _
52 | _
53 | _
54 | _
55 | _
56 | _
57 | _
58 | _
59 | _
60 | _
61 | _
62 |
63 | _
64 |
65 |
66 |
67 |
68 | 0
69 | SetItem(ACCT_ID) _:Set
70 |
71 |
72 |
73 | ACCT_ID
74 | _
75 | #parseByteStack({CODE})
76 | {STORAGE}
77 | {ORIGSTORAGE}
78 | _
79 |
80 | ...
81 |
82 |
83 | _
84 | _
85 | _
86 |
87 |
88 | requires #rangeAddress(ACCT_ID)
89 | andBool #rangeAddress(CALLER_ID)
90 | andBool #rangeAddress(ORIGIN_ID)
91 | andBool #range(0 <= CALL_DEPTH < 1024)
92 | {REQUIRES}
93 | {ENSURES}
--------------------------------------------------------------------------------
/erc20/verification.k:
--------------------------------------------------------------------------------
1 | requires "evm-symbolic.k"
2 | requires "evm-data-map-symbolic.k"
3 | requires "edsl.k"
4 | requires "../lemmas-buf.k"
5 |
6 | module VERIFICATION
7 | imports EVM-SYMBOLIC
8 | imports EVM-DATA-MAP-SYMBOLIC
9 | imports EDSL
10 | imports LEMMAS
11 |
12 | rule #buf(N, #asWord(WS)) => WS
13 | requires #noOverflow(WS) andBool N ==Int #sizeByteArray(WS)
14 |
15 | rule chop ( W0:Int +Int W1:Int ) -Word W1:Int => chop ( W0 )
16 | requires #rangeUInt(256, W0) andBool #rangeUInt(256, W1)
17 |
18 |
19 | // ########################
20 | // Gas
21 | // ########################
22 |
23 | rule 0 <=Int X -Int #gas(A, B, C) => true requires #gas(A, B, C) <=Int X
24 | rule X -Int #gas(A, B, C) true requires X (B2 +Int C2) -Int (B1 +Int C1)
27 |
28 | rule 0 <=Int #gas(_, _, _) => true
29 | rule #gas(_, _, _) true
30 |
31 |
32 | // ########################
33 | // Buffer Reasoning
34 | // ########################
35 |
36 | rule #noOverflowAux(BUF) => true requires #isBuf(BUF)
37 | rule #noOverflowAux(WS1 ++ WS2) => #noOverflowAux(WS1) andBool #noOverflowAux(WS2)
38 |
39 | // #buf unfolding, for concrete DATA
40 | rule #buf(SIZE, DATA) => #padToWidth(SIZE, #asByteStack(DATA)) requires #range(0 <= DATA < (2 ^Int (SIZE *Int 8))) [concrete]
41 |
42 | // #buf folding, for symbolic DATA - todo test - might apply in too many places
43 | rule #padToWidth(SIZE, #asByteStack(DATA)) => #buf(SIZE, DATA) requires notBool #isConcrete(DATA)
44 |
45 | // ########################
46 | // Memory Reasoning
47 | // ########################
48 |
49 | rule store(M, K, select(M, K)) => M
50 |
51 | syntax Bool ::= Map "==IMap" Map [function, smtlib(=)]
52 | syntax Bool ::= Map "==IMap" Map "except" Set [function]
53 | // --------------------------------------------------------
54 | rule store(M1, K, _) ==IMap M2 except Ks
55 | => M1 ==IMap M2 except Ks
56 | requires K in Ks
57 |
58 | rule M1 ==IMap store(M2, K, _) except Ks
59 | => M1 ==IMap M2 except Ks
60 | requires K in Ks
61 |
62 | rule M1 ==IMap M2 except _ => true
63 | requires M1 ==K M2 // structural equality
64 |
65 | syntax Set ::= keys(Map) [function]
66 | // -----------------------------------
67 | rule K1 in keys(store(M, K2, _)) => true requires K1 ==Int K2
68 | rule K1 in keys(store(M, K2, _)) => K1 in keys(M) requires K1 =/=Int K2
69 |
70 | //Reduces IMaps where multiple entries share the same key
71 | rule store(store(M, K0, V0), K1, V1) => store(M, K0, V1)
72 | requires K0 ==Int K1
73 |
74 | rule store(store(M, K0, V0), K1, V1) => store(store(M, K1, V1), K0, V0)
75 | requires K0 =/=Int K1 andBool K1 in keys(M)
76 |
77 | rule notBool( hash2(K1,V1) ==K hash2(K2,V2) ) => K1 =/=Int K2 orBool V1 =/=Int V2
78 |
79 | rule A ==K hash2(K,V) => hash2(K,V) ==K A
80 | requires #isConcrete(A)
81 |
82 | //Assumption of non-collision between hashes and small constants that likely represent memory addresses or offsets.
83 | rule notBool( hash2(_,_) ==K A ) => true
84 | requires #isConcrete(A) andBool A <=Int 20
85 |
86 | // ########################
87 | // Arithmetic
88 | // ########################
89 |
90 | rule A -Int B +Int B => A
91 | rule A +Int B -Int B => A
92 | rule A +Int B -Int A => B
93 | rule A +Int (B -Int A) => B
94 |
95 | endmodule
96 |
--------------------------------------------------------------------------------
/erc20/vyper/.build/.kevm.rev:
--------------------------------------------------------------------------------
1 | 27ab1d7e6114e13bc31294d99cafd5d6d0ce7131
2 |
--------------------------------------------------------------------------------
/erc20/vyper/ERC20.v.bytes:
--------------------------------------------------------------------------------
1 | 0x600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a05263d0e30db06000511415610168573460008112585761014052336101605261016051600060c052602060c02001546101405161016051600060c052602060c020015401116101405115176100e657600080fd5b6101405161016051600060c052602060c02001540161016051600060c052602060c020015560025461014051600254011161014051151761012657600080fd5b610140516002540160025561014051610180526101605160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020610180a3005b632e1a7d4d6000511415610260576020600461014037341561018957600080fd5b33610160526101405161016051600060c052602060c020015410156101ad57600080fd5b6101405161016051600060c052602060c02001540361016051600060c052602060c02001556101405160025410156101e457600080fd5b61014051600254036002556000600060006000600160605161014051806040519013585780919012585702610160516000f161021f57600080fd5b61014051610180526000610160517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020610180a3600160005260206000f3005b6318160ddd600051141561028657341561027957600080fd5b60025460005260206000f3005b6370a0823160005114156102cd57602060046101403734156102a757600080fd5b60043560205181101558575061014051600060c052602060c020015460005260206000f3005b63a9059cbb60005114156103e057604060046101403734156102ee57600080fd5b60043560205181101558575033610180526101605161018051600060c052602060c0200154101561031e57600080fd5b6101605161018051600060c052602060c02001540361018051600060c052602060c020015561014051600060c052602060c02001546101605161014051600060c052602060c0200154011161016051151761037857600080fd5b6101605161014051600060c052602060c02001540161014051600060c052602060c0200155610160516101a05261014051610180517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206101a0a3600160005260206000f3005b6323b872dd6000511415610559576060600461014037341561040157600080fd5b600435602051811015585750602435602051811015585750336101a0526101a05161014051600160c052602060c0200160c052602060c02001546101c0526101805161014051600060c052602060c0200154101561045e57600080fd5b6101805161014051600060c052602060c02001540361014051600060c052602060c020015561016051600060c052602060c02001546101805161016051600060c052602060c020015401116101805115176104b857600080fd5b6101805161016051600060c052602060c02001540161016051600060c052602060c0200155610180516101c05110156104f057600080fd5b610180516101c051036101a05161014051600160c052602060c0200160c052602060c0200155610180516101e05261016051610140517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206101e0a3600160005260206000f3005b63095ea7b360005114156105ef576040600461014037341561057a57600080fd5b6004356020518110155857503361018052610160516101405161018051600160c052602060c0200160c052602060c0200155610160516101a05261014051610180517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560206101a0a3600160005260206000f3005b63dd62ed3e600051141561064f576040600461014037341561061057600080fd5b6004356020518110155857506024356020518110155857506101605161014051600160c052602060c0200160c052602060c020015460005260206000f3005b
2 |
--------------------------------------------------------------------------------
/erc20/vyper/ERC20.v.py:
--------------------------------------------------------------------------------
1 | # Solidity-Compatible EIP20/ERC20 Token
2 | # Implements https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
3 | # Author: Phil Daian
4 |
5 | # The use of the num256 datatype as in this token is not
6 | # recommended, as it can pose security risks.
7 |
8 | # This token is intended as a proof of concept towards
9 | # language interoperability and not for production use.
10 |
11 | # Events issued by the contract
12 | Transfer: __log__({_from: indexed(address), _to: indexed(address), _value: num256})
13 | Approval: __log__({_owner: indexed(address), _spender: indexed(address), _value: num256})
14 |
15 | balances: num256[address]
16 | allowances: (num256[address])[address]
17 | num_issued: num256
18 |
19 | @public
20 | @payable
21 | def deposit():
22 | _value = as_num256(msg.value)
23 | _sender = msg.sender
24 | self.balances[_sender] = num256_add(self.balances[_sender], _value)
25 | self.num_issued = num256_add(self.num_issued, _value)
26 | # Fire deposit event as transfer from 0x0
27 | log.Transfer(0x0000000000000000000000000000000000000000, _sender, _value)
28 |
29 | @public
30 | def withdraw(_value : num256) -> bool:
31 | _sender = msg.sender
32 | # Make sure sufficient funds are present, op will not underflow supply
33 | # implicitly through overflow protection
34 | self.balances[_sender] = num256_sub(self.balances[_sender], _value)
35 | self.num_issued = num256_sub(self.num_issued, _value)
36 | send(_sender, as_wei_value(as_num128(_value), wei))
37 | # Fire withdraw event as transfer to 0x0
38 | log.Transfer(_sender, 0x0000000000000000000000000000000000000000, _value)
39 | return true
40 |
41 | @public
42 | @constant
43 | def totalSupply() -> num256:
44 | return self.num_issued
45 |
46 | @public
47 | @constant
48 | def balanceOf(_owner : address) -> num256:
49 | return self.balances[_owner]
50 |
51 | @public
52 | def transfer(_to : address, _value : num256) -> bool:
53 | _sender = msg.sender
54 | # Make sure sufficient funds are present implicitly through overflow protection
55 | self.balances[_sender] = num256_sub(self.balances[_sender], _value)
56 | self.balances[_to] = num256_add(self.balances[_to], _value)
57 | # Fire transfer event
58 | log.Transfer(_sender, _to, _value)
59 | return true
60 |
61 | @public
62 | def transferFrom(_from : address, _to : address, _value : num256) -> bool:
63 | _sender = msg.sender
64 | allowance = self.allowances[_from][_sender]
65 | # Make sure sufficient funds/allowance are present implicitly through overflow protection
66 | self.balances[_from] = num256_sub(self.balances[_from], _value)
67 | self.balances[_to] = num256_add(self.balances[_to], _value)
68 | self.allowances[_from][_sender] = num256_sub(allowance, _value)
69 | # Fire transfer event
70 | log.Transfer(_from, _to, _value)
71 | return true
72 |
73 | @public
74 | def approve(_spender : address, _value : num256) -> bool:
75 | _sender = msg.sender
76 | self.allowances[_sender][_spender] = _value
77 | # Fire approval event
78 | log.Approval(_sender, _spender, _value)
79 | return true
80 |
81 | @public
82 | @constant
83 | def allowance(_owner : address, _spender : address) -> num256:
84 | return self.allowances[_owner][_spender]
85 |
86 |
--------------------------------------------------------------------------------
/erc20/vyper/Makefile:
--------------------------------------------------------------------------------
1 | # Bytecode compiled with old Vyper. Needs KEVM version before Vyper storage layout fix.
2 | KEVM_VERSION_FILE:=.build/.kevm.rev
3 |
4 | # Required to have different lemmas dir from non-#buf ERC20 specs.
5 | SPEC_GROUP:=erc20/vyper/vyper
6 |
7 | DEFINITION_MODULE:=VYPER-VERIFICATION
8 |
9 | BASEDIR_LEMMAS=lemmas-buf.md
10 | # We need gnosis version of abstract-semantics-segmented-gas.k because we use an older KEVM.
11 | LOCAL_LEMMAS:=vyper-verification.k \
12 | ../verification.k \
13 | ../../gnosis/abstract-semantics-segmented-gas.k \
14 | ../../resources/evm-symbolic.k \
15 | ../../resources/evm-data-map-symbolic.k \
16 | ../../resources/not-KLabel.k
17 | TMPLS:=module-tmpl.k spec-tmpl.k
18 |
19 | KPROVE_OPTS=--smt-prelude $(RESOURCES)/evm.smt2
20 |
21 | SPEC_NAMES:=totalSupply \
22 | balanceOf \
23 | allowance \
24 | approve \
25 | transfer-success-1 \
26 | transfer-success-2 \
27 | transfer-failure-1 \
28 | transfer-failure-2 \
29 | transferFrom-success-1 \
30 | transferFrom-success-2 \
31 | transferFrom-failure-1 \
32 | transferFrom-failure-2
33 |
34 | include ../../resources/kprove.mak
35 |
--------------------------------------------------------------------------------
/erc20/vyper/module-tmpl.k:
--------------------------------------------------------------------------------
1 | requires "abstract-semantics-segmented-gas.k"
2 | requires "vyper-verification.k"
3 |
4 | // Custom module-tmpl needed to import VYPER-VERIFICATION, in turn needed to import NOT-KLABEL
5 | module {MODULE}-SPEC
6 | imports ABSTRACT-SEMANTICS-SEGMENTED-GAS
7 | imports VYPER-VERIFICATION
8 |
9 | {RULES}
10 |
11 | endmodule
12 |
--------------------------------------------------------------------------------
/erc20/vyper/spec-tmpl.k:
--------------------------------------------------------------------------------
1 | // {RULENAME}
2 | rule
3 | {K}
4 | 1
5 | NORMAL
6 | {SCHEDULE}
7 |
8 |
9 |
10 |
11 | {STATUSCODE}
12 | _
13 | _
14 | _ => _
15 |
16 |
17 | #parseByteStack({CODE})
18 | #computeValidJumpDests(#parseByteStack({CODE}))
19 |
20 | ACCT_ID // contract owner
21 | CALLER_ID // who called this contract; in the begining, origin // msg.sender
22 |
23 | {CALLDATA}
24 |
25 | 0
26 | .WordStack => _
27 | .Map => _
28 | 0 => _
29 | {GAS}
30 | 0 => _
31 | _ => _
32 |
33 | false // NOTE: non-static call
34 | CALL_DEPTH
35 |
36 |
37 |
38 | _
39 | {LOG}
40 | {REFUND} // TODO: more detail
41 |
42 |
43 | _
44 | ORIGIN_ID // who fires tx
45 | _
46 |
47 | _
48 | _
49 | _
50 | _
51 | _
52 | _
53 | _
54 | _
55 | _
56 | _
57 | _
58 | _
59 | _
60 | _
61 | _
62 |
63 | _
64 |
65 |
66 |
67 |
68 | SetItem(ACCT_ID) _:Set
69 |
70 |
71 |
72 | ACCT_ID
73 | _
74 | #parseByteStack({CODE})
75 | {STORAGE}
76 | {ORIGSTORAGE}
77 | _
78 |
79 | ...
80 |
81 |
82 | _
83 | _
84 | _
85 |
86 |
87 | requires #rangeAddress(ACCT_ID)
88 | andBool #rangeAddress(CALLER_ID)
89 | andBool #rangeAddress(ORIGIN_ID)
90 | andBool #range(0 <= CALL_DEPTH < 1024)
91 | {REQUIRES}
92 | {ENSURES}
--------------------------------------------------------------------------------
/erc20/vyper/vyper-verification.k:
--------------------------------------------------------------------------------
1 | requires "verification.k"
2 | requires "not-KLabel.k"
3 |
4 | module VYPER-VERIFICATION [symbolic]
5 | imports VERIFICATION
6 | imports NOT-KLABEL
7 | endmodule
8 |
--------------------------------------------------------------------------------
/erc20/zeppelin/Makefile:
--------------------------------------------------------------------------------
1 | KEVM_VERSION_FILE:=../.build/.kevm.rev
2 |
3 | # Required to have different lemmas dir from non-#buf ERC20 specs.
4 | SPEC_GROUP:=erc20/buf/zeppelin
5 |
6 | BASEDIR_LEMMAS=$(RESOURCES)/lemmas-buf.md
7 | LOCAL_LEMMAS:=../verification.k \
8 | ../../resources/abstract-semantics-segmented-gas.k \
9 | ../../resources/evm-symbolic.k \
10 | ../evm-data-map-symbolic.k
11 | TMPLS:=../module-tmpl.k ../spec-tmpl.k
12 |
13 | KPROVE_OPTS=--smt-prelude $(RESOURCES)/evm.smt2
14 |
15 | SPEC_NAMES:=totalSupply \
16 | balanceOf \
17 | allowance \
18 | approve \
19 | transfer-success-1 \
20 | transfer-success-2 \
21 | transfer-failure-1-a \
22 | transfer-failure-1-b \
23 | transfer-failure-2 \
24 | transferFrom-success-1 \
25 | transferFrom-success-2 \
26 | transferFrom-failure-1-a \
27 | transferFrom-failure-1-b \
28 | transferFrom-failure-2
29 |
30 | include ../../resources/kprove.mak
31 |
--------------------------------------------------------------------------------
/erc20/zeppelin/StandardToken.inlined.gist:
--------------------------------------------------------------------------------
1 | https://gist.github.com/anonymous/329a61e60ff35a75fd74865df1010fcd
2 |
--------------------------------------------------------------------------------
/erc20/zeppelin/spec-diff.patch:
--------------------------------------------------------------------------------
1 | @@ -81,6 +81,7 @@
2 | andBool CALLER_ID =/=Int TO_ID
3 | andBool VALUE <=Int BAL_FROM
4 | andBool BAL_TO +Int VALUE #exception
17 | @@ -103,7 +105,8 @@
18 | +requires:
19 | andBool CALLER_ID =/=Int TO_ID
20 | andBool ( VALUE >Int BAL_FROM
21 | - orBool BAL_TO +Int VALUE >=Int (2 ^Int 256) )
22 | + orBool BAL_TO +Int VALUE >=Int (2 ^Int 256)
23 | + orBool TO_ID ==Int 0 )
24 |
25 | [transfer-failure-2]
26 | storage:
27 | @@ -111,7 +114,8 @@
28 | _:Map
29 | +requires:
30 | andBool CALLER_ID ==Int TO_ID
31 | - andBool VALUE >Int BAL_FROM
32 | + andBool ( VALUE >Int BAL_FROM
33 | + orBool TO_ID ==Int 0 )
34 |
35 | [transferFrom]
36 | callData: #abiCallData("transferFrom", #address(FROM_ID), #address(TO_ID), #uint256(VALUE))
37 | @@ -141,6 +145,7 @@
38 | andBool VALUE <=Int BAL_FROM
39 | andBool BAL_TO +Int VALUE #exception
53 | @@ -167,7 +173,8 @@
54 | andBool FROM_ID =/=Int TO_ID
55 | andBool ( VALUE >Int BAL_FROM
56 | orBool BAL_TO +Int VALUE >=Int (2 ^Int 256)
57 | - orBool VALUE >Int ALLOW )
58 | + orBool VALUE >Int ALLOW
59 | + orBool TO_ID ==Int 0 )
60 |
61 | [transferFrom-failure-2]
62 | storage:
63 | @@ -177,12 +184,13 @@
64 | +requires:
65 | andBool FROM_ID ==Int TO_ID
66 | andBool ( VALUE >Int BAL_FROM
67 | - orBool VALUE >Int ALLOW )
68 | + orBool VALUE >Int ALLOW
69 | + orBool TO_ID ==Int 0 )
70 |
--------------------------------------------------------------------------------
/gnosis/.build/.kevm.rev:
--------------------------------------------------------------------------------
1 | 27ab1d7e6114e13bc31294d99cafd5d6d0ce7131
2 |
--------------------------------------------------------------------------------
/gnosis/GnosisSafe_RuntimeVerification.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runtimeverification/verified-smart-contracts/e61ef57de99d07d7182436490f152a14621c5a82/gnosis/GnosisSafe_RuntimeVerification.pdf
--------------------------------------------------------------------------------
/gnosis/GnosisSafe_RuntimeVerification_Audit.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runtimeverification/verified-smart-contracts/e61ef57de99d07d7182436490f152a14621c5a82/gnosis/GnosisSafe_RuntimeVerification_Audit.pdf
--------------------------------------------------------------------------------
/gnosis/abstract-semantics-segmented-gas.k:
--------------------------------------------------------------------------------
1 | requires "evm-symbolic.k"
2 | requires "not-KLabel.k"
3 |
4 | //Older version that uses #notKLabel
5 | module ABSTRACT-SEMANTICS-SEGMENTED-GAS
6 | imports EVM
7 | imports EVM-SYMBOLIC
8 | imports NOT-KLABEL
9 |
10 | // to avoid unnecessary case analyses
11 | rule LT W0 W1 => bool2Word(W0 #push ... [trusted]
12 | rule GT W0 W1 => bool2Word(W0 >Int W1) ~> #push ... [trusted]
13 | rule EQ W0 W1 => bool2Word(W0 ==Int W1) ~> #push ... [trusted]
14 | rule ISZERO W => bool2Word(W ==Int 0 ) ~> #push ... [trusted]
15 |
16 | // ########################
17 | // Segmented gas representatioon - #gas construct
18 | // ########################
19 |
20 | // accumulate the gas cost and never run out of gas
21 | rule G ~> #deductGas => . ...
22 | #gas(INITGAS, NONMEM, MEM) => #gas(INITGAS, NONMEM +Int G, MEM)
23 | _ => #gas(INITGAS, NONMEM, MEM)
24 | requires #notKLabel(G, "#symCmem")
25 | [trusted, matching(#gas)]
26 |
27 | rule #symCmem(MEM') ~> #deductGas => . ...
28 | #gas(INITGAS, NONMEM, MEM) => #gas(INITGAS, NONMEM, MEM +Int MEM')
29 | _ => #gas(INITGAS, NONMEM, MEM)
30 | [trusted, matching(#symCmem,#gas)]
31 |
32 | //If G is not explicitly typed, it will be typed as G:K. This leads to intermittent SPEC ERROR below,
33 | // in multi-threaded environment, on appliation of this rule.
34 | // `java.lang.AssertionError: disjunctions are not supported by SMT translation`
35 | // Issue cause: contains 2 terms `#deductGas`, so for G:K, the rule can match in 2 ways. Observed with in hkg-erc20.
36 | rule G:KItem ~> #deductGas ...
37 | INITGAS => #gas(INITGAS, 0, 0)
38 | requires #notKLabel(INITGAS, "#gas")
39 | [trusted]
40 |
41 | rule MU':Int ~> #deductMemory => #symCmem(Cmem(SCHED, MU') -Int Cmem(SCHED, MU)) ~> #deductGas ...
42 | MU => MU' SCHED
43 | [trusted]
44 | endmodule
45 |
--------------------------------------------------------------------------------
/gnosis/bmc/Makefile:
--------------------------------------------------------------------------------
1 | KEVM_VERSION_FILE:=../.build/.kevm.rev
2 |
3 | LOCAL_LEMMAS:=../abstract-semantics.k ../verification.k ../abstract-semantics-segmented-gas.k ../../resources/not-KLabel.k
4 | TMPLS:=../module-tmpl.k ../spec-tmpl.k
5 |
6 | KPROVE_OPTS:=--smt-prelude $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../evm.smt2)
7 |
8 | SPEC_NAMES:=encodeTransactionData \
9 | signatureSplit \
10 | checkSignatures-thres-too-large \
11 | checkSignatures-thres-1-sig-v2-ec0 \
12 | checkSignatures-thres-1-sig-v2-not-ec0-success \
13 | checkSignatures-thres-1-sig-v2-not-ec0-notOwner \
14 | checkSignatures-thres-2-sig-v2-ec0 \
15 | checkSignatures-thres-2-sig-v2-o0-eq-o1
16 |
17 | # FIXME:
18 | # checkSignatures-thres-1-sig-v0
19 | # checkSignatures-thres-2-sig-v2-o0-neq-o1-success
20 | # checkSignatures-thres-2-sig-v2-o0-neq-o1-failure
21 |
22 | include ../../resources/kprove.mak
23 |
--------------------------------------------------------------------------------
/gnosis/bmc/generated-external-contract/ExternalContract.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.0;
2 |
3 | contract ExternalContract {
4 |
5 | function isValidSignature(
6 | bytes calldata _data,
7 | bytes calldata _signature)
8 | external
9 | returns (bool isValid)
10 | {
11 | isValid = false;
12 | }
13 | }
--------------------------------------------------------------------------------
/gnosis/bmc/generated-external-contract/gnosis-testing-ExternalContract.hex:
--------------------------------------------------------------------------------
1 |
2 | ======= ExternalContract.sol:ExternalContract =======
3 | Binary of the runtime part:
4 | 608060405234801561001057600080fd5b5060043610610048576000357c01000000000000000000000000000000000000000000000000000000009004806320c13b0b1461004d575b600080fd5b6101196004803603604081101561006357600080fd5b810190808035906020019064010000000081111561008057600080fd5b82018360208201111561009257600080fd5b803590602001918460018302840111640100000000831117156100b457600080fd5b9091929391929390803590602001906401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b9091929391929390505050610133565b604051808215151515815260200191505060405180910390f35b600080905094935050505056fea165627a7a72305820e0f7eff099fa7c3378fadb78e36eb0155b2a913a00f5eefceec8242c88e84ca10029
--------------------------------------------------------------------------------
/gnosis/evm.smt2:
--------------------------------------------------------------------------------
1 | ; (set-option :auto-config false)
2 | ; (set-option :smt.mbqi false)
3 | ; (set-option :smt.array.extensional false)
4 |
5 | ; int extra
6 | (define-fun int_max ((x Int) (y Int)) Int (ite (< x y) y x))
7 | (define-fun int_min ((x Int) (y Int)) Int (ite (< x y) x y))
8 | (define-fun int_abs ((x Int)) Int (ite (< x 0) (- 0 x) x))
9 |
10 | ; bool to int
11 | (define-fun smt_bool2int ((b Bool)) Int (ite b 1 0))
12 |
13 | ; IMap
14 | (define-sort IMap () (Array Int Int))
15 | (define-fun emptyIMap () IMap ((as const IMap) 0))
16 |
17 | ; ceil32
18 | (define-fun ceil32 ((x Int)) Int ( * ( div ( + x 31 ) 32 ) 32 ) )
19 |
--------------------------------------------------------------------------------
/gnosis/generated/gnosis-Proxy-0.1.0.hex:
--------------------------------------------------------------------------------
1 |
2 | ======= contracts/proxies/Proxy.sol:Proxy =======
3 | Binary of the runtime part:
4 | 60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690509056fea165627a7a723058201cddd95839fb6a2721e9db6df2726cacc48f77a2b18ba97008f236afad1ada7f0029
5 |
--------------------------------------------------------------------------------
/gnosis/generated/solidity compilation instructions.txt:
--------------------------------------------------------------------------------
1 | Solidity version: 0.5.1-develop.2018.11.29+commit.f6d01323.Linux.g++
2 | Gnosis version: https://github.com/denis-bogdanas/safe-contracts
3 | branch `rv`
4 | At the moment it is v0.1.0 with some functions marked public.
5 |
6 | Instructions to produce hex files:
7 |
8 | $ cd
9 | $ solc --bin-runtime contracts/proxies/Proxy.sol > gnosis-Proxy-0.1.0.hex
10 | $ solc --bin-runtime contracts/GnosisSafe.sol > gnosis-GnosisSafe-0.1.0.hex
11 |
12 | When compiling Solidity code which contains multiple contracts and libraries, the output bytecode will be split in multiple strings, one for each contract/library.
13 | If one of the contracts inherits the others, then its bytecode will contain the bytecode of the inherited contracts and libraries as well.
14 |
15 | Resulting files are bigger than .hex files in this repo. They contain the bytecode for multiple solidity classes.
16 | Hex files on this repo were cleared up. They only contain the fragment that was used in gnosis-spec.ini
17 |
18 | To generate .evm files:
19 | Use --asm option instead of --bin-runtime
20 |
--------------------------------------------------------------------------------
/gnosis/module-tmpl.k:
--------------------------------------------------------------------------------
1 | requires "abstract-semantics.k"
2 | requires "verification.k"
3 |
4 | module {MODULE}-SPEC
5 | imports ABSTRACT-SEMANTICS
6 | imports VERIFICATION
7 |
8 | {RULES}
9 |
10 | endmodule
11 |
--------------------------------------------------------------------------------
/gnosis/old/old-issues.md:
--------------------------------------------------------------------------------
1 | ## malicious library
2 | Since this scenario requires correct set of signatures,
3 | the risk is reduced if the library code is verified to be safe.
4 | ```solidity
5 | contract C {
6 | function foo() {
7 | owners[SENTINEL_OWNERS] = SENTINEL_OWNERS;
8 | }
9 | function bar() {
10 | call(to=proxy, data=removeOwner(..));
11 | }
12 | }
13 | ```
14 | Contract C deployed at address `a`.
15 | ### 1. executor calls `execTransactionAndPaySubmitter(to = a, data = C.foo, operation = DelegateCall, correct signatures)`
16 | 1. fallback function `delegatecall`s `execTransactionAndPaySubmitter`.
17 | * `this`: Proxy
18 | * `msg.sender`: executor
19 | 2. `execTransactionAndPaySubmitter` calls `execute` and then `executeDelegateCall` internally.
20 | * `this`: Proxy
21 | * `msg.sender`: executor
22 | 3. `executeDelegateCall` `delegatecall`s `C.foo` at address `a`
23 | * `this`: Proxy
24 | * `msg.sender`: executor
25 | 4. storage of the Proxy is modified.
26 |
27 | ### 2.executor calls `execTransactionAndPaySubmitter(data = C.foo,...)`
28 | 1. ~3. same as above.
29 | 4. `C.bar` `call`s `removeOwner` to proxy
30 | * `this`: proxy
31 | * `msg.sender`: proxy
32 | * ==> `authorized`
33 |
--------------------------------------------------------------------------------
/gnosis/test/ApiTest.sol:
--------------------------------------------------------------------------------
1 | pragma solidity 0.5.0;
2 |
3 |
4 | /// @title Enum - Collection of enums
5 | /// @author Richard Meissner -
6 | contract ApiTest {
7 | enum Operation {
8 | Call,
9 | DelegateCall,
10 | Create
11 | }
12 |
13 | bytes32 public constant SAFE_TX_TYPEHASH = 0x14d461bc7412367e924637b363c7bf29b8f47e2f84869f4426e5633d8af47b20;
14 | bytes32 public domainSeparator;
15 |
16 | //same set of arguments as encodeTransactionData
17 | function testAbiEncodeAndKeccak(
18 | address to,
19 | uint256 value,
20 | bytes memory data,
21 | Operation operation,
22 | uint256 safeTxGas,
23 | uint256 dataGas,
24 | uint256 gasPrice,
25 | address gasToken,
26 | address refundReceiver,
27 | uint256 _nonce
28 | )
29 | public
30 | pure
31 | returns (bytes memory)
32 | {
33 | return abi.encode(SAFE_TX_TYPEHASH, to, value, keccak256(data), operation, safeTxGas, dataGas, gasPrice, gasToken, refundReceiver, _nonce);
34 | }
35 |
36 | function testAbiEncode(
37 | address to,
38 | uint256 value,
39 | bytes32 keccakOut,
40 | Operation operation,
41 | uint256 safeTxGas,
42 | uint256 dataGas,
43 | uint256 gasPrice,
44 | address gasToken,
45 | address refundReceiver,
46 | uint256 _nonce
47 | )
48 | public
49 | pure
50 | returns (bytes memory)
51 | {
52 | return abi.encode(SAFE_TX_TYPEHASH, to, value, keccakOut, operation, safeTxGas, dataGas, gasPrice, gasToken, refundReceiver, _nonce);
53 | }
54 |
55 | function testKeccak(bytes memory data)
56 | public
57 | pure
58 | returns (bytes32)
59 | {
60 | return keccak256(data);
61 | }
62 |
63 | function testAbiEncodePacked(bytes32 safeTxHash)
64 | public
65 | view
66 | returns (bytes memory)
67 | {
68 | return abi.encodePacked(byte(0x19), byte(0x01), domainSeparator, safeTxHash);
69 | }
70 |
71 | function testEcrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
72 | public
73 | pure
74 | returns (address)
75 | {
76 | return ecrecover(hash, v, r, s);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/gnosis/test/Makefile:
--------------------------------------------------------------------------------
1 | KEVM_VERSION_FILE:=../.build/.kevm.rev
2 |
3 | LOCAL_LEMMAS:=../verification.k \
4 | ../abstract-semantics.k \
5 | ../abstract-semantics-segmented-gas.k \
6 | ../../resources/evm-symbolic.k \
7 | ../../resources/evm-data-map-symbolic.k \
8 | ../../resources/ecrec-symbolic.k \
9 | ../../resources/not-KLabel.k
10 | TMPLS:=../module-tmpl.k ../spec-tmpl.k
11 |
12 | KPROVE_OPTS:=--smt-prelude $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../evm.smt2)
13 |
14 | SPEC_NAMES:=testKeccak-1 \
15 | testKeccak-2 \
16 | testAbiEncode \
17 | testAbiEncode-AndKeccak-1 \
18 | testAbiEncode-AndKeccak-2 \
19 | testAbiEncodePacked \
20 | testEcrecover-non-empty \
21 | testEcrecover-empty
22 |
23 | include ../../resources/kprove.mak
24 |
--------------------------------------------------------------------------------
/k-test/KTest.sol:
--------------------------------------------------------------------------------
1 | pragma solidity 0.4.24;
2 |
3 |
4 | /// Contracts for testing kprove reasoning engine.
5 | contract KTest {
6 |
7 | function ecrecImplication(address a1, bytes32 p1, uint8 a2v, bytes32 p3, bytes32 p4, address a3)
8 | public
9 | pure
10 | returns (bool)
11 | {
12 | address a2 = ecrecover(p1, a2v, p3, p4);
13 | return a1 < a2 && a2 < a3;
14 | }
15 |
16 | function ecrecConstraint(address a1, bytes32 p1, uint8 a2v, bytes32 p3, bytes32 p4, address a3)
17 | public
18 | pure
19 | returns (bool)
20 | {
21 | address a2 = ecrecover(p1, a2v, p3, p4);
22 | if (a1 < a2 && a2 < a3) {
23 | return true;
24 | }
25 | return false;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/k-test/Makefile:
--------------------------------------------------------------------------------
1 | #BUILD_DIR:=../erc20/.build
2 |
3 | # verification.k is required to import evm-symbolic.k
4 | LOCAL_LEMMAS:=verification.k \
5 | abstract-semantics.k \
6 | ../resources/abstract-semantics-segmented-gas.k \
7 | ../resources/evm-symbolic.k \
8 | ../resources/evm-data-map-concrete.k \
9 | ../resources/ecrec-symbolic.k
10 |
11 | # Just to have the simplest initial config
12 | TMPLS:=../gnosis/module-tmpl.k spec-tmpl.k
13 |
14 | MAKEFILE_PATH := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
15 | KPROVE_OPTS:=--smt-prelude $(MAKEFILE_PATH)/smt-prelude.smt2
16 |
17 | SPEC_NAMES:=ecrecT-false-implication \
18 | ecrecT-false-constraint \
19 | rhsOnlyVar \
20 | test-getKLabelString
21 |
22 | include ../resources/kprove.mak
23 |
--------------------------------------------------------------------------------
/k-test/abstract-semantics.k:
--------------------------------------------------------------------------------
1 | requires "abstract-semantics-segmented-gas.k"
2 | requires "ecrec-symbolic.k"
3 |
4 | module ABSTRACT-SEMANTICS
5 | imports ABSTRACT-SEMANTICS-SEGMENTED-GAS
6 | imports ECREC-SYMBOLIC
7 | endmodule
8 |
--------------------------------------------------------------------------------
/k-test/smt-prelude.smt2:
--------------------------------------------------------------------------------
1 | (set-option :auto-config false)
2 | (set-option :smt.mbqi true)
3 |
--------------------------------------------------------------------------------
/k-test/spec-tmpl.k:
--------------------------------------------------------------------------------
1 | // {RULENAME}
2 | rule
3 | {K}
4 | 1
5 | NORMAL
6 | {SCHEDULE}
7 |
8 |
9 |
10 |
11 | {STATUSCODE}
12 | _
13 | _
14 | _ => _
15 |
16 |
17 | #parseByteStack({CODE})
18 | #computeValidJumpDests(#parseByteStack({CODE}))
19 |
20 | ACCT_ID // contract owner
21 | CALLER_ID // who called this contract; in the begining, origin // msg.sender
22 |
23 | {CALLDATA}
24 |
25 | 0
26 | .WordStack => _
27 | .Map => _
28 | 0 => _
29 | {GAS}
30 | 0 => _
31 | _ => _
32 |
33 | false // NOTE: non-static call
34 | {CALLDEPTH}
35 |
36 |
37 |
38 | _
39 | {LOG}
40 | {REFUND} // TODO: more detail
41 |
42 |
43 | _
44 | ORIGIN_ID // who fires tx
45 | _
46 |
47 | _
48 | _
49 | _
50 | _
51 | _
52 | _
53 | _
54 | _
55 | _
56 | _
57 | _
58 | _
59 | _
60 | _
61 | _
62 |
63 | _
64 |
65 |
66 |
67 |
68 | 0
69 | SetItem(ACCT_ID) SetItem(1) _:Set
70 |
71 |
72 |
73 | ACCT_ID
74 | {BALANCE}
75 | #parseByteStack({CODE})
76 | {STORAGE}
77 | {ORIGSTORAGE}
78 | _
79 |
80 |
81 | // precompiled account for ECCREC
82 | 1
83 | 0
84 | .WordStack
85 | .Map
86 | .Map
87 | 0
88 |
89 | // ... // TODO: fix
90 |
91 |
92 | _
93 | _
94 | _
95 |
96 |
97 | requires 0 <=Int ACCT_ID andBool ACCT_ID #sizeWordStack(WS, 0) +Int N SIZELIMIT SIZELIMIT #sizeWordStack(WS, 0) +Int N <=Int SIZE requires N =/=Int 0
17 |
18 | //Rules for #padToWidth with non-regular symbolic arguments.
19 | rule #padToWidth(32, #asByteStack(V)) => #asByteStackInWidth(V, 32)
20 | requires 0 <=Int V andBool V WS
23 | requires #noOverflow(WS) andBool N ==Int #sizeWordStack(WS)
24 |
25 | rule X modInt Y => X
26 | requires 0 <=Int X andBool X chop ( W0 )
29 | requires #rangeUInt(256, W0) andBool #rangeUInt(256, W1)
30 |
31 | // The number below is equal to: (2^256 - 1) - (2^160 - 1), which in hex would be graphically
32 | // f...f (24 times) ++ 0...0 (40 times). An Ethereum address has at most 40 hex digits.
33 | // It follow when we bit-wise AND the two numbers, the result will always be 0.
34 |
35 | rule 115792089237316195423570985007226406215939081747436879206741300988257197096960 &Int X:Int => 0
36 | requires #rangeAddress(X)
37 | endmodule
38 |
--------------------------------------------------------------------------------
/resources/Makefile:
--------------------------------------------------------------------------------
1 | SPEC_GROUP:=examples
2 | # mock non-empty value
3 | SPEC_INI:=.mock.ini
4 |
5 | KPROVE_OPTS:=--smt-prelude $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/evm.smt2)
6 |
7 | SPEC_NAMES:=sum-to-n
8 |
9 | LOCAL_LEMMAS:=
10 | TMPLS:=
11 |
12 | include kprove.mak
13 |
14 | # non-standard spec generation
15 | $(SPECS_DIR)/$(SPEC_GROUP)/sum-to-n-spec.k: $(RESOURCES)/sum-to-n.md $(TANGLER) $(LEMMAS)
16 | pandoc --from markdown --to "$(TANGLER)" --metadata="code:.sum-to-n" $< > $@
17 |
--------------------------------------------------------------------------------
/resources/abstract-semantics-direct-gas.k:
--------------------------------------------------------------------------------
1 | requires "evm-direct-gas.k"
2 |
3 | module ABSTRACT-SEMANTICS-DIRECT-GAS
4 | imports EVM
5 | imports EVM-DIRECT-GAS
6 |
7 | // to avoid unnecessary case analyses
8 | rule LT W0 W1 => bool2Word(W0 #push ... [trusted]
9 | rule GT W0 W1 => bool2Word(W0 >Int W1) ~> #push ... [trusted]
10 | rule EQ W0 W1 => bool2Word(W0 ==Int W1) ~> #push ... [trusted]
11 | rule ISZERO W => bool2Word(W ==Int 0 ) ~> #push ... [trusted]
12 |
13 | endmodule
14 |
--------------------------------------------------------------------------------
/resources/abstract-semantics-segmented-gas.k:
--------------------------------------------------------------------------------
1 | requires "evm-symbolic.k"
2 |
3 | module ABSTRACT-SEMANTICS-SEGMENTED-GAS
4 | imports EVM
5 | imports EVM-SYMBOLIC
6 |
7 | // to avoid unnecessary case analyses
8 | rule LT W0 W1 => bool2Word(W0 #push ... [trusted]
9 | rule GT W0 W1 => bool2Word(W0 >Int W1) ~> #push ... [trusted]
10 | rule EQ W0 W1 => bool2Word(W0 ==Int W1) ~> #push ... [trusted]
11 | rule ISZERO W => bool2Word(W ==Int 0 ) ~> #push ... [trusted]
12 |
13 | // ########################
14 | // Segmented gas representatioon - #gas construct
15 | // ########################
16 |
17 | // accumulate the gas cost and never run out of gas
18 | rule MEM' ~> #deductMemoryGas => . ...
19 | #gas(INITGAS, NONMEM, MEM) => #gas(INITGAS, NONMEM, MEM +Int MEM')
20 | _ => #gas(INITGAS, NONMEM, MEM)
21 | [trusted, matching(#gas)]
22 |
23 | //Will run only if rule above doesn't match
24 | rule G ~> #deductGas => . ...
25 | #gas(INITGAS, NONMEM, MEM) => #gas(INITGAS, NONMEM +Int G, MEM)
26 | _ => #gas(INITGAS, NONMEM, MEM)
27 | [trusted, matching(#gas)]
28 |
29 | endmodule
30 |
--------------------------------------------------------------------------------
/resources/build-html.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | for doc in $(find . -name '*.md' \! -name 'sum-to-n.md') ; do
3 | pandoc --lua-filter=resources/relink.lua -so ${doc%.md}.html $doc
4 | done
5 | # build files that have TeX equations
6 | for doc in resources/sum-to-n.md ; do
7 | pandoc --lua-filter=resources/relink.lua --mathjax=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML -so ${doc%.md}.html $doc
8 | done
9 |
--------------------------------------------------------------------------------
/resources/debugging.md:
--------------------------------------------------------------------------------
1 | # EVM Verifier Debugging Cheatsheet
2 |
3 |
4 | ### Internal commands for running kprover
5 |
6 | ```
7 | $ cd evm-semantics
8 | $ make deps defn split-proof-tests
9 | $ export PATH=`pwd`/.build/k/k-distribution/target/release/k/bin:$PATH
10 | $ kompile --debug --backend java -I .build/defn/java -d .build/defn/java --main-module ETHEREUM-SIMULATION --syntax-module ETHEREUM-SIMULATION .build/defn/java/driver.k
11 | $ kprove tests/proofs/specs/vyper-erc20/totalSupply-spec.k -d .build/defn/java -m VERIFICATION --z3-executable
12 | ```
13 |
14 |
15 | ### IntelliJ debugger setup
16 |
17 | 1. Install Intellij (remember to install scala plugin)
18 | 1. In the `k5` dir, `mvn package`
19 | 1. Import k5 project:
20 | 1. Import Project -> Path to the pom.xml
21 | 2. Select project SDK: JDK1.8
22 | 1. Edit Configuration
23 | 1. Click Edit Configuration, click `+` and choose Application
24 | 2. Enter
25 | * Main class: `org.kframework.main.Main`
26 | * VM options: `-Xms64m -Xmx4g -Xss32m -XX:+TieredCompilation -ea`
27 | * Program arguments: `-kprove /path/to/spec.k -d .build/defn/java -m VERIFICATION ` see [kprove tutorial](https://github.com/runtimeverification/verified-smart-contracts/blob/master/resources/kprove-tutorial.md)
28 | * Working dir: `/path/to/evm-semantics`
29 | * Env Variables:
30 | * `LD_LIBRARY_PATH` : `$LD_LIBRARY_PATH:$MODULE_DIR$/../k-distribution/target/release/k/lib/native/linux64`
31 | * `PATH` : `$PATH:$MODULE_DIR$/../k-distribution/target/release/k/bin:$MODULE_DIR$/../k-distribution/target/release/k/lib/native/linux:$MODULE_DIR$/../k-distribution/target/release/k/lib/native/linux64:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`
32 | * Use classpath of module: `k-distribution`
33 |
34 | 1. Breakpoints
35 | * Start from `proveRule()` in `SymbolicRewriter.java`.
36 | * At line `if (term.implies(targetTerm)) {`.
37 | Set a breakpoint with the following condition, which will stop at the begining of the execution of each opcode.
38 | ```
39 | ((KList) ((KItem) ((KList) ((KItem) term.term()).kList()).get(0)).kList()).get(0).toString().startsWith("#KSequence(#exec[_]")
40 | ```
41 | You can also add `step >= N` to constrain the number of steps.
42 | * More recent versions of K have updated versions of the method `proveRule()`. You can move the breakpoint to one of the first lines of `for (ConstrainedTerm term : queue)`, such as `v++`, and use the same condition as above.
43 | 2. Using the debugger
44 | * The debugger should stop at each opcode. You can see the current opcode at the top of the `` cell of the current configuration. The current configuration is stored in the `term` variable.
45 |
46 | ### FAQ
47 | **Q:** The following error was thrown while I was trying to run the debugger. What should I do?
48 | ```
49 | java.lang.OutOfMemoryError: GC overhead limit exceeded
50 | ```
51 | **A:** This error was thrown most likely because the memory heap size of the VM was not big enough. In order to fix this error try to increase the heap size by editing the current configuration and replace in the `VM Options` the `-Xmx4g` with `-Xmx12g`. This will allocate 12GB for the VM memory heap.
--------------------------------------------------------------------------------
/resources/ecrec-symbolic.k:
--------------------------------------------------------------------------------
1 | requires "edsl.k"
2 | requires "evm-symbolic.k"
3 |
4 | module ECREC-SYMBOLIC [symbolic]
5 | imports K-REFLECTION
6 | imports EVM
7 | imports EDSL
8 | imports EVM-SYMBOLIC
9 |
10 | // ########################
11 | // ECRECOVER
12 | // ########################
13 |
14 | rule ECREC => #end EVMC_SUCCESS ...
15 | DATA
16 |
17 | requires notBool #isConcrete(DATA) andBool #sizeWordStack(DATA) ==Int 128 andBool notBool #ecrecEmpty(DATA)
18 | [trusted]
19 |
20 | rule ECREC => #end EVMC_SUCCESS ...
21 | DATA
22 |
23 | requires notBool #isConcrete(DATA) andBool #sizeWordStack(DATA) ==Int 128 andBool #ecrecEmpty(DATA)
24 | [trusted]
25 |
26 | endmodule
27 |
--------------------------------------------------------------------------------
/resources/edsl.md:
--------------------------------------------------------------------------------
1 | eDSL: Domain-Specific Language for EVM Specifications
2 | =====================================================
3 |
4 | The [K-framework] provides a [reachability logic theorem prover] that is parameterized by the langauge semantics.
5 | Instantiated with the [KEVM], a complete formal semantics of the Ethereum Virtual Machine (EVM),
6 | the K prover yields a correct-by-construction deductive program verifer for the EVM.
7 | The EVM verifier takes an EVM bytecode and a specification as inputs, and automatically proves that the bytecode satisfies the specification, if it is the case.
8 | The EVM specification essentially specifies the pre- and post-conditions of the EVM bytecode in the form of reachability logic claims.
9 |
10 | We present a domain-specific language (DSL) for the EVM specifications, called eDSL, to succintly specify the specifications.
11 | The eDSL consists of two parts:
12 |
13 | * [eDSL High-Level Notations](https://github.com/kframework/evm-semantics/blob/master/edsl.md)
14 | * [eDSL Specifications](edsl-spec.md)
15 | * [eDSL Specification Templates](edsl-spec.md#edsl-specification-template)
16 | * [eDSL Template Parameters](edsl-spec.md#edsl-template-parameters)
17 |
18 | [KEVM]:
19 | [K-framework]:
20 | [reachability logic theorem prover]:
21 |
--------------------------------------------------------------------------------
/resources/evm-data-map-concrete.k:
--------------------------------------------------------------------------------
1 | requires "edsl.k"
2 |
3 | module EVM-DATA-MAP-CONCRETE [symbolic]
4 | imports K-REFLECTION
5 | imports EVM-DATA
6 | imports EDSL
7 |
8 | // Same rules exist in KEVM, but are marked [concrete]. Allowing them for symbolic arguments here.
9 |
10 | rule #lookup( (KEY |-> VAL) M, KEY ) => VAL
11 | rule #lookup( M, KEY ) => 0 requires notBool KEY in_keys(M)
12 |
13 | rule #range(WM, START, WIDTH) => #range(WM, START +Int WIDTH -Int 1, WIDTH, .WordStack)
14 |
15 | rule WM[ N := W : WS ] => (WM[N <- W])[N +Int 1 := WS]
16 |
17 | //semantics of #buf
18 | rule #buf(LEN, BYTES) => #padToWidth(LEN, #asByteStack( BYTES ))
19 |
20 | endmodule
21 |
--------------------------------------------------------------------------------
/resources/evm-direct-gas.k:
--------------------------------------------------------------------------------
1 | requires "edsl.k"
2 |
3 | module EVM-DIRECT-GAS [symbolic]
4 | imports EVM
5 | imports EDSL
6 |
7 | // ########################
8 | // Direct gas representatioon as number - rules copy-pasted from KEVM but without [concrete]
9 | // ########################
10 |
11 | // Rules from evm.md that got [concrete] as part of migration to segmented gas model.
12 | // Only enabling the subset that is needed for current specs.
13 | //-----------------------------------------
14 |
15 | /*
16 | rule #memoryUsageUpdate(MU, START, WIDTH) => maxInt(MU, (START +Int WIDTH) up/Int 32) requires WIDTH >Int 0
17 |
18 | rule Cgascap(SCHED, GCAP, GAVAIL, GEXTRA)
19 | => #if GAVAIL > #then GCAP #else minInt(#allBut64th(GAVAIL -Int GEXTRA), GCAP) #fi
20 | */
21 | rule Csstore(SCHED, NEW, CURR, ORIG)
22 | => #if CURR ==Int NEW orBool ORIG =/=Int CURR #then Gsload < SCHED > #else #if ORIG ==Int 0 #then Gsstoreset < SCHED > #else Gsstorereset < SCHED > #fi #fi
23 | requires Ghasdirtysstore << SCHED >>
24 |
25 | rule Csstore(SCHED, NEW, CURR, ORIG)
26 | => #if CURR ==Int 0 andBool NEW =/=Int 0 #then Gsstoreset < SCHED > #else Gsstorereset < SCHED > #fi
27 | requires notBool Ghasdirtysstore << SCHED >>
28 |
29 | rule Rsstore(SCHED, NEW, CURR, ORIG)
30 | => #if CURR =/=Int NEW andBool ORIG ==Int CURR andBool NEW ==Int 0 #then
31 | Rsstoreclear < SCHED >
32 | #else
33 | #if CURR =/=Int NEW andBool ORIG =/=Int CURR andBool ORIG =/=Int 0 #then
34 | #if CURR ==Int 0 #then 0 -Int Rsstoreclear < SCHED > #else #if NEW ==Int 0 #then Rsstoreclear < SCHED > #else 0 #fi #fi
35 | #else
36 | 0
37 | #fi +Int
38 | #if CURR =/=Int NEW andBool ORIG ==Int NEW #then
39 | #if ORIG ==Int 0 #then Gsstoreset < SCHED > #else Gsstorereset < SCHED > #fi -Int Gsload < SCHED >
40 | #else
41 | 0
42 | #fi
43 | #fi
44 | requires Ghasdirtysstore << SCHED >>
45 |
46 | rule Rsstore(SCHED, NEW, CURR, ORIG)
47 | => #if CURR =/=Int 0 andBool NEW ==Int 0 #then Rsstoreclear < SCHED > #else 0 #fi
48 | requires notBool Ghasdirtysstore << SCHED >>
49 |
50 | /*
51 | rule Cextra(SCHED, ISEMPTY, VALUE)
52 | => Gcall < SCHED > +Int Cnew(SCHED, ISEMPTY, VALUE) +Int Cxfer(SCHED, VALUE)
53 |
54 | rule Cmem(SCHED, N) => (N *Int Gmemory < SCHED >) +Int ((N *Int N) /Int Gquadcoeff < SCHED >)
55 | */
56 |
57 | endmodule
58 |
--------------------------------------------------------------------------------
/resources/evm-symbolic.k:
--------------------------------------------------------------------------------
1 | requires "edsl.k"
2 |
3 | module EVM-SYMBOLIC [symbolic]
4 | imports EVM
5 | imports EDSL
6 |
7 | // ########################
8 | // Ecrecover
9 | // todo move to ecrec-symbolic.k when K supports it.
10 | // ########################
11 |
12 | //Symbolic wrapper over the argument of #ecrec, no implementation.
13 | syntax Int ::= #symEcrec ( WordStack ) [function]
14 |
15 | //Symbolic predicate representing whether output of #ecrec is empty. No implementation.
16 | syntax Bool ::= #ecrecEmpty( WordStack ) [function]
17 |
18 | // Range for #symEcrec
19 |
20 | //case 0 is never wrapped into #symEcrec(), corresponds to #ecrecEmpty(DATA) == true
21 | rule 0 true
22 |
23 | //that's because the result in concrete semantics is trimmed to Address range.
24 | rule #symEcrec(DATA) true
25 |
26 | // Lemmas implied by the above, but still required to match side conditions of #padToWidth rule in lemmas.md
27 | // General range conversion lemmas like below are not an option, dramatic performance decrease:
28 | // rule A < pow256 => true requires A < pow160
29 | rule 0 <=Int #symEcrec(DATA) => true
30 | rule #symEcrec(DATA) true
31 |
32 | // ########################
33 | // Symbolic Gas
34 | // ########################
35 |
36 | syntax Int ::= #gas ( Int , Int , Int ) [function] // startGas, nonMemory, memory
37 | // -----------------------------------------------------------------------------------
38 | /*
39 | startGas - gas available at the beginning of execution
40 | nonMemory - gas consumed on non-memory operations
41 | memory - gas consumed on memory operation
42 |
43 | Concrete semantics:
44 |
45 | rule #gas ( StartGas , NonMemory , Memory ) => StartGas -Int NonMemory -Int Memory
46 | */
47 |
48 | syntax Int ::= #symCmem ( Int ) [function]
49 | // -------------------------------------------
50 |
51 | // callSuccess? caputures various cases where a call may fail including out of gas, insufficient balance and etc.
52 | // TODO: include the calldata as the argument.
53 | syntax Int ::= #callGas ( Schedule , Int , Int , Int , Bool ) [function] // schedule, gasCap, accountTo, value, callSuccess?
54 | // ------------------------------------------------------------------------------------------------------------------------------
55 |
56 |
57 | // ########################
58 | // Symbolic Call
59 | // ########################
60 |
61 | // PC helps to differentiate different calls to the same account.
62 | // TODO: include the calldata as the argument.
63 | syntax Bool ::= #callSuccess ( Int , Int ) [function] // pc, accountTo
64 | | #callFailure ( Int , Int ) [function] // pc, accountTo
65 | // ------------------------------------------------------------------------
66 |
67 | syntax Int ::= #callResult ( Int , Int ) [function] // pc, accountTo
68 | // ----------------------------------------------------------------------
69 |
70 |
71 | syntax Int ::= #extCodeSize ( Int ) [function]
72 | // -----------------------------------------------
73 |
74 | // ERC20 transfer(address,uint256)
75 | // pc, to addr
76 | syntax Bool ::= #tokenTransferCallSuccess ( Int , Int ) [function]
77 | | #tokenTransferCallFailure ( Int , Int ) [function]
78 | // ------------------------------------------------------------------
79 |
80 | // 3rd argument: NOW variable hack to force to generate Z3 query
81 | syntax Int ::= #tokenTransferCallReturnSize ( Int , Int , Int ) [function]
82 | | #tokenTransferCallReturnValue ( Int , Int , Int ) [function]
83 | // ---------------------------------------------------------------------------
84 |
85 | endmodule
86 |
--------------------------------------------------------------------------------
/resources/evm.smt2:
--------------------------------------------------------------------------------
1 | ; (set-option :auto-config false)
2 | ; (set-option :smt.mbqi false)
3 | ; (set-option :smt.array.extensional false)
4 |
5 | ; int extra
6 | (define-fun int_max ((x Int) (y Int)) Int (ite (< x y) y x))
7 | (define-fun int_min ((x Int) (y Int)) Int (ite (< x y) x y))
8 | (define-fun int_abs ((x Int)) Int (ite (< x 0) (- 0 x) x))
9 |
10 | ; bool to int
11 | (define-fun smt_bool2int ((b Bool)) Int (ite b 1 0))
12 |
13 | ; ceil32
14 | (define-fun ceil32 ((x Int)) Int ( * ( div ( + x 31 ) 32 ) 32 ) )
15 |
--------------------------------------------------------------------------------
/resources/gen-spec.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import sys
4 | import re
5 | import configparser
6 |
7 | def app(specs, spec):
8 | if not specs:
9 | return spec
10 | else:
11 | delimiter = "\n\n"
12 | return delimiter.join((specs, spec))
13 |
14 | # TODO: for Python 3.5 or higher: z = {**x, **y}
15 | def merge_two_dicts(x, y):
16 | z = dict(x)
17 | z.update(y)
18 | return z
19 |
20 | def subst(text, key, val):
21 | return text.replace('{' + key.upper() + '}', val)
22 |
23 | def safe_get(config, section):
24 | if section in config:
25 | return config[section]
26 | else:
27 | return {}
28 |
29 | def inherit_get(config, section):
30 | if not section:
31 | return safe_get(config, 'root')
32 | else:
33 | parent = inherit_get(config, '-'.join(section.split('-')[:-1]))
34 | current = safe_get(config, section)
35 | merged = merge_two_dicts(parent, current) # TODO: for Python 3.5 or higher: {**parent, **current}
36 | for key in list(merged.keys()):
37 | if key.startswith('+'):
38 | merged[key[1:]] += merged[key]
39 | del merged[key]
40 | return merged
41 |
42 | def gen(spec_template, rule_template, spec_ini, spec_name, rule_name_list):
43 | spec_config = configparser.ConfigParser(comment_prefixes=(';'))
44 | spec_config.read(spec_ini)
45 | if 'pgm' not in spec_config:
46 | print('''Must specify a "pgm" section in the .ini file.''')
47 | sys.exit(1)
48 | pgm_config = spec_config['pgm']
49 | rule_spec_list = []
50 | for name in rule_name_list:
51 | rule_spec = rule_template
52 | for config in [ inherit_get(spec_config, name)
53 | , pgm_config
54 | ]:
55 | rule_spec = subst_all(rule_spec, config)
56 | # for key in config:
57 | # rule_spec = subst(rule_spec, key, config[key].strip())
58 | rule_spec = subst(rule_spec, "rulename", name)
59 | rule_spec_list.append(rule_spec)
60 | delimeter = "\n"
61 | rules = delimeter.join(rule_spec_list)
62 | genspec = subst(spec_template, 'module', spec_name.upper())
63 | genspec = subst(genspec, 'rules', rules)
64 | print(genspec)
65 | # genspec = template
66 | # for config in [ inherit_get(spec_config, name)
67 | # , {'module': name.upper()}
68 | # , pgm_config['DEFAULT']
69 | # ]:
70 | # for key in config:
71 | # genspec = subst(genspec, key, config[key].strip())
72 | # print(genspec)
73 |
74 | def subst_all(init_rule_spec, config):
75 | rule_spec = init_rule_spec
76 | for key in config:
77 | rule_spec = subst(rule_spec, key, config[key].strip())
78 | if rule_spec != init_rule_spec:
79 | return subst_all(rule_spec, config)
80 | else:
81 | return rule_spec
82 |
83 | if __name__ == '__main__':
84 | if len(sys.argv) < 6:
85 | print("usage: ")
86 | sys.exit(1)
87 | spec_template = open(sys.argv[1], "r").read()
88 | rule_template = open(sys.argv[2], "r").read()
89 | gen(spec_template, rule_template, sys.argv[3], sys.argv[4], sys.argv[5:])
90 |
--------------------------------------------------------------------------------
/resources/instructions.md:
--------------------------------------------------------------------------------
1 | # General Instruction for Reproducing Mechanized Proofs
2 |
3 | The formal specifications presented in this repository are written in [eDSL], a domain-specific language for EVM specifications, which must be known in order to thoroughly understand the specifications.
4 | Refer to [resources] for background on our technology.
5 | Each of the specifications provides the [eDSL] specification template parameters.
6 | The full [K] [reachability logic] specifications are automatically derived by instantiating a specification template with these template parameters.
7 |
8 | #### Generating Full Reachability Logic Specifications
9 |
10 | Run the following command in the root directory of this repository, and it will generate the full [reachability logic] specifications, under the directory `specs`, for the smart contract(s) in the `` directory:
11 |
12 | ```
13 | $ make -C split-proof-tests
14 | ```
15 |
16 | #### Reproducing Proofs
17 |
18 | To prove that the specifications are satisfied by (the compiled EVM bytecode of) the target contracts, run the EVM verifier as follows:
19 |
20 | ```
21 | $ make -C test
22 | ```
23 |
24 | #### Installing the EVM Verifier
25 |
26 | The EVM verifier is part of the [KEVM] project. The following commands will successfully install it, provided that all of the dependencies are installed.
27 |
28 | ```
29 | $ make -C deps
30 | ```
31 |
32 | For detailed instructions on installing and running the EVM verifier, see [KEVM]'s [Installing/Building](https://github.com/kframework/evm-semantics/blob/master/README.md#installingbuilding) and [Example Usage](https://github.com/kframework/evm-semantics/blob/master/README.md#example-usage) pages.
33 |
34 | ## [Resources](/README.md#resources)
35 |
36 | ## [Disclaimer](/README.md#disclaimer)
37 |
38 | [K]:
39 | [eDSL]:
40 | [KEVM]:
41 | [reachability logic]:
42 | [resources]:
43 |
--------------------------------------------------------------------------------
/resources/kprove-group.mak:
--------------------------------------------------------------------------------
1 | SUBCLEAN=$(addsuffix .clean,$(SUBDIRS))
2 | SUBCLEANDEPS=$(addsuffix .clean-deps,$(SUBDIRS))
3 | SUBDEPS=$(addsuffix .deps,$(SUBDIRS))
4 | SUBPROOF=$(addsuffix .proof,$(SUBDIRS))
5 | SUBTEST=$(addsuffix .test,$(SUBDIRS))
6 |
7 | .PHONY: all clean clean-deps deps split-proof-tests test $(SUBDIRS) $(SUBCLEAN) $(SUBCLEANDEPS) $(SUBDEPS) $(SUBPROOF) $(SUBTEST)
8 |
9 | all: $(SUBDIRS)
10 | clean: $(SUBCLEAN)
11 | clean-deps: $(SUBCLEANDEPS)
12 | deps: $(SUBDEPS)
13 | split-proof-tests: $(SUBPROOF)
14 | test: $(SUBTEST)
15 |
16 | $(SUBDIRS):
17 | $(MAKE) -C $@
18 |
19 | $(SUBCLEAN): %.clean:
20 | $(MAKE) -C $* clean
21 |
22 | $(SUBCLEANDEPS): %.clean-deps:
23 | $(MAKE) -C $* clean-deps
24 |
25 | $(SUBDEPS): %.deps:
26 | $(MAKE) -C $* deps
27 |
28 | $(SUBPROOF): %.proof:
29 | $(MAKE) -C $* split-proof-tests
30 |
31 | $(SUBTEST): %.test:
32 | $(MAKE) -C $* test
33 |
34 | #
35 | # For Jenkins Build
36 | #
37 |
38 | NPROCS?=1
39 |
40 | .PHONY: jenkins
41 |
42 | # K bug workaround: Because KEVM parse cache is shared between projects, rules with equal body but different attributes will collide.
43 | # That's why we need clean-kevm-cache below.
44 | jenkins:
45 | set -e; \
46 | for i in $(SUBDIRS); do \
47 | $(MAKE) -C $$i clean-kevm-cache all; \
48 | $(MAKE) -C $$i test -j$(NPROCS); \
49 | done
50 |
--------------------------------------------------------------------------------
/resources/not-KLabel.k:
--------------------------------------------------------------------------------
1 | module NOT-KLABEL [symbolic]
2 | imports K-REFLECTION
3 |
4 | //Returns true if the KLabel of `T` is not `L`, or if `T` is a variable.
5 | syntax Bool ::= #notKLabel ( K , String ) [function]
6 | rule #notKLabel(T, L) => #getKLabelString(T) =/=String L orBool #isVariable(T)
7 |
8 | endmodule
9 |
--------------------------------------------------------------------------------
/resources/pdf-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runtimeverification/verified-smart-contracts/e61ef57de99d07d7182436490f152a14621c5a82/resources/pdf-icon.png
--------------------------------------------------------------------------------
/resources/relink.lua:
--------------------------------------------------------------------------------
1 | function fix_local_links(link)
2 | if not string.find("://",link.target) then
3 | link.target = string.gsub(link.target,"%.md$",".html")
4 | link.target = string.gsub(link.target,"%.md#(.*)$",".html#%1")
5 | end
6 | return link
7 | end
8 |
9 | local first_header = true
10 | local my_title = nil
11 |
12 | function find_title(header)
13 | if first_header == true then
14 | if header.level == 1 then
15 | my_title = header.content
16 | end
17 | first_header = false
18 | end
19 | return header
20 | end
21 |
22 | function do_metadata(m)
23 | if m['title'] == nil and m['pagetitle'] == nil then
24 | m['pagetitle'] = my_title
25 | end
26 | return m
27 | end
28 |
29 | return {{Link = fix_local_links, Header = find_title},
30 | {Meta = do_metadata}}
31 |
--------------------------------------------------------------------------------
/run-proofs.sh:
--------------------------------------------------------------------------------
1 | # Usage in evm-semantics/tests/proofs:
2 | # E.g. ./run-proofs gnosis-erc20 gnosis-erc20-1
3 | # $1: folder in ./specs
4 | # $2: output folder
5 | # $3...: files to be verified
6 | # OR
7 | # $3: all/empty = all
8 |
9 | options=( \
10 | # '--log-basic' \
11 | # '--log-cells "(k),(gas),(statusCode)"' \
12 | # '--log --log-cells "(k),(pc),(wordStack)"' \
13 | # '--log-cells "(k),(output),(localMem),(pc),(gas),(wordStack),(accounts)"' \
14 | )
15 |
16 | output_top_dir="output"
17 | output_dir="$2"
18 |
19 | mkdir -p "$output_top_dir/$output_dir"
20 | touch "$output_top_dir/$output_dir/log"
21 |
22 | # Assuming an (exported) KEVM environmental variable.
23 | # If you don't have one, uncomment this and set it here:
24 |
25 | # KEVM="/Users"
26 |
27 | run_proof() {
28 | touch "$output_top_dir/$output_dir/$file_name"
29 |
30 | cmd_part1="kprove "$file_path" -d "${KEVM}/.build/defn/java" -m VERIFICATION"
31 | cmd_part2="&> "$output_top_dir/$output_dir/$file_name""
32 | cmd="$cmd_part1 ${options[@]} $cmd_part2"
33 |
34 | log="$(date): Verifying $file_name with ${options[@]}"
35 | echo "$log" >> "$output_top_dir/$output_dir/log"
36 | echo "$log"
37 |
38 | eval "$cmd"
39 | }
40 |
41 | if [ "$3" == "all" ] || [ -z "$3" ]
42 | then
43 | for file in ./specs/"$1"/*
44 | do
45 | file_name="${file##*/}"
46 | file_end="${file:(-6)}"
47 | if [ "$file_end" == "spec.k" ]
48 | then
49 | file_path="${file:2}"
50 | run_proof "$@"
51 | else
52 | echo "skipping $file_name because it is not a spec file"
53 | fi
54 | done
55 | else
56 | i=3
57 | if [ "$3" == "-d" ]
58 | then
59 | echo "deleting $output_top_dir/$output_dir"
60 | rm -rf "$output_top_dir/$output_dir/*"
61 | i=4
62 | fi
63 | for ((j=i; j <= $#; j++ )); do
64 | file_name="${!j}"
65 | file_path="specs/$1/$file_name"
66 | if [ -e "$file_path" ]
67 | then
68 | run_proof "$@"
69 | else
70 | echo "skipping $file_name because it does not exist - maybe a typo?"
71 | fi
72 | done
73 | fi
--------------------------------------------------------------------------------
/script/dkprove.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | kprove --debugg \
4 | --output-omit "" --output-omit "" --output-omit "" \
5 | --output-omit "" --output-omit "" --output-omit "" --output-omit "" \
6 | --output-omit "" --output-omit "" --output-omit "" --output-omit "" \
7 | --output-omit "" --output-omit "" --output-omit "" --output-omit "" \
8 | --output-omit "" --output-omit "" --output-omit "" --output-omit "" \
9 | --output-omit "" --output-omit "" --output-omit "" --output-omit "" \
10 | --output-omit "" --output-omit "" --output-omit "" --output-omit "" \
11 | --output-omit "" --output-omit "" --output-omit "" --output-omit "" \
12 | --output-omit "" --output-omit "" --output-omit "" --output-omit "" \
13 | --output-omit "" --output-omit "" --output-omit "" --output-omit "" \
14 | --output-omit "" --output-omit "" --output-omit "" \
15 | --output-tostring "" \
16 | --output-tokenize "" --output-tostring "