Skip to content

Commit

Permalink
🚨 Reenable 4byte tests and remove blessed from bin
Browse files Browse the repository at this point in the history
  • Loading branch information
acuarica committed Nov 30, 2023
1 parent b8c9db1 commit 7021d46
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 216 deletions.
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/dist/
/docs/tsdoc/
/.eslintrc.js
/.eslintrc.js
/4byte/functionHashes.min.js
/4byte/eventHashes.min.js
6 changes: 6 additions & 0 deletions 4byte/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/**
* This module provides a fair database of selectors for both functions and events.
*
Expand All @@ -10,8 +11,11 @@
*
* @packageDocumentation
*/
/* eslint-env node */

const { Contract } = require('sevm');

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore to avoid `has no default export` due to module's size
const functionHashes = require('./functionHashes.min.js');
const eventHashes = require('./eventHashes.min.js');

Check failure on line 21 in 4byte/index.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18)

Cannot find module './eventHashes.min.js' or its corresponding type declarations.

Check failure on line 21 in 4byte/index.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20)

Cannot find module './eventHashes.min.js' or its corresponding type declarations.
Expand All @@ -29,6 +33,8 @@ function patch(contract) {

for (const [selector, fn] of Object.entries(contract.functions)) {
if (selector in functionHashes) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
fn.label = functionHashes[selector];
}
}
Expand Down
165 changes: 10 additions & 155 deletions bin/sevm.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { EtherscanProvider } from 'ethers';
import envPaths from 'env-paths';
import path from 'path';

import { Contract, EVM, formatOpcode, solStmts, toHex } from 'sevm';
import { Contract, EVM, formatOpcode, toHex } from 'sevm';
import 'sevm/4byte';

