# Constraints

Important limits and boundaries when building on Rome EVM. Understanding these constraints helps you design contracts that work reliably.

## Solana Transaction Limits

| Constraint                 | Value       | Impact                                                       |
| -------------------------- | ----------- | ------------------------------------------------------------ |
| Transaction size           | 1,232 bytes | Large EVM txs are split across holder accounts (transparent) |
| Compute units per tx       | \~1.4M CU   | Operations exceeding this use iterative mode                 |
| Accounts per tx (no ALT)   | 28          | Use Address Lookup Tables for more                           |
| Accounts per tx (with ALT) | 64+         | ALT automatically used when > 28 accounts                    |
| Max holder size            | 80 KB       | Max RLP size for a single EVM transaction                    |

## EVM Execution Limits

| Constraint             | Value                   | Notes                                                 |
| ---------------------- | ----------------------- | ----------------------------------------------------- |
| Contract storage slots | 256 per storage account | Multiple storage accounts can be created per contract |
| Opcodes per iteration  | \~500                   | For iterative (VmIt) mode                             |
| Account lock TTL       | 3-4 seconds             | During iterative execution                            |
| Treasury wallets       | 64                      | Fee pool wallets                                      |
| Contract size limit    | 480 KB                  | Raised from Ethereum's 24 KB (OP-Geth mode)           |

## CPI Constraints

| Constraint                | Value                     | Notes                                           |
| ------------------------- | ------------------------- | ----------------------------------------------- |
| CPI depth                 | 4 levels max              | Solana's CPI depth limit                        |
| Accounts per CPI call     | Limited by Solana tx size | Practically \~20 accounts per CPI               |
| CPI + Transfer Hook depth | Uses CPI levels           | Transfer hooks from inside CPI may exceed depth |

**CPI depth is the most critical constraint.** Rome EVM consumes one CPI level when Solana calls the Rome program. If your Solidity contract then calls another Solana program via CPI, that's level 2. If that program calls another, that's level 3. You have at most 4 levels total.

```
Level 0: Solana Runtime → Rome EVM Program
Level 1: Rome EVM Program → Your CPI target (e.g., Jupiter)
Level 2: Jupiter → another program (e.g., Raydium)
Level 3: Raydium → SPL Token (maximum depth)
```

## Token-2022 Transfer Hook Constraints

| Constraint              | Impact                                                                                     |
| ----------------------- | ------------------------------------------------------------------------------------------ |
| One hook per mint       | Meta-Hook Router solves this (up to 8 sub-hooks)                                           |
| `transfer_checked` only | Hooks don't fire on plain `transfer`. Rome bridge MUST use `transfer_checked`              |
| Mint/burn not hooked    | Controlled via mint authority, not hooks                                                   |
| Single-state mode only  | OP-Geth unreachable from inside Solana tx                                                  |
| Token wrapping escape   | Users can wrap tokens to bypass hooks. Mitigated via wrapper blacklist + PermanentDelegate |

## Gas and Pricing Constraints

| Constraint           | Notes                                                      |
| -------------------- | ---------------------------------------------------------- |
| Gas pricing source   | Meteora DAMM V1 pool (SPL gas token)                       |
| Gas price multiplier | Configurable per proxy (`gas_price_mul`)                   |
| Minimum gas price    | Set by proxy configuration                                 |
| Gas estimation       | Performed off-chain via Mollusk emulator before submission |

## Network-Specific Constraints

| Environment       | Chain ID | Program ID                                    |
| ----------------- | -------- | --------------------------------------------- |
| Local             | 1001     | Set in `rome-setup` config                    |
| Devnet (montispl) | 200002   | `RD2Gg7Lcnv62XmRHAzxh6fQQfMRzHtN5LeKPVBhYU5S` |
| Testnet (Martius) | 121214   | Check deployment config                       |
| Testnet (Caelian) | 121215   | Check deployment config                       |

## Precompile Constraints

| Precompile                 | Constraint                                                   |
| -------------------------- | ------------------------------------------------------------ |
| Modexp (0x05)              | **Disabled** — can be enabled via feature flag               |
| BN254 ecPairing (0x08)     | High CU cost — typically requires iterative mode (\~200K CU) |
| CPI precompile (0xFF...08) | Accounts must be declared upfront in the Solana transaction  |

## Oracle Constraints

| Constraint            | Value                                                        |
| --------------------- | ------------------------------------------------------------ |
| Default max staleness | 60 seconds                                                   |
| Historical round data | Not supported — `getRoundData(roundId)` reverts              |
| Switchboard EMA       | Not supported — `latestEMAData()` reverts on SwitchboardV3   |
| Parser offsets        | Empirically validated — must re-validate before redeployment |

## Design Recommendations

1. **Keep CPI depth shallow.** Design contracts to minimize nesting. If you're calling Jupiter which calls Raydium which calls SPL Token, you're at 3 levels — dangerously close to the limit.
2. **Prefer atomic mode.** Design operations to fit within \~1.4M CU. Iterative mode adds latency (3-4 second locks) and complexity.
3. **Declare accounts upfront.** All Solana accounts touched by CPI must be known at transaction creation time. Dynamic account discovery within a CPI call is not possible.
4. **Use `transfer_checked`.** If you're building anything that touches Token-2022 tokens, always use `transfer_checked` to ensure hooks fire.
5. **Test CU consumption.** Use `eth_estimateGas` during development. Optimize with Yul for hot paths. See [CU Optimization](https://github.com/rome-protocol/docs/blob/main/developer-guides/cu-optimization.md).

## What's Next

* [Compute Budget](/core-concepts/compute-budget.md) — detailed CU costs per operation
* [Token Interop](/core-concepts/token-interop.md) — ERC-20 ↔ SPL bridging model
* [CU Optimization Guide](https://github.com/rome-protocol/docs/blob/main/developer-guides/cu-optimization.md) — practical optimization techniques


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rome.builders/core-concepts/constraints.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
