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