본문으로 건너뛰기
mip.watch
⌘K

MIP-3

Linear Memory

확정 표준 트랙 코어 MONAD_NINE에 번들됨 GitHub ↗ 포럼 ↗
아이디어 초안 검토 중 최종 검토 확정 유지 중

Redefine memory expansion cost to be linear and enforce an explicit maximum memory usage per transaction

작성자
Category Labs
생성일
2025-12-10
수정일
2026. 6. 15.

이해관계자 영향

이 MIP이 각 대상에게 무엇을 바꾸는지 보여줍니다. 심각도와 조치 플래그는 모델이 도출하며, MIP 유형/카테고리별로 결정론적 최소값이 적용됩니다.

AI 요약을 사용할 수 없음 — 구조적 기본값으로 대체

핵심 요약

이 MIP의 AI 인사이트를 사용할 수 없습니다 — 아래에 구조적 기본값을 표시합니다.

무엇이 바뀌나

  • 이 MIP의 AI 인사이트를 사용할 수 없습니다 — 아래에 구조적 기본값을 표시합니다.

개발자

스마트 컨트랙트 및 dapp 개발자, RPC 사용자, 도구 제작자

낮음

사용자

지갑 사용자, EOA 보유자, dapp 방문자

낮음

검증자

노드 운영자, RPC 운영자, 위임자

중간

재단

Monad 재단 및 Category Labs 코어 개발자

낮음

명세

인용
서브시스템 executionevm

## Abstract

Redefine memory expansion cost to be linear and enforce an explicit maximum memory usage per transaction. 

## Motivation

Currently, EVM memory usage is bounded by a quadratic expansion cost and the 63/64 rule. The theoretical memory limit of a transaction is at least 26 MB. Historical transaction analysis shows that average memory usage is ~2 KB and maximum observed memory usage is ~2 MB. 

Benchmarks also indicate that the current memory expansion formula overcharges for actual resource usage.

This update aligns cost with actual resource consumption. It makes memory usage more predictable, particularly for contracts that rely on large memory allocations.

## Specification

Memory expansion cost is redefined as:

```python
memory_size_words = (memory_byte_size + 31) // 32
memory_cost = memory_size_words // 2
```

The max memory usage is capped at 8 MB.  Memory allocation is bounded across call contexts with the following rule: 

1. Let `k` be the memory used by the current call, and `j` the memory used by parent calls.
2. The remaining memory available to a child call is: 

```python
 remaining_memory = 8 * 1024 * 1024 - j - k
```
3. Once a call returns, the memory is returned to the pool.
4. If a call exceeds the remaining memory limit, it reverts.

## Backwards Compatibility

This proposal is highly compatible with existing contracts. Almost all standard EVM operations remain valid and ERC-4337 contracts continue to function correctly, as child call memory is released upon completion. Replay testing of historical Ethereum transactions will be used to quantify compatibility.

However, contracts that allocate more than 8 MB of memory will now revert.

## Security Considerations

The cost to expand memory to the 8MB ceiling is 131,072 gas. The result is that it is cheaper to expand memory than current costs. Potentially concurrency limits for RPC nodes should be adjusted to prevent OOM issue. 

## Acknowledgements

The proposals in this MIP are based on two previous EIP documents. Additionally, conversations with Charles Cooper were instructive in developing the Monad memory model:

- [EIP-7686](https://eips.ethereum.org/EIPS/eip-7686) (@vbuterin)
- [EIP-7923](https://eips.ethereum.org/EIPS/eip-7923) (@charles-cooper, @qizhou)

MIP-3 differs from EIP-7686 in that EIP-7686 defines a direct relationship between memory limit and gas limit, and from EIP-7923 in that MIP-3 does not adopt the page-based thrashing cost model.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).

포럼 토론

게시물 15개 · 좋아요 5개 · 4개월 전
포럼에서 더 읽기 ↗
  1. @John Bergschneider #1 2025. 12. 31. 오후 5:21

    MIP3 - Linear EVM memory cost This proposal reprices EVM memory expansion from a quadratic cost model to a linear one. To bound total memory usage within a block, each transaction is explicitly limited by its peak memory usage. The motivation is to better align EVM gas costs with real resource usage and to introduce an explicit invariant on total memory usage at the block level. Any feedback or discussion is appreciated on: - the proposed linear memory cost model - the explicit per-transaction memory limit - potential DoS concerns - developer ergonomics and usage concerns

  2. @Pdobacz #2 2026. 1. 19. 오후 4:54

    Hello, I have questions to the design and spec: 1. How does the call which exceeds memory exit? revert or exceptionally halt? If revert, does the gas to extend memory get charged before reverting? and other instruction gas charges (esp. *CALL )? exceptionally halt is more consistent with current OOM behavior (out-of-gas), but revert is more friendly. The spec says “revert” but I want to confirm that’s what was meant and spec out the fine details. 2. For all calculation related to memory limit, the memory size isn’t rounded up to the nearest word, i.e. if caller frame allocates `limit - 1byte` memory, callee frame can still allocate `1byte` of memory? This is in the spec, but want to confirm.

  3. @Pdobacz #3 2026. 1. 20. 오전 11:08

    - Can we expand discussion with EIP-7686 and EIP-7923 in the Rationale section, i.e. why is MIP-3 chosen over them? (my understanding is that EIP-7686 would combine unfavorably with Monad’s “charge-gas-limit” rule, what about the paging from EIP-7923?) - Similar to EIP-7923, behavior of MSIZE after the activation should be confirmed (esp. given the lack of rounding to word in memory limit calculation.) In other words - would MSIZE return limit or limit - 1byte in the case mentioned in (2.)?

  4. @John Bergschneider #4 2026. 1. 21. 오후 3:20

    Some Responses: - Exceeding the memory limit causes the current call frame to revert rather than halt. One rationale for this decision is compatibility with ERC-4337 bundlers for the following reason: if exceeding the memory limit resulted in an exceptional halt a transaction could DOS erc4337 bundlers by using the memory limit. If compatibility with erc4337 is not necessary then this can be changed to halt.

  5. @John Bergschneider #5 2026. 1. 23. 오전 12:00

    - Expansion cost remains in terms of 32 byte word expansion. This will be defined more explicitly in the MIP. - EIP-7686 and EIP-7923 are designed for ethereum execution specifically. For example in EIP-7686, it defines a strict bound on memory expansion via gas. This defines the amount of expandable memory to be linearly dependent on the amount of gas forwarded in the call. This is not compatible to the constraints of Monad execution. As it would cause a higher memory footprint per transaction. - MSIZE semantics are unchanged. It returns the size of active memory in bytes. So the case where caller frame allocates limit - 1byte memory is rounded up to the limit memory. The child call would not have any remaining memory to allocate.