import { describe, it, expect } from 'vitest';
import { sload } from './0x54_SLOAD.js';
import { createFrame } from '../../Frame/index.js';
import { createMemoryHost } from '../../Host/createMemoryHost.js';
import { from as addressFrom } from '../../../primitives/Address/index.js';
describe('SLOAD (0x54)', () => {
it('loads value from storage', () => {
const host = createMemoryHost();
const addr = addressFrom("0x1234567890123456789012345678901234567890");
host.setStorage(addr, 0x42n, 0x1337n);
const frame = createFrame({
stack: [0x42n],
gasRemaining: 10000n,
address: addr,
});
expect(sload(frame, host)).toBeNull();
expect(frame.stack).toEqual([0x1337n]);
expect(frame.pc).toBe(1);
});
it('loads zero for uninitialized storage', () => {
const host = createMemoryHost();
const addr = addressFrom("0x1234567890123456789012345678901234567890");
const frame = createFrame({
stack: [0xFFFFFFFFFn],
gasRemaining: 10000n,
address: addr,
});
expect(sload(frame, host)).toBeNull();
expect(frame.stack).toEqual([0n]);
});
it('isolates storage by address', () => {
const host = createMemoryHost();
const addr1 = addressFrom("0x1111111111111111111111111111111111111111");
const addr2 = addressFrom("0x2222222222222222222222222222222222222222");
host.setStorage(addr1, 0x42n, 0xAAAAn);
host.setStorage(addr2, 0x42n, 0xBBBBn);
let frame = createFrame({
stack: [0x42n],
gasRemaining: 10000n,
address: addr1,
});
expect(sload(frame, host)).toBeNull();
expect(frame.stack).toEqual([0xAAAAn]);
frame = createFrame({
stack: [0x42n],
gasRemaining: 10000n,
address: addr2,
});
expect(sload(frame, host)).toBeNull();
expect(frame.stack).toEqual([0xBBBBn]);
});
it('consumes 2100 gas on cold access', () => {
const host = createMemoryHost();
const addr = addressFrom("0x1234567890123456789012345678901234567890");
host.setStorage(addr, 0x42n, 0x1337n);
const frame = createFrame({
stack: [0x42n],
gasRemaining: 5000n,
address: addr,
});
expect(sload(frame, host)).toBeNull();
expect(frame.gasRemaining).toBe(2900n); // 5000 - 2100
});
it('returns StackUnderflow on empty stack', () => {
const host = createMemoryHost();
const frame = createFrame({
stack: [],
gasRemaining: 10000n,
address: addressFrom("0x1111111111111111111111111111111111111111"),
});
expect(sload(frame, host)).toEqual({ type: "StackUnderflow" });
});
it('returns OutOfGas when insufficient gas', () => {
const host = createMemoryHost();
const frame = createFrame({
stack: [0x42n],
gasRemaining: 50n,
address: addressFrom("0x1111111111111111111111111111111111111111"),
});
expect(sload(frame, host)).toEqual({ type: "OutOfGas" });
});
it('returns StackOverflow when stack full', () => {
const host = createMemoryHost();
const fullStack = new Array(1024).fill(0n);
const frame = createFrame({
stack: fullStack,
gasRemaining: 10000n,
address: addressFrom("0x1111111111111111111111111111111111111111"),
});
expect(sload(frame, host)).toEqual({ type: "StackOverflow" });
});
});