sevm
Version:
A Symbolic Ethereum Virtual Machine (EVM) bytecode decompiler & analyzer library & CLI
230 lines • 7.28 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SelfDestruct = exports.Invalid = exports.Revert = exports.Return = exports.Stop = exports.DelegateCall = exports.StaticCall = exports.Create2 = exports.CallCode = exports.ReturnData = exports.Call = exports.Create = exports.Sha3 = void 0;
const _1 = require(".");
function info(...args) {
return [
Math.max(...args.map(e => e.depth)) + 1,
(args?.reduce((accum, curr) => accum + curr.count, 0) ?? 0) + 1
];
}
class Sha3 extends _1.Tag {
constructor(offset, size, args) {
super(...info(offset, size, ...args ?? []));
this.offset = offset;
this.size = size;
this.args = args;
this.tag = 'Sha3';
}
eval() {
return new Sha3(this.offset.eval(), this.size.eval(), this.args?.map(_1.evalE));
}
children() {
return [...super.children(), ...this.args ?? []];
}
}
exports.Sha3 = Sha3;
class Create extends _1.Tag {
/**
* Creates a new account with associated code.
*
* @param value Value in _wei_ to send to the new account.
* @param offset Byte offset in the memory in bytes, the initialisation code for the new account.
* @param size Byte size to copy (size of the initialisation code).
* @param bytecode
*/
constructor(value, offset, size, bytecode = null) {
super(...info(value, offset, size));
this.value = value;
this.offset = offset;
this.size = size;
this.bytecode = bytecode;
this.tag = 'Create';
this.type = 'address';
}
eval() {
return new Create(this.value.eval(), this.offset.eval(), this.size.eval(), this.bytecode);
}
}
exports.Create = Create;
class Call extends _1.Tag {
constructor(gas, address, value, argsStart, argsLen, retStart, retLen) {
super(...info(gas, address, value, argsStart, argsLen, retStart, retLen));
this.gas = gas;
this.address = address;
this.value = value;
this.argsStart = argsStart;
this.argsLen = argsLen;
this.retStart = retStart;
this.retLen = retLen;
this.tag = 'Call';
this.throwOnFail = false;
}
eval() {
return this;
}
}
exports.Call = Call;
class ReturnData extends _1.Tag {
constructor(retOffset, retSize) {
super(...info(retOffset, retSize));
this.retOffset = retOffset;
this.retSize = retSize;
this.tag = 'ReturnData';
this.type = 'bytes';
this.wrapped = false;
}
eval() {
return this;
}
}
exports.ReturnData = ReturnData;
class CallCode extends _1.Tag {
constructor(gas, address, value, memoryStart, memoryLength, outputStart, outputLength) {
super(...info(gas, address, value, memoryStart, memoryLength, outputStart, outputLength));
this.gas = gas;
this.address = address;
this.value = value;
this.memoryStart = memoryStart;
this.memoryLength = memoryLength;
this.outputStart = outputStart;
this.outputLength = outputLength;
this.tag = 'CallCode';
}
eval() {
return this;
}
}
exports.CallCode = CallCode;
class Create2 extends _1.Tag {
constructor(offset, size, value) {
super(...info(offset, size, value));
this.offset = offset;
this.size = size;
this.value = value;
this.tag = 'Create2';
}
eval() {
return this;
}
}
exports.Create2 = Create2;
class StaticCall extends _1.Tag {
constructor(gas, address, memoryStart, memoryLength, outputStart, outputLength) {
super(...info(gas, address, memoryStart, memoryLength, outputStart, outputLength));
this.gas = gas;
this.address = address;
this.memoryStart = memoryStart;
this.memoryLength = memoryLength;
this.outputStart = outputStart;
this.outputLength = outputLength;
this.tag = 'StaticCall';
}
eval() {
return this;
}
}
exports.StaticCall = StaticCall;
class DelegateCall extends _1.Tag {
constructor(gas, address, memoryStart, memoryLength, outputStart, outputLength) {
super(...info(gas, address, memoryStart, memoryLength, outputStart, outputLength));
this.gas = gas;
this.address = address;
this.memoryStart = memoryStart;
this.memoryLength = memoryLength;
this.outputStart = outputStart;
this.outputLength = outputLength;
this.tag = 'DelegateCall';
}
eval() {
return this;
}
}
exports.DelegateCall = DelegateCall;
class Stop {
constructor() {
this.name = 'Stop';
}
eval() {
return this;
}
}
exports.Stop = Stop;
class Return {
/**
* Exits the current context successfully.
*
* @param offset Byte offset in the memory in bytes, to copy what will be the return data of this context.
* @param size Byte size to copy (size of the return data).
* @param args
*/
constructor(offset, size, args) {
this.offset = offset;
this.size = size;
this.args = args;
this.name = 'Return';
}
eval() {
return new Return(this.offset.eval(), this.size.eval(), this.args?.map(_1.evalE));
}
}
exports.Return = Return;
class Revert {
/**
* Stop the current context execution, revert the state changes (see `STATICCALL` for a list
* of state changing opcodes) and return the unused gas to the caller.
*
* It also reverts the gas refund to its value before the current context.
* If the execution is stopped with `REVERT`, the value 0 is put on the stack of the calling context,
* which continues to execute normally.
* The return data of the calling context is set as the given chunk of memory of this context.
*
* @param offset byte offset in the memory in bytes. The return data of the calling context.
* @param size byte size to copy (size of the return data).
* @param args
*/
constructor(offset, size, selector, sig, args) {
this.offset = offset;
this.size = size;
this.selector = selector;
this.sig = sig;
this.args = args;
this.name = 'Revert';
}
eval() {
return new Revert(this.offset.eval(), this.size.eval(), this.selector, this.sig, this.args?.map(_1.evalE));
}
/**
* https://docs.soliditylang.org/en/latest/control-structures.html#panic-via-assert-and-error-via-require
*/
static isRequireOrAssert(selector) {
return selector === undefined || selector === Revert.ERROR || selector === Revert.PANIC;
}
isRequireOrAssert() {
return Revert.isRequireOrAssert(this.selector);
}
}
exports.Revert = Revert;
Revert.ERROR = '08c379a0';
Revert.PANIC = '4e487b71';
class Invalid {
constructor(opcode) {
this.opcode = opcode;
this.name = 'Invalid';
}
eval() {
return this;
}
}
exports.Invalid = Invalid;
class SelfDestruct {
constructor(address) {
this.address = address;
this.name = 'SelfDestruct';
}
eval() {
return this;
}
}
exports.SelfDestruct = SelfDestruct;
//# sourceMappingURL=system.js.map