vyper
vyper copied to clipboard
vyper.exceptions.StackTooDeep: Unsupported dup depth 17
Version Information
- vyper Version (output of
vyper --version): 0.4.0+commit.e9db8d9 - OS: GNU/Linux
- Python Version (output of
python --version): Python 3.12.5
What's your issue about?
I ran
vyper --verbose bug.vy
where bug.vy contains
#pragma version ~=0.4.0
#pragma evm-version cancun
#pragma optimize gas
#pragma experimental-codegen
MAX_CLAIM_INTERVALS: constant(uint256) = 128 # ~10 years
MAX_PROOF_LENGTH: constant(uint256) = 32 # ~ 4 billion claimers
interface RocketStorageInterface:
def getAddress(_key: bytes32) -> address: view
interface RocketMerkleDistributorInterface:
def claimAndStake(_nodeAddress: address,
_rewardIndex: DynArray[uint256, MAX_CLAIM_INTERVALS],
_amountRPL: DynArray[uint256, MAX_CLAIM_INTERVALS],
_amountETH: DynArray[uint256, MAX_CLAIM_INTERVALS],
_merkleProof: DynArray[DynArray[bytes32, MAX_PROOF_LENGTH], MAX_CLAIM_INTERVALS],
_stakeAmount: uint256): nonpayable
rocketMerkleDistributorKey: constant(bytes32) = keccak256("contract.addressrocketMerkleDistributorMainnet")
rocketStorage: public(immutable(RocketStorageInterface))
@internal
@view
def _getMerkleDistributor() -> RocketMerkleDistributorInterface:
return RocketMerkleDistributorInterface(
staticcall rocketStorage.getAddress(rocketMerkleDistributorKey)
)
struct BorrowerState:
RPL: uint256 # RPL available for repayments and/or withdrawal
ETH: uint256 # ETH available for liquidation and/or withdrawal
index: uint256 # first not-yet-accounted interval index
address: address # current address for the borrower
borrowers: public(HashMap[address, BorrowerState])
@deploy
def __init__(_rocketStorage: address):
rocketStorage = RocketStorageInterface(_rocketStorage)
@external
def forceClaimMerkleRewards(
_node: address,
_rewardIndex: DynArray[uint256, MAX_CLAIM_INTERVALS],
_amountRPL: DynArray[uint256, MAX_CLAIM_INTERVALS],
_amountETH: DynArray[uint256, MAX_CLAIM_INTERVALS],
_merkleProof: DynArray[DynArray[bytes32, MAX_PROOF_LENGTH], MAX_CLAIM_INTERVALS]
):
self._claimMerkleRewards(_node, _rewardIndex, _amountRPL, _amountETH, _merkleProof)
@internal
def _updateIndex(_toIndex: uint256):
pass
@internal
def _claimMerkleRewards(
_node: address,
_rewardIndex: DynArray[uint256, MAX_CLAIM_INTERVALS],
_amountRPL: DynArray[uint256, MAX_CLAIM_INTERVALS],
_amountETH: DynArray[uint256, MAX_CLAIM_INTERVALS],
_merkleProof: DynArray[DynArray[bytes32, MAX_PROOF_LENGTH], MAX_CLAIM_INTERVALS],
) -> (uint256, uint256):
maxUnclaimedIndex: uint256 = 0
totalRPL: uint256 = self.borrowers[_node].RPL
totalETH: uint256 = self.borrowers[_node].ETH
for index: uint256 in _rewardIndex:
maxUnclaimedIndex = max(index + 1, maxUnclaimedIndex)
extcall self._getMerkleDistributor().claimAndStake(_node, _rewardIndex, _amountRPL, _amountETH, _merkleProof, 0)
self._updateIndex(maxUnclaimedIndex)
return totalRPL, totalETH
I got this output
cli specified: `Settings(compiler_version=None, optimize=None, evm_version=None, experimental_codegen=None, debug=None, enable_decimals=None)`
Error compiling: bug.vy
Traceback (most recent call last):
File "/home/ramana/.local/bin/vyper", line 8, in <module>
sys.exit(_parse_cli_args())
^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/cli/vyper_compile.py", line 65, in _parse_cli_args
return _parse_args(sys.argv[1:])
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/cli/vyper_compile.py", line 238, in _parse_args
compiled = compile_files(
^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/cli/vyper_compile.py", line 377, in compile_files
output = vyper.compile_from_file_input(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/compiler/__init__.py", line 129, in compile_from_file_input
exc_handler(str(file_input.path), exc)
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/cli/vyper_compile.py", line 278, in exc_handler
raise exception
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/compiler/__init__.py", line 126, in compile_from_file_input
ret[output_format] = formatter(compiler_data)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/compiler/output.py", line 367, in build_bytecode_output
return f"0x{compiler_data.bytecode.hex()}"
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/functools.py", line 993, in __get__
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/compiler/phases.py", line 253, in bytecode
return generate_bytecode(self.assembly, insert_compiler_metadata=insert_compiler_metadata)
^^^^^^^^^^^^^
File "/usr/lib/python3.12/functools.py", line 993, in __get__
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/compiler/phases.py", line 235, in assembly
return generate_assembly_experimental(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/__init__.py", line 39, in generate_assembly_experimental
return compiler.generate_evm(optimize == OptimizationLevel.NONE)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 160, in generate_evm
self._generate_evm_for_basicblock_r(asm, fn.entry, StackModel())
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 302, in _generate_evm_for_basicblock_r
self._generate_evm_for_basicblock_r(asm, bb, stack.copy())
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 302, in _generate_evm_for_basicblock_r
self._generate_evm_for_basicblock_r(asm, bb, stack.copy())
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 302, in _generate_evm_for_basicblock_r
self._generate_evm_for_basicblock_r(asm, bb, stack.copy())
[Previous line repeated 9 more times]
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 299, in _generate_evm_for_basicblock_r
asm.extend(self._generate_evm_for_instruction(inst, stack, next_liveness))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 405, in _generate_evm_for_instruction
self._emit_input_operands(assembly, inst, operands, stack)
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 268, in _emit_input_operands
self.dup_op(assembly, stack, op)
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 571, in dup_op
self.dup(assembly, stack, stack.get_depth(op))
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 565, in dup
assembly.append(_evm_dup_for(depth))
^^^^^^^^^^^^^^^^^^^
File "/home/ramana/.local/pipx/venvs/vyper/lib/python3.12/site-packages/vyper/venom/venom_to_assembly.py", line 584, in _evm_dup_for
raise StackTooDeep(f"Unsupported dup depth {dup_idx}")
vyper.exceptions.StackTooDeep: Unsupported dup depth 17
This is an unhandled internal compiler error. Please create an issue on Github to notify the developers!
https://github.com/vyperlang/vyper/issues/new?template=bug.md
How can it be fixed?
Fill this in if you know how to fix it.
More minimised version of bug.vy:
#pragma version ~=0.4.0
#pragma evm-version cancun
#pragma optimize gas
#pragma experimental-codegen
interface Iface:
def f5(x: DynArray[uint256, 128],
y: DynArray[DynArray[bytes32, 32], 128]): nonpayable
@internal
@view
def f4() -> Iface:
return Iface(0x0000000000000000000100000000000000000001)
struct St:
a: uint256
b: uint256
s1: public(HashMap[uint256, St])
@external
def f1(x: DynArray[uint256, 128], y: DynArray[DynArray[bytes32, 32], 128]):
self.f2(x, y)
@internal
def f3(i: uint256):
pass
@internal
def f2(x: DynArray[uint256, 128], y: DynArray[DynArray[bytes32, 32], 128]) -> (uint256, uint256):
c: uint256 = 0
a: uint256 = self.s1[0].a
b: uint256 = self.s1[0].b
for i: uint256 in [0]:
c = i
extcall self.f4().f5(x, y)
self.f3(c)
return a, b
we need to add a stack2mem pass in the case where we allocate too many stack variables