const paths = envPaths('sevm');
Expand Down Expand Up @@ -182,12 +182,6 @@ void yargs(process.argv.slice(2))
pos,
make(decompile)
)
.command(
'console <contract>',
'Opens the interactive viewer to inspect bytecode',
pos,
make(show)
)
.command('config', 'Shows cache path used to store downloaded bytecode', {}, () =>
console.info(paths.cache)
)
Expand Down Expand Up @@ -355,152 +349,13 @@ function cfg(contract) {
// }
// }

/**
*
* @param {Contract} contract
*/
function show(contract) {
const screen = blessed.screen({ smartCSR: true });
screen.title = 'my window title';

const box = blessed.box({
parent: screen,
// top: 'center',
// left: 'center',
right: 0,
width: '80%',
// height: '50%',
content: 'Hello {bold}world{/bold}!',
tags: true,
border: {
type: 'line',
},
style: {
fg: 'white',
// bg: 'magenta',
border: {
fg: '#f0f0f0',
},
// hover: {
// bg: 'green'
// }
},
});

// Append our box to the screen.
// screen.append(box);

// If our box is clicked, change the content.
// box.on('click', function (data) {
// box.setContent('{center}Some different {red-fg}content{/red-fg}.{/center}');
// screen.render();
// });

// If box is focused, handle `enter`/`return` and give us some more content.
// box.key('enter', function (ch, key) {
// box.setContent('{right}Even different {black-fg}content{/black-fg}.{/right}\n');
// box.setLine(1, 'bar');
// box.insertLine(1, 'foo');
// screen.render();
// });

// Quit on Escape, q, or Control-C.
screen.key(['escape', 'q', 'C-c'], function (_ch, _key) {
return process.exit(0);
});

blessed.box({
parent: screen,
label: ' {bold}{cyan-fg}Metadata{/cyan-fg}{/bold} ',
width: '20%',
height: '20%',
content: getMetadata(contract.metadata),
tags: true,
border: {
type: 'line',
},
style: {
fg: 'white',
border: {
fg: '#f0f0f0',
},
},
});

const functionList = blessed.list({
parent: screen,
label: ' {bold}{cyan-fg}Functions{/cyan-fg}{/bold} ',
tags: true,
top: '20%',
width: '20%',
height: '40%',
keys: true,
vi: true,
// mouse: true,
border: 'line',
scrollbar: {
ch: ' ',
track: {
bg: 'cyan',
},
style: {
inverse: true,
},
},
style: {
item: {
hover: {
bg: 'blue',
},
},
selected: {
bg: 'blue',
bold: true,
},
},
search: function (_callback) {
// prompt.input('Search:', '', function (err, value) {
// if (err) return;
// return callback(null, value);
// });
},
});
functionList.on('select item', elem => {
const fn = fns[elem.getText()];
box.setContent(fn.decompile());
screen.render();
});
// const entries = [
// /** @type {const} */ (['main', { decompile: () => solStmts(contract.main) }]),
// ...Object.entries(contract.functions).map(
// ([selector, fn]) => /**@type{const}*/ ([fn.label ?? selector, fn])
// ),
// ];
// const fns = Object.fromEntries(entries);
// functionList.setItems(Object.keys(fns));

const entries = [
/** @type {const} */ (['main', { decompile: () => solStmts(contract.main) }]),
...Object.entries(contract.functions).map(
([selector, fn]) => /**@type{const}*/ ([fn.label ?? selector, fn])
),
];
const fns = Object.fromEntries(entries);
functionList.setItems(Object.keys(fns));

const eventList = blessed.list({
parent: screen,
label: ' {bold}{cyan-fg}Events{/cyan-fg}{/bold} ',
tags: true,
bottom: 0,
width: '20%',
height: '40%',
keys: true,
vi: true,
border: 'line',
});
eventList.setItems(contract.getEvents());

functionList.focus();
screen.render();
}

/**
*
* @param {EVM['metadata']} metadata
*/
function getMetadata(metadata) {
return metadata ? `solc ${metadata.solc} ${metadata.url}` : '--';
}
// eventList.setItems(contract.getEvents());
61 changes: 20 additions & 41 deletions test/etherscan.smoke.js → test/etherscan.smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { expect } from 'chai';
import c from 'ansi-colors';
import { CloudflareProvider, EtherscanProvider, InfuraProvider, PocketProvider } from 'ethers';

import { Contract, ERCIds, sol } from 'sevm';
import { STEP } from 'sevm';
import { Contract, ERCIds, sol, type State, STEP } from 'sevm';
import type { Expr, Inst, StaticCall, Throw } from 'sevm/ast';
import 'sevm-4byte';

/**
Expand Down Expand Up @@ -36,11 +36,7 @@ const provider = {
new PocketProvider(),
],
current: 0,
/**
* @param {string} address
* @returns {Promise<string>}
*/
getCode: async function (address) {
getCode: async function (address: string): Promise<string> {
this.current = (this.current + 1) % this.providers.length;
const code = await this.providers[this.current].getCode(address);
return code;
Expand All @@ -60,20 +56,19 @@ describe(`etherscan | MAX=\`${MAX ?? ''}\` CONTRACT=\`${CONTRACT}\``, function (
*/
csv = readFileSync(csvPath);
} catch {
it.skip(`Addresses CSV \`${csvPath}\` not found, skipping`, () => {});
it.skip(`Addresses CSV \`${csvPath}\` not found, skipping`, function () {
/**/
});
return;
}

/** @type {Map<string, import('sevm/ast').Throw[]>} */
const errorsByContract = new Map();
const errorsByContract: Map<string, Throw[]> = new Map();
const metadataStats = new (class {
noMetadata = 0;
/** @type {Set<string>} */
protocols = new Set();
protocols: Set<string> = new Set();
solcs = new Set();

/** @param {Contract['metadata']} metadata */
append(metadata) {
append(metadata: Contract['metadata']) {
if (metadata) {
this.protocols.add(metadata.protocol);
this.solcs.add(metadata.solc);
Expand All @@ -84,15 +79,10 @@ describe(`etherscan | MAX=\`${MAX ?? ''}\` CONTRACT=\`${CONTRACT}\``, function (
})();

const selectorStats = new (class {
/** @type {Set<string>} */
hitSelectors = new Set();
/** @type {Set<string>} */
missedSelectors = new Set();
hitSelectors = new Set<string>();
missedSelectors = new Set<string>();

/**
* @param {Contract['functions']} functions
*/
append(functions) {
append(functions: Contract['functions']) {
for (const fn of Object.values(functions)) {
(fn.label !== undefined ? this.hitSelectors : this.missedSelectors).add(
fn.selector
Expand All @@ -102,13 +92,9 @@ describe(`etherscan | MAX=\`${MAX ?? ''}\` CONTRACT=\`${CONTRACT}\``, function (
})();

const ercsStats = new (class {
/** @type {Map<(typeof ERCIds)[number], number>} */
counts = new Map();
counts = new Map<(typeof ERCIds)[number], number>();

/**
* @param {Contract} contract
*/
append(contract) {
append(contract: Contract) {
for (const erc of ERCIds) {
if (contract.isERC(erc)) {
const count = this.counts.get(erc) ?? 0;
Expand All @@ -122,10 +108,7 @@ describe(`etherscan | MAX=\`${MAX ?? ''}\` CONTRACT=\`${CONTRACT}\``, function (
count = 0;
total = 0n;

/**
* @param {bigint} diff
*/
append(diff) {
append(diff: bigint) {
this.count++;
this.total += diff;
}
Expand All @@ -136,13 +119,9 @@ describe(`etherscan | MAX=\`${MAX ?? ''}\` CONTRACT=\`${CONTRACT}\``, function (
})();

const precompiledStats = new (class {
/** @type {Map<string, number>} */
counts = new Map();
counts = new Map<string, number>();

/**
* @param {string} address
*/
append(address) {
append(address: string) {
const count = this.counts.get(address) ?? 0;
this.counts.set(address, count + 1);
}
Expand All @@ -168,7 +147,7 @@ describe(`etherscan | MAX=\`${MAX ?? ''}\` CONTRACT=\`${CONTRACT}\``, function (
writeFileSync(path, code);
} catch (err) {
console.info(
error(/**@type{{ message: string }}*/ (err).message),
error((err as { message: string }).message),
provider.providers[provider.current]
);
}
Expand All @@ -181,9 +160,9 @@ describe(`etherscan | MAX=\`${MAX ?? ''}\` CONTRACT=\`${CONTRACT}\``, function (

const step = STEP();
/** @param {import('sevm').State<import('sevm/ast').Inst, import('sevm/ast').Expr>} state */
const STATICCALL = state => {
const STATICCALL = (state: State<Inst, Expr>) => {
step['STATICCALL'](state);
const call = /** @type {import('sevm/ast').StaticCall}*/ (state.stack.top);
const call = state.stack.top as StaticCall;
const address = call.address.eval();
if (address.tag === 'Val' && address.val <= 9n) {
precompiledStats.append(sol`${address}`);
Expand Down
Loading

0 comments on commit 7021d46

Please sign in to comment.