shift()
function will fail if passed a negative integer at compile timeLow Risk
https://github.com/vyperlang/vyper/blob/b01cd686aa567b32498fefd76bd96b0597c6f099/vyper/builtins/functions.py#L1451-L1466
The built-in shift()
function accepts an INT256
as an input, which are accounted for and work fine at runtime. However, there is a compile time check that causes a revert if a negative literal is passed to the function.
In the evaluate()
method, which is used when shift()
is evaluated at compile time, there is the following check:
if value < 0 or value >= 2**256:
raise InvalidLiteral("Value out of range for uint256", node.args[0])
However, the function is intended to accept INT256
as an argument:
_inputs = [("x", (UINT256_T, INT256_T)), ("_shift_bits", IntegerT.any())]
This is properly handled in the build_IR()
method, but fails when evaluate()
is called at compile time.
Contracts that shift a negative literal and attempt to evaluate the expression at compile time will fail to compile.
Manual Review
The ideal option would be to update the evaluate()
method to handle negative integers.
Alternatively, given the shift()
function is deprecated and may not justify the extra work, the easiest solution is to simply raise UnfoldableNote
for values between type(int256).min
and 0
, which will skip evaluation and leave the function to be evaluated at runtime.