question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Transaction status is 1, but last opcode is REVERT

See original GitHub issue

I have a project that uses brownie and ganache-cli --fork against a geth node. (Geth is running according to these steps).

A few of my tests check the return_value of my transactions. Most succeed, but one has no return value despite not reverting.

Expected Behavior

A transaction with a status of 1 should have a return value.

Current Behavior

  • eth_getTransactionReceipt.status is 1
  • debug_traceTransaction final instruction is REVERT

Steps to Reproduce

  1. git clone https://github.com/SatoshiAndKin/argobytes-contracts-brownie (at ecf07c4)
  2. Follow the readme
  3. ./scripts/test.sh tests/test_uniswap_v1_arbitrage.py -I
./scripts/test.sh tests/test_uniswap_v1_arbitrage.py -I
+ [ -z /home/ski/code/argobytes-contracts-brownie/venv ]
+ brownie test --network mainnet-fork tests/test_uniswap_v1_arbitrage.py -I
Brownie v1.8.9 - Python development framework for Ethereum

===================================================================================== test session starts =====================================================================================
platform linux -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: /home/ski/code/argobytes-contracts-brownie
plugins: eth-brownie-1.8.9, forked-1.1.3, web3-5.10.0, hypothesis-5.15.0, xdist-1.32.0
collecting ... Attached to local RPC client listening at '127.0.0.1:8575'...
collected 1 item                                                                                                                                                                              

tests/test_uniswap_v1_arbitrage.py F
address_zero = '0x0000000000000000000000000000000000000000', argobytes_atomic_trade = <ArgobytesAtomicTrade Contract '0xF024fE5EF0b1Bf88caf9B1222E49d1A5CC312a71'>
dai_erc20 = <Dai Contract '0x6B175474E89094C44Da98b954EedeAC495271d0F'>, argobytes_owned_vault = <ArgobytesOwnedVault Contract '0xb66F46436fa703237A9Fd26f4DA63919D3cc943D'>
example_action = <ExampleAction Contract '0xDb43EFA90874d427e38Ff1e5F08572c0a2619930'>, chi = <ChiToken Contract '0x0000000000004946c0e9F43F4Dee607b0eF1fA1c'>
uniswap_v1_factory = <Vyper_contract Contract '0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95'>, uniswap_v1_action = <UniswapV1Action Contract '0x006ba56B025c63aE46c510a904422945F2389d6F'>
usdc_erc20 = <FiatTokenProxy Contract '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'>

    def test_uniswap_arbitrage(address_zero, argobytes_atomic_trade, dai_erc20, argobytes_owned_vault, example_action, chi, uniswap_v1_factory, uniswap_v1_action, usdc_erc20):
        assert argobytes_owned_vault.balance() == 0
        assert example_action.balance() == 0
    
        value = 1e18
    
        # send some ETH into the vault
        accounts[0].transfer(argobytes_owned_vault, value)
        # send some ETH into the sweep contract to simulate arbitrage profits
        accounts[0].transfer(example_action, value)
    
        # mint some gas token
        # TODO: how much should we make?
        argobytes_owned_vault.mintGasToken(chi, 26, {"from": accounts[0]})
    
        # make sure balances match what we expect
        assert argobytes_owned_vault.balance() == value
        assert example_action.balance() == value
    
        usdc_exchange = uniswap_v1_action.getExchange(uniswap_v1_factory, usdc_erc20)
        dai_exchange = uniswap_v1_action.getExchange(uniswap_v1_factory, dai_erc20)
    
        # sweep a bunch of times to use up gas
        encoded_actions = argobytes_atomic_trade.encodeActions(
            [
                example_action,
                uniswap_v1_action,
                uniswap_v1_action,
                uniswap_v1_action,
            ],
            [
                # add some faked profits
                example_action.sweep.encode_input(uniswap_v1_action, address_zero),
    
                # trade ETH to USDC
                # uniswap_v1_action.tradeEtherToToken(address to, address exchange, address dest_token, uint dest_min_tokens, uint trade_gas)
                uniswap_v1_action.tradeEtherToToken.encode_input(uniswap_v1_action, usdc_exchange, usdc_erc20, 1, 0),
    
                # trade USDC to DAI
                # uniswap_v1_action.tradeTokenToToken(address to, address exchange, address src_token, address dest_token, uint dest_min_tokens, uint trade_gas)
                uniswap_v1_action.tradeTokenToToken.encode_input(
                    uniswap_v1_action, usdc_exchange, usdc_erc20, dai_erc20, 1, 0),

                # trade DAI to ETH
                # uniswap_v1_action.tradeTokenToEther(address to, address exchange, address src_token, uint dest_min_tokens, uint trade_gas)
                uniswap_v1_action.tradeTokenToEther.encode_input(address_zero, dai_exchange, dai_erc20, 1, 0),
            ],
        )
    
        arbitrage_tx = argobytes_owned_vault.atomicArbitrage(
            chi, argobytes_atomic_trade, address_zero, [address_zero], value, encoded_actions, {'from': accounts[1]})
    
        assert argobytes_owned_vault.balance() > value
    
        # make sure the transaction succeeded
        # there should be a revert above if status == 0, but something is wrong
        assert arbitrage_tx.status == 1
