> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Frame

> EVM execution frame representing stack, memory, gas, and call context for smart contract execution

## Overview

A Frame represents a single EVM execution context. When a smart contract executes, it runs within a frame that maintains:

* **Stack** - 1024-element LIFO stack of 256-bit values
* **Memory** - Sparse byte-addressable scratch space
* **Gas** - Remaining gas for execution
* **Call context** - Caller, address, value, calldata

Each CALL, DELEGATECALL, STATICCALL, CREATE, or CREATE2 creates a new nested frame. The EVM supports up to 1024 call depth.

## Type Definition

```typescript theme={null}
import type { BrandedFrame } from 'voltaire/evm/Frame';

// BrandedFrame structure
type BrandedFrame = {
  // Stack (max 1024 items)
  stack: bigint[];

  // Memory (sparse map)
  memory: Map<number, number>;
  memorySize: number; // Word-aligned size

  // Execution state
  pc: number;           // Program counter
  gasRemaining: bigint;
  bytecode: Uint8Array;

  // Call context
  caller: Address;
  address: Address;
  value: bigint;
  calldata: Uint8Array;
  output: Uint8Array;
  returnData: Uint8Array;

  // Flags
  stopped: boolean;
  reverted: boolean;
  isStatic: boolean;

  // Other
  authorized: bigint | null;
  callDepth: number;

  // Optional: hardfork, access lists, block context, logs...
};
```

## Creating a Frame

```typescript theme={null}
import { Frame } from 'voltaire/evm/Frame';

// Create with defaults
const frame = Frame();

// Create with parameters
const frame = Frame({
  bytecode: new Uint8Array([0x60, 0x01, 0x60, 0x02, 0x01]), // PUSH1 1, PUSH1 2, ADD
  gas: 100000n,
  caller: callerAddress,
  address: contractAddress,
  value: 0n,
  calldata: new Uint8Array([]),
  isStatic: false,
});
```

### Frame Parameters

| Parameter      | Type         | Default      | Description                          |
| -------------- | ------------ | ------------ | ------------------------------------ |
| `bytecode`     | `Uint8Array` | `[]`         | Contract bytecode to execute         |
| `gas`          | `bigint`     | `1000000n`   | Initial gas allocation               |
| `caller`       | `Address`    | zero address | Message sender (msg.sender)          |
| `address`      | `Address`    | zero address | Current contract address             |
| `value`        | `bigint`     | `0n`         | Wei transferred (msg.value)          |
| `calldata`     | `Uint8Array` | `[]`         | Input data (msg.data)                |
| `isStatic`     | `boolean`    | `false`      | Static call (no state modifications) |
| `stack`        | `bigint[]`   | `[]`         | Initial stack state                  |
| `gasRemaining` | `bigint`     | `gas`        | Override gas (for resuming)          |

## Stack Operations

### pushStack

Push a 256-bit value onto the stack.

```typescript theme={null}
import { Frame, pushStack } from 'voltaire/evm/Frame';

const frame = Frame();
const error = pushStack(frame, 42n);

if (error) {
  // error.type === "StackOverflow" when stack has 1024 items
  console.error(error.type);
}
```

### popStack

Pop the top value from the stack.

```typescript theme={null}
import { Frame, popStack, pushStack } from 'voltaire/evm/Frame';

const frame = Frame();
pushStack(frame, 100n);
pushStack(frame, 200n);

const result = popStack(frame);
if (result.error) {
  // result.error.type === "StackUnderflow" when stack is empty
  console.error(result.error.type);
} else {
  console.log(result.value); // 200n (LIFO)
}
```

### peekStack

Read a stack value without removing it.

```typescript theme={null}
import { Frame, peekStack, pushStack } from 'voltaire/evm/Frame';

const frame = Frame();
pushStack(frame, 10n);
pushStack(frame, 20n);
pushStack(frame, 30n);

const top = peekStack(frame, 0);     // 30n (top)
const second = peekStack(frame, 1);  // 20n
const third = peekStack(frame, 2);   // 10n
```

## Gas Operations

### consumeGas

Deduct gas from the frame. Returns `OutOfGas` error if insufficient.

```typescript theme={null}
import { Frame, consumeGas } from 'voltaire/evm/Frame';

const frame = Frame({ gas: 100n });

consumeGas(frame, 30n);  // gasRemaining: 70n
consumeGas(frame, 50n);  // gasRemaining: 20n

const error = consumeGas(frame, 50n);
if (error) {
  console.log(error.type);       // "OutOfGas"
  console.log(frame.gasRemaining); // 0n
}
```

## Memory Operations

