With Solidity 0.4.23 a require
statement seemingly fail if a contract called has a returndatasize
of less than 32. This issue was found when wrapping a transferFrom
function call, which doesn't return anything, in a require
.
Older contracts that use STOP
to return control flow place 1
on the stack through the return of CALL
and so RETURNDATASIZE
is set to 0
. The new require seems to enforce that at least 32
bytes must be returned by the child contract (with RETURNDATASIZE >= 0x20
) which seems to break old contracts that simply check whether the return of CALL
itself was 1
.
The token contract used is Adex.
This issue indicates that any token transfered without a return will fail, affecting any contract using tokens transfers that are wrapped in a require as of solidity v0.4.23
To ensure this really is an issue, we have tried running the code with 2 solidity versions. Essentially wrapping the transferFrom
in a require
.
- Solidity v0.4.21 0x692ac40b9d5e866ef4c5b090349e7d4d27d817b72bc92f7c29cd15fe1de91c91
- Solidity v0.4.23 0xfa7023baf597b811ce50b9ae7f7cf30b9a12fbf6c5ce821a333df1925b9142cd
The below example highlights the issue, if the code is deployed with solidity v0.4.23 the transfer of BadToken using the Transferer will fail, if an earlier solidity version is used. transfer
on the Transferer contract will not revert.
- BadToken x Transferer in Solidity v0.4.23: 0xd6d52208061a639d348c63a3c5ec55e695c84994a2673ecf1fb4b25918a2c061
- BadToken x Transferer in Solidity v0.4.21: 0xaad6440ff4bb6896d9c384087787208a7b2c93b8e612702c5cc08118d5041120