>       assert arbitrage_tx.return_value is not None
E       AssertionError: assert None is not None
E        +  where None = <Transaction '0x903f37e1596487075620d2c83dea892287b553c0147d97fb8bf4642a2083e177'>.return_value

tests/test_uniswap_v1_arbitrage.py:67: AssertionError

Interactive mode enabled. Use quit() to continue running tests.
>>> arbitrage_tx.trace[-1]['op']                                                                                                                                                               
'REVERT'
>>> arbitrage_tx._trace[-1]['op']                                                                                                                                                              
'REVERT'
>>>  

Context

Due to previous issues with reverting traces pointing to incorrect lines, I’ve disabled solc’s runs, so that shouldn’t be the problem.

I suspected that gastoken2/chi might be related to the issue, but removing that code didn’t change anything.

I’m sure the transaction isn’t actually reverting because my test balance increases after the transaction is completed. If the transaction had reverted, the balance would not increase.

I don’t think Brownie is the problem here. Brownie just gets the trace from ganache.

Your Environment

  • Version used: ganache-cli 6.9.1 and 6.10.0-beta.1
  • Version of Truffle/Remix/Other tools used: eth-brownie-1.8.9
  • NodeJS Version: [ ] 6.x, [ ] 7.x (unsupported), [ ] 8.x, [ ] 9.x, [x] v12.16.3
  • Operating System and version (include distro if Linux): Ubuntu 20.04
  • Link to your project or repro gist: https://github.com/SatoshiAndKin/argobytes-contracts-brownie
  • Commit hash to use with above link for reproduction: ecf07c4
  • I intend to submit a pull request to fix this issue: [ ]

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:27 (18 by maintainers)

github_iconTop GitHub Comments

2reactions
seesemichaeljcommented, Sep 22, 2020

Quick update here: I’ve figured out the root cause of @WyseNynja’s bug (at least the next hurdle haha). I can reproduce it in a test, and hoping to get over this one soon!

1reaction
WyseNynjacommented, Oct 26, 2020

Yes! My tests so far are much better. I haven’t had time to finish them all (been working on proxy contracts instead), but the ones that were failing are passing now. Thank you!

On Oct 26, 2020, at 10:40 AM, Mike Seese notifications@github.com wrote:

@WyseNynja have you been able to test this yet? Are your forking issues resolved? Looks like it also made into a stable release a couple weeks ago: https://github.com/trufflesuite/ganache-core/releases/tag/v2.13.0 | https://github.com/trufflesuite/ganache-cli/releases/tag/v6.12.0

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is a revert opt code? - Ethereum Stack Exchange
At etherscan I search the failed transaction and it has this message: "Value transfer did not complete, most likely as a result of...
Read more >
Failed Transaction with opcode "REVERT". . . money lost?
The Receipt Status is "Fail", and the Value says "Value transfer did not complete, most likely as a result of a REVERT opcode"....
Read more >
Error: VM Exception while processing transaction: revert.
REVERT : "revert" ⇐ Something somewhere broke. This revert will return the remaining gas. The most common error.
Read more >
Ethereum Virtual Machine Opcodes
uint8 Mnemonic Stack Output 00 STOP ‑ 01 ADD a + b 02 MUL a * b
Read more >
How to reference LINK token on (forked) development network ...
In this instance, the account used for Link token funding does not have any Link. For some reason, the transaction does not get...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found