### writeMemory

Write a byte to memory. Memory expands in 32-byte words.

```typescript theme={null}
import { Frame, writeMemory } from 'voltaire/evm/Frame';

const frame = Frame();
writeMemory(frame, 0, 0xde);
writeMemory(frame, 1, 0xad);
writeMemory(frame, 2, 0xbe);
writeMemory(frame, 3, 0xef);

console.log(frame.memorySize); // 32 (word-aligned)
```

### readMemory

Read a byte from memory. Uninitialized memory returns 0.

```typescript theme={null}
import { Frame, readMemory, writeMemory } from 'voltaire/evm/Frame';

const frame = Frame();
writeMemory(frame, 100, 0xff);

console.log(readMemory(frame, 100)); // 255 (0xff)
console.log(readMemory(frame, 0));   // 0 (uninitialized)
```

### memoryExpansionCost

Calculate gas cost for memory expansion.

```typescript theme={null}
import { Frame, memoryExpansionCost, consumeGas, writeMemory } from 'voltaire/evm/Frame';

const frame = Frame({ gas: 1000n });

// Calculate cost before expanding
const cost = memoryExpansionCost(frame, 64);
consumeGas(frame, cost);

// Now safe to write
writeMemory(frame, 63, 0xff);
```

Memory cost formula: `3n + n²/512` where n is word count. This quadratic growth prevents memory DoS attacks.

## Error Types

```typescript theme={null}
type EvmError =
  | { type: "StackOverflow" }      // Stack exceeds 1024 items
  | { type: "StackUnderflow" }     // Pop/peek from empty stack
  | { type: "OutOfGas" }           // Insufficient gas
  | { type: "OutOfBounds" }        // Invalid memory access
  | { type: "InvalidJump" }        // Jump to non-JUMPDEST
  | { type: "InvalidOpcode" }      // Unknown opcode
  | { type: "RevertExecuted" }     // REVERT opcode executed
  | { type: "CallDepthExceeded" }  // Call depth > 1024
  | { type: "WriteProtection" }    // State modification in STATICCALL
  | { type: "InsufficientBalance" }
  | { type: "NotImplemented"; message: string };
```

## Arithmetic Methods

Frames include bound arithmetic methods for opcodes 0x01-0x0b:

```typescript theme={null}
const frame = Frame();
pushStack(frame, 10n);
pushStack(frame, 20n);

const error = frame.add();  // Stack: [30n]

// Available methods:
// frame.add(), frame.mul(), frame.sub(), frame.div(), frame.sdiv()
// frame.mod(), frame.smod(), frame.addmod(), frame.mulmod()
// frame.exp(), frame.signextend()
```

## Complete Example

```typescript theme={null}
import { Frame, pushStack, popStack, consumeGas, writeMemory, readMemory } from 'voltaire/evm/Frame';
import { Address } from 'voltaire/primitives/Address';

// Simulate ADD opcode execution
const frame = Frame({
  bytecode: new Uint8Array([0x60, 0x0a, 0x60, 0x14, 0x01]), // PUSH1 10, PUSH1 20, ADD
  gas: 21000n,
  caller: Address("0x1111111111111111111111111111111111111111"),
  address: Address("0x2222222222222222222222222222222222222222"),
});

// PUSH1 10 (gas: 3)
consumeGas(frame, 3n);
pushStack(frame, 10n);
frame.pc += 2;

// PUSH1 20 (gas: 3)
consumeGas(frame, 3n);
pushStack(frame, 20n);
frame.pc += 2;

// ADD (gas: 3)
consumeGas(frame, 3n);
const error = frame.add();
frame.pc += 1;

// Result
const result = popStack(frame);
console.log(result.value);        // 30n
console.log(frame.gasRemaining);  // 20991n
```

## API Reference

| Function                               | Description                |
| -------------------------------------- | -------------------------- |
| `Frame(params?)`                       | Create new execution frame |
| `pushStack(frame, value)`              | Push bigint onto stack     |
| `popStack(frame)`                      | Pop and return top value   |
| `peekStack(frame, index)`              | Read value at depth index  |
| `consumeGas(frame, amount)`            | Deduct gas from frame      |
| `readMemory(frame, offset)`            | Read byte from memory      |
| `writeMemory(frame, offset, value)`    | Write byte to memory       |
| `memoryExpansionCost(frame, endBytes)` | Calculate expansion gas    |

## Related

* [EVM Types](/evm/types) - Complete type reference
* [Instructions](/evm/instructions) - Opcode implementations
* [Gas Constants](/primitives/gas-constants) - Gas cost definitions
