Skip to content

Commit

Permalink
Typify Solidity Types
Browse files Browse the repository at this point in the history
  • Loading branch information
acuarica committed Apr 6, 2023
1 parent efbb7e6 commit 0477a4b
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 6 deletions.
21 changes: 19 additions & 2 deletions src/evm/expr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,27 @@ import type { MappingLoad, MappingStore, SLoad, SStore } from './storage';
import type { State } from '../state';
import type { Opcode } from '../opcode';

export type SizeN<N extends number, T extends number[]> = T['length'] extends N
? T[number]
: SizeN<N, [AsNumber<Plus<T[0], T[-1]>>, ...T]>;

export type Bits = SizeN<32, [8]>;

export type Bytes = SizeN<32, [1]>;

/**
* https://docs.soliditylang.org/en/v0.8.17/types.html
*/
export type Type = 'address' | 'address payable' | 'uint256';
export type Type =
| 'address'
| 'address payable'
| 'bool'
| `uint`
| `uint${Bits}`
| `int`
| `int${Bits}`
| `bytes`
| `bytes${Bytes}`;

/**
*
Expand Down Expand Up @@ -126,7 +143,7 @@ export function Tag<N extends string>(tag: N, prec: number = Val.prec) {

static readonly prec = prec;

type?: string;
type?: Type;

isVal(): this is Val {
return this.tag === 'Val';
Expand Down
2 changes: 1 addition & 1 deletion src/evm/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class Call extends Tag('Call') {

export class ReturnData extends Tag('ReturnData') {
readonly name = 'ReturnData';
override readonly type?: string;
override readonly type = 'bytes';
readonly wrapped = false;

constructor(readonly retOffset: any, readonly retSize: any) {
Expand Down
17 changes: 17 additions & 0 deletions src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,20 @@ export declare global {
fromEntries<K extends string, V>(entries: Iterable<readonly [K, V]>): { [k in K]: V };
}
}

declare global {
/**
* https://github.com/microsoft/TypeScript/pull/45711
*
* https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
*/
type Len<T extends readonly unknown[]> = T extends { length: infer L } ? L : never;

type Tuple<L extends number, T extends readonly unknown[] = []> = T extends { length: L }
? T
: Tuple<L, [...T, unknown]>;

type Plus<A extends number, B extends number> = Len<[...Tuple<A>, ...Tuple<B>]>;

type AsNumber<T> = T extends number ? T : never;
}
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Expr, type Inst, Throw, type Val } from './evm/expr';
import { type Expr, type Inst, Throw, type Val, type Type } from './evm/expr';
import { Not } from './evm/logic';
import type { Return, Revert } from './evm/system';
import { State } from './state';
Expand Down Expand Up @@ -304,7 +304,7 @@ export class PublicFunction {
this.stmts.forEach(stmt =>
PublicFunction.patchCallDataLoad(
stmt as unknown as Record<string, Expr>,
paramTypes
paramTypes as Type[]
)
);
}
Expand Down Expand Up @@ -346,7 +346,7 @@ export class PublicFunction {
}
}

private static patchCallDataLoad(stmtOrExpr: Record<string, Expr>, paramTypes: string[]) {
private static patchCallDataLoad(stmtOrExpr: Record<string, Expr>, paramTypes: Type[]) {
for (const propKey in stmtOrExpr) {
if (propKey === 'mappings') continue;

Expand Down

0 comments on commit 0477a4b

Please sign in to comment.