Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vyper 0.2.14 #1155

Merged
merged 2 commits into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion brownie/project/compiler/vyper.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@ def _get_dependencies(ast_json: List) -> List:
return sorted(set([i["name"].split(".")[-1] for i in import_nodes]))


def _is_revert_jump(pc_list: List, revert_pc: int) -> bool:
return pc_list[-1]["op"] == "JUMPI" and int(pc_list[-2].get("value", "0"), 16) == revert_pc


def _generate_coverage_data(
source_map_str: str, opcodes_str: str, contract_name: str, ast_json: List
) -> Tuple:
Expand All @@ -297,6 +301,14 @@ def _generate_coverage_data(
pc_list: List = []
count, pc = 0, 0

revert_pc = -1
if opcodes[-5] == "JUMPDEST" and opcodes[-1] == "REVERT":
# starting in vyper 0.2.14, reverts without a reason string are optimized with a jump
# to the end of the bytecode. if the bytecode ends with this pattern, we set `revert_pc`
# as the program counter of the jumpdest so we can identify these optimizer reverts
# within traces.
revert_pc = len(opcodes) - 5

while opcodes:
# format of source is [start, stop, contract_id, jump code]
source = source_map.popleft()
Expand All @@ -316,6 +328,10 @@ def _generate_coverage_data(
len(pc_list) > 6
and pc_list[-7]["op"] == "CALLVALUE"
and pc_list[-1]["op"] == "REVERT"
) or (
len(pc_list) > 2
and pc_list[-3]["op"] == "CALLVALUE"
and _is_revert_jump(pc_list[-2:], revert_pc)
):
# special case - initial nonpayable check on vyper >=0.2.5
pc_list[-1]["dev"] = "Cannot send ether to nonpayable function"
Expand Down Expand Up @@ -345,7 +361,7 @@ def _generate_coverage_data(
continue

node = _find_node_by_offset(ast_json, offset)
if pc_list[-1]["op"] == "REVERT":
if pc_list[-1]["op"] == "REVERT" or _is_revert_jump(pc_list[-2:], revert_pc):
# custom revert error strings
if node["ast_type"] == "FunctionDef" and pc_list[-7]["op"] == "CALLVALUE":
pc_list[-1]["dev"] = "Cannot send ether to nonpayable function"
Expand Down Expand Up @@ -377,6 +393,8 @@ def _generate_coverage_data(

pc_list[0]["path"] = "0"
pc_list[0]["offset"] = [0, _convert_src(ast_json[-1]["src"])[1]]
if revert_pc != -1:
pc_list[-1]["optimizer_revert"] = True

pc_map = dict((i.pop("pc"), i) for i in pc_list)

Expand Down
4 changes: 2 additions & 2 deletions tests/network/transaction/test_subcalls.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@


vyper_source = """
# @version 0.2.12
# @version 0.2.14


TARGET: constant(address) = 0xD0660cD418a64a1d44E9214ad8e459324D8157f1
Expand Down Expand Up @@ -54,7 +54,7 @@ def solidity_contract(accounts):

@pytest.fixture()
def vyper_contract(accounts):
container = compile_source(vyper_source, vyper_version="0.2.12").Vyper
container = compile_source(vyper_source, vyper_version="0.2.14").Vyper
return container.deploy({"from": accounts[0]})


Expand Down