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: 0x8F
Introduced: Frontier (EVM genesis)
DUP16 duplicates the 16th stack item and pushes it to the top of the stack. The original 16th item remains in place.
Specification
Stack Input:
[..., value, item15, ..., item1]
Stack Output:
[..., value, item15, ..., item1, value]
Gas Cost: 3 (GasFastestStep)
Operation:
value = stack[depth - 16]
stack.push(value)
Behavior
DUP16 copies the 16th-from-top stack item without removing it. Requires stack depth ≥ 16.
Key characteristics:
- Requires stack depth ≥ 16
- Original value unchanged
- New copy pushed to top
- StackUnderflow if depth < 16
- Stack depth increases by 1
Examples
Basic Usage
import { handler_0x8F_DUP16 } from '@tevm/voltaire/evm/stack/handlers';
import { createFrame } from '@tevm/voltaire/evm/Frame';
// Duplicate 16th item
const frame = createFrame({
stack: [1600n, 1500n, 1400n, 1300n, 1200n, 1100n, 1000n, 900n, 800n, 700n, 600n, 500n, 400n, 300n, 200n, 100n],
gasRemaining: 1000n
});
const err = handler_0x8F_DUP16(frame);
console.log(frame.stack); // [1600n, 1500n, 1400n, 1300n, 1200n, 1100n, 1000n, 900n, 800n, 700n, 600n, 500n, 400n, 300n, 200n, 100n, 100n] - 16th 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 16 items
dup16 // Duplicate 16th 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
push1 0x10
// Stack: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10]
dup16
// Stack: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 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 |
|---|
| DUP16 | 3 | Duplicate 16th 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
let v16 := 16
// Access v1 from depth 16
dup16
}
}```
### 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
// DUP16 requires 16 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
push1 0x0f
// Only 15 items - DUP16 will fail!
dup16 // 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
push1 0x10
// Exactly 16 items - safe
dup16 // Success
}
Implementation
/**
* DUP16 opcode (0x8F) - Duplicate 16th stack item
*
* Stack: [..., value, ...] => [..., value, ..., value]
* Gas: 3 (GasFastestStep)
*/
export function handler_0x8F_DUP16(frame: FrameType): EvmError | null {
const gasErr = consumeGas(frame, FastestStep);
if (gasErr) return gasErr;
if (frame.stack.length < 16) {
return { type: "StackUnderflow" };
}
const value = frame.stack[frame.stack.length - 16];
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, 100n] // Only 15 items
});
const err = handler_0x8F_DUP16(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_0x8F_DUP16(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, 100n],
gasRemaining: 2n // Need 3
});
const err = handler_0x8F_DUP16(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, 0n, MAX]
});
handler_0x8F_DUP16(frame);
console.log(frame.stack[frame.stack.length - 1]); // MAX (duplicated)
References