This page is a placeholder. All examples on this page are currently AI-generated and are not correct. This documentation will be completed in the future with accurate, tested examples.
Overview
Opcode: 0x8E
Introduced: Frontier (EVM genesis)
DUP15 duplicates the 15th stack item and pushes it to the top of the stack. The original 15th item remains in place.
Specification
Stack Input:
[..., value, item14, ..., item1]
Stack Output:
[..., value, item14, ..., item1, value]
Gas Cost: 3 (GasFastestStep)
Operation:
value = stack[depth - 15]
stack.push(value)
Behavior
DUP15 copies the 15th-from-top stack item without removing it. Requires stack depth ≥ 15.
Key characteristics:
- Requires stack depth ≥ 15
- Original value unchanged
- New copy pushed to top
- StackUnderflow if depth < 15
- Stack depth increases by 1
Examples
Basic Usage
import { handler_0x8E_DUP15 } from '@tevm/voltaire/evm/stack/handlers';
import { createFrame } from '@tevm/voltaire/evm/Frame';
// Duplicate 15th item
const frame = createFrame({
stack: [1500n, 1400n, 1300n, 1200n, 1100n, 1000n, 900n, 800n, 700n, 600n, 500n, 400n, 300n, 200n, 100n],
gasRemaining: 1000n
});
const err = handler_0x8E_DUP15(frame);
console.log(frame.stack); // [1500n, 1400n, 1300n, 1200n, 1100n, 1000n, 900n, 800n, 700n, 600n, 500n, 400n, 300n, 200n, 100n, 100n] - 15th item duplicated
console.log(frame.gasRemaining); // 997n (3 gas consumed)
Solidity Compilation
contract Example {
function deepAccess() public pure {
// Access deep stack value
assembly {
// Stack has 15 items
dup15 // Duplicate 15th item to top
}
}
}
Assembly Usage
assembly {
push1 0x01
push1 0x02
push1 0x03
push1 0x04
push1 0x05
push1 0x06
push1 0x07
push1 0x08
push1 0x09
push1 0x0a
push1 0x0b
push1 0x0c
push1 0x0d
push1 0x0e
push1 0x0f
// Stack: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]
dup15
// Stack: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x01] - first item duplicated
}
Gas Cost
Cost: 3 gas (GasFastestStep)
All DUP1-16 operations cost the same despite different stack depths accessed.
Comparison:
| Operation | Gas | Note |
|---|
| DUP15 | 3 | Duplicate 15th item |
| PUSH1-32 | 3 | Same cost tier |
| POP | 2 | Cheaper |
Common Usage
Deep Stack Access
function complex() public pure {
assembly {
// Build deep stack
let v1 := 1
let v2 := 2
let v3 := 3
let v4 := 4
let v5 := 5
let v6 := 6
let v7 := 7
let v8 := 8
let v9 := 9
let v10 := 10
let v11 := 11
let v12 := 12
let v13 := 13
let v14 := 14
let v15 := 15
// Access v1 from depth 15
dup15
}
}```
### Efficient Copies
```solidity
// Instead of multiple loads
assembly {
let value := sload(slot) // Expensive
// Use value
let value2 := sload(slot) // Wasteful!
}
// Use DUP to reuse
assembly {
let value := sload(slot) // Load once
dup1 // Copy
// Use both copies
}
Conditional Logic
assembly {
let condition := calldataload(0)
dup1 // Keep condition for later
iszero
jumpi(skip)
// Use condition again
skip:
}
Stack Depth Requirements
Minimum Depth
// DUP15 requires 15 items on stack
assembly {
push1 0x01
push1 0x02
push1 0x03
push1 0x04
push1 0x05
push1 0x06
push1 0x07
push1 0x08
push1 0x09
push1 0x0a
push1 0x0b
push1 0x0c
push1 0x0d
push1 0x0e
// Only 14 items - DUP15 will fail!
dup15 // StackUnderflow
}
Safe Usage
assembly {
push1 0x01
push1 0x02
push1 0x03
push1 0x04
push1 0x05
push1 0x06
push1 0x07
push1 0x08
push1 0x09
push1 0x0a
push1 0x0b
push1 0x0c
push1 0x0d
push1 0x0e
push1 0x0f
// Exactly 15 items - safe
dup15 // Success
}
Implementation
/**
* DUP15 opcode (0x8E) - Duplicate 15th stack item
*
* Stack: [..., value, ...] => [..., value, ..., value]
* Gas: 3 (GasFastestStep)
*/
export function handler_0x8E_DUP15(frame: FrameType): EvmError | null {
const gasErr = consumeGas(frame, FastestStep);
if (gasErr) return gasErr;
if (frame.stack.length < 15) {
return { type: "StackUnderflow" };
}
const value = frame.stack[frame.stack.length - 15];
const pushErr = pushStack(frame, value);
if (pushErr) return pushErr;
frame.pc += 1;
return null;
}
Edge Cases
Stack Underflow
// Insufficient stack depth
const frame = createFrame({
stack: [100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n] // Only 14 items
});
const err = handler_0x8E_DUP15(frame);
console.log(err); // { type: "StackUnderflow" }
Stack Overflow
// Stack at maximum, can't add more
const frame = createFrame({
stack: new Array(1024).fill(0n)
});
const err = handler_0x8E_DUP15(frame);
console.log(err); // { type: "StackOverflow" }
Out of Gas
// Insufficient gas
const frame = createFrame({
stack: [100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n, 100n],
gasRemaining: 2n // Need 3
});
const err = handler_0x8E_DUP15(frame);
console.log(err); // { type: "OutOfGas" }
Maximum Value
// Duplicate max uint256
const MAX = (1n << 256n) - 1n;
const frame = createFrame({
stack: [0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, MAX]
});
handler_0x8E_DUP15(frame);
console.log(frame.stack[frame.stack.length - 1]); // MAX (duplicated)
References