Vyper handles AugAssign statements by first caching the target location to avoid double evaluation. However, in the case when target is an access to a DynArray and the rhs modifies the array, the cached target will evaluate first, and the bounds check will not be re-evaluated during the write portion of the statement. In other words, the following code
def poc():
a: DynArray[uint256, 2] = [1, 2]
a[1] += a.pop()
is equivalent to:
def poc():
a: DynArray[uint256, 2] = [1, 2]
a[1] += a[len(a) - 1]
a.pop()
rather than:
def poc():
a: DynArray[uint256, 2] = [1, 2]
s: uint256 = a[1]
t: uint256 = a.pop()
a[1] = s + t # reverts due to oob access
References
Vyper handles AugAssign statements by first caching the target location to avoid double evaluation. However, in the case when target is an access to a DynArray and the rhs modifies the array, the cached target will evaluate first, and the bounds check will not be re-evaluated during the write portion of the statement. In other words, the following code
is equivalent to:
rather than:
References