vyperlang / vyper

Pythonic Smart Contract Language for the EVM
https://vyperlang.org
Other
4.87k stars 799 forks source link

Vyper doesn't read bool returned by Solidity's modifying contracts after state is modified #1377

Closed michwill closed 5 years ago

michwill commented 5 years ago

Version Information

What's your issue about?

When a Vyper contract casts an address to an interface, and a modifying method is called, such as InterfaceName(address).method(), if the method returns bool, Vyper doesn't see that bool properly when the external contract deployed at address is written in Solidity.

The self-contained minimal test case (which should pass when fixed) is here: https://github.com/michwill/vyper-solidity-bug

haydenadams commented 5 years ago

Pretty sure this is not the case. If it was, this line in Uniswap would fail:

https://github.com/Uniswap/contracts-vyper/blob/master/contracts/uniswap_exchange.vy#L132

since many tokens on Uniswap (pretty sure all) are written in Solidity.

michwill commented 5 years ago

That is exactly how I discovered it: followed Uniswap as an example. However, Uniswap was compiled with vyper-0.1.0b4. @haydenadams I strongly suspect that this line you have mentioned will fail with the newest vyper when working with contracts written in solidity. But I have to admit that I didn't try to arrange this test with Uniswap

haydenadams commented 5 years ago

@michwill appears you were right and I totally forgot about this issue until I spent an hour debugging it...

It's not solidity specific (or even bool specific). It's the same for external calls to vyper contracts an other variable types. It has to do with directly asserting the result of an external call:

https://github.com/ethereum/vyper/issues/1468

The workaround is to set the result equal to a local variable before asserting:

success: bool = self.token.transferFrom(msg.sender, self, token_amount)
assert success