sevm
Version:
A Symbolic Ethereum Virtual Machine (EVM) bytecode decompiler & analyzer library & CLI
112 lines • 3.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CallDataLoad = exports.CallValue = exports.DataCopy = exports.Fn = exports.FNS = exports.Props = exports.Prop = void 0;
const _1 = require(".");
/**
* Represents a global Solidity built-in property.
*
* @see https://docs.soliditylang.org/en/develop/units-and-global-variables.html#special-variables-and-functions
*/
class Prop extends _1.Tag {
constructor(symbol, type) {
super(0, 1);
this.symbol = symbol;
this.type = type;
this.tag = 'Prop';
}
eval() {
return this;
}
}
exports.Prop = Prop;
const prop = (prop) => [prop[0], new Prop(prop[0], prop[1])];
const applyPrefix = (props, obj) => props.map(([field, type]) => [`${obj}.${field}`, type]);
/**
* A collection of _Block and Transaction Properties_ defined as `Prop`.
*
* @see https://docs.soliditylang.org/en/develop/units-and-global-variables.html#block-and-transaction-properties
* @see {@link Prop}
*/
exports.Props = Object.assign(Object.fromEntries([
['address(this)', 'address'],
['codesize()', 'uint'],
['returndatasize()', 'uint'],
['address(this).balance', 'uint'],
['gasleft()', 'uint'],
].map(prop)), Object.fromEntries(applyPrefix([
['basefee', 'uint'],
['coinbase', 'address payable'],
['timestamp', 'uint'],
['number', 'uint'],
['difficulty', 'uint'],
['gaslimit', 'uint'],
['chainid', 'uint'],
['prevrandao', 'uint'],
], 'block').map(prop)), Object.fromEntries(applyPrefix([
['sender', 'address'],
['data.length', 'uint'],
], 'msg').map(prop)), Object.fromEntries(applyPrefix([
['origin', 'address'],
['gasprice', 'uint'],
], 'tx').map(prop)));
exports.FNS = {
BALANCE: [(address) => `${address}.balance`, 'uint256', 0x31],
EXTCODESIZE: [(address) => `address(${address}).code.length`, 'uint256', 0x3b],
EXTCODEHASH: [(address) => `keccak256(address(${address}).code)`, 'bytes32', 0x3f],
BLOCKHASH: [(blockNumber) => `blockhash(${blockNumber})`, 'bytes32', 0x40],
};
class Fn extends _1.Tag {
constructor(mnemonic, value) {
super(value.depth + 1, value.count + 1);
this.mnemonic = mnemonic;
this.value = value;
this.tag = 'Fn';
this.type = exports.FNS[mnemonic][1];
}
eval() {
return new Fn(this.mnemonic, this.value.eval());
}
}
exports.Fn = Fn;
class DataCopy extends _1.Tag {
constructor(kind, offset, size, address, bytecode) {
super(Math.max(offset.depth, size.depth, address?.depth ?? 0) + 1, offset.count + size.count + (address?.count ?? 0) + 1);
this.kind = kind;
this.offset = offset;
this.size = size;
this.address = address;
this.bytecode = bytecode;
this.tag = 'DataCopy';
}
eval() {
return this;
}
}
exports.DataCopy = DataCopy;
/**
* Get deposited value by the instruction/transaction responsible for this execution.
*/
class CallValue extends _1.Tag {
constructor() {
super(0, 1);
this.tag = 'CallValue';
}
eval() {
return this;
}
}
exports.CallValue = CallValue;
class CallDataLoad extends _1.Tag {
constructor(location) {
super(location.depth + 1, location.count + 1);
this.location = location;
this.tag = 'CallDataLoad';
}
eval() {
return new CallDataLoad(this.location.eval());
// this.location = this.location.eval();
// return this;
}
}
exports.CallDataLoad = CallDataLoad;
//# sourceMappingURL=special.js.map