Purpose of checking if `returndatasize` is greater than 31 bytes in `SafeTransferLib`?
xenide opened this issue · 4 comments
I'm curious regarding the purpose of checking for the return size being greater than 31 bytes. Is it to guard against implementations returning a uint8
/ uint128
etc types instead of a bool?
Besides, it doesn't guard against implementations which return a uint256
type but of value 1
does it?
For context, I had this question after referencing solady's implementation, which doesn't check for the return type greater than 31 bytes.
@xenide Solady's implementation does indeed check that the returndatasize
is greater than 31, albeit with some devious trickery.
In all the examples, as all the call function selectors does not end with the 0x01
byte, simply checking that slot 0x00
is rewritten to 0x0000000000000000000000000000000000000000000000000000000000000001
(i.e. 1) is sufficient to check that the returndatasize
is indeed greater than 31.
got it, but both of these implementations don't really protect against an ERC20 that returns a uint8
or uint16
for example, if the contract is written using solidity.
If the contract was using assembly or yul then it's possible to return less than 32 bytes. Correct?
@xenide It is possible to return less than 32 bytes if you write in assembly. But then, this will result in memory slot 0x00 not being exactly 1.
So to circle back to the original question, the purpose of checking for return data size greater than 31 bytes is really to guard against weird implementations in assembly/yul which returns types less than 32 bytes. It does not guard against solidity implementations returning a 1
in int/uint/bool
Is my understanding correct? If so, I'll close this issue