Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update oval node to support oval factory deployments #83

Merged
merged 36 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
977b422
feat: oval multi unlocker
md0x Jul 15, 2024
588cd5d
feat: add contract types
md0x Jul 16, 2024
7efa89d
feat: change structure and signatures
md0x Jul 16, 2024
ddfd91e
feat: comments and env var
md0x Jul 16, 2024
87bac83
feat: ci tests
md0x Jul 16, 2024
b3731f7
feat: fix tests
md0x Jul 16, 2024
cb52562
feat: fix tests bis
md0x Jul 16, 2024
9a5c3e2
fix: tests ci
md0x Jul 16, 2024
c092f09
fix: tests ci pkeys
md0x Jul 16, 2024
de05da5
feat: simplify
md0x Jul 16, 2024
ba6590b
feat: remove dep
md0x Jul 16, 2024
c33b1de
feat: init configs
md0x Jul 16, 2024
d66cad8
feat: remove extra type
md0x Jul 16, 2024
0aa2f98
feat: clean tests
md0x Jul 16, 2024
4131b76
feat: oval discovery
md0x Jul 17, 2024
9dfd12e
feat: oval discovery improvements
md0x Jul 17, 2024
9783f18
feat: simplify call
md0x Jul 17, 2024
7d2017b
feat: improve oval discovery initialization
md0x Jul 17, 2024
28ba4fc
feat: data structure wallet manager
md0x Jul 18, 2024
8773050
feat: improve wallet manager selection criteria
md0x Jul 19, 2024
6654052
feat: add log to notify if key used multiple times
md0x Jul 19, 2024
31d21c5
feat: tests use public getWallet
md0x Jul 19, 2024
69b24fb
feat: encode unlock for Permission Proxy
md0x Jul 19, 2024
79fd454
feat: check that sender is correct
md0x Jul 19, 2024
8ab9061
feat: update permission call
md0x Jul 19, 2024
f2fb908
feat: refine comments
md0x Jul 19, 2024
6bb034a
fix: stub permission proxy call
md0x Jul 19, 2024
34679cb
feat: readme
md0x Jul 19, 2024
d814d73
feat: rename function and comments
md0x Jul 23, 2024
5c77377
feat: add try catch
md0x Jul 23, 2024
fee339d
feat: simplify factory update logic
md0x Jul 23, 2024
54d3ed1
Merge branch 'development' into pablo/oval-shared-unlockers
md0x Jul 23, 2024
9ef3966
feat: remove contract types
md0x Jul 31, 2024
5a1c469
feat: ignore contract types
md0x Jul 31, 2024
fe07a88
feat: oval abi
md0x Jul 31, 2024
35bf78e
feat: oval discovery warm up log
md0x Jul 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: "CI"

on:
workflow_dispatch:
pull_request:
push:
branches:
- "master"

jobs:
test:
runs-on: "ubuntu-latest"
steps:
- name: "Check out the repo"
uses: "actions/checkout@v4"

- name: "Install Node.js"
uses: "actions/setup-node@v3"
with:
node-version: "20"

- name: "Install Yarn"
run: "npm install --global yarn"

- name: "Install Node.js dependencies"
run: "yarn install"

- name: "Create .env file"
run: |
echo 'PROVIDER_URL="https://mainnet.infura.io/v3/00000000000000000000000000000000"' > .env
echo 'PROVIDER_WSS="wss://mainnet.infura.io/ws/v3/00000000000000000000000000000000"' >> .env
echo 'FORWARD_URL="https://relay.flashbots.net"' >> .env
echo 'OVAL_CONFIGS="{"0x000000000000000000000000000000000000beef":{"unlockerKey":"0x000000000000000000000000000000000000000000000000000000000000beef","refundAddress":"0x000000000000000000000000000000000000beef","refundPercent":90}}"' >> .env
echo 'AUTH_PRIVATE_KEY="0x0000000000000000000000000000000000000000000000000000000000000000"' >> .env
echo 'MAINNET_BLOCK_OFFSET=5' >> .env

- name: "Run the tests"
run: "yarn test"

- name: "Add test summary"
run: |
echo "## Tests result" >> $GITHUB_STEP_SUMMARY
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
11 changes: 11 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"require": "ts-node/register",
"extension": [
"ts"
],
"spec": "test/**/*.ts",
"watch-files": [
"src/**/*.ts",
"test/**/*.ts"
]
}
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Define a `.env` file and define, at minimum, the following (see [here](./src/lib

```
OVAL_CONFIGS=<oval_configs_json> # JSON string that maps Oval contract addresses to their specific configurations (see below).
OVAL_CONFIGS_SHARED=<oval_configs_shared_json># JSON string for shared unlocker configurations (see below).
OVAL_ADDRESS=0x420 # (Only if not using OVAL_CONFIGS) The address of the Oval contract you want to target with the Oval Node.
REFUND_ADDRESS=0x42069 # (Only if not using OVAL_CONFIGS) The refund address you want to send the OEV kickback to.
REFUND_PERCENT=0.5 # (Only if not using OVAL_CONFIGS) The percentage of the OEV kickback to send to the refund address.
Expand All @@ -48,7 +49,6 @@ CHAIN_ID=<network_chain_id> # Chain ID of the Ethereum network

`OVAL_CONFIGS` is a JSON string that maps Oval contract addresses to their specific configurations. Each entry in this JSON object should have the following format:


```json
{
"<Oval_Contract_Address>": {
Expand All @@ -66,6 +66,19 @@ CHAIN_ID=<network_chain_id> # Chain ID of the Ethereum network
- `Refund_Address`: The Ethereum address where refunds will be sent.
- `Refund_Percentage`: The percentage of the OEV kickback to send to the refund address.

`OVAL_CONFIGS_SHARED` is a JSON string that specifies the shared unlocker configurations for all Oval contracts. Each entry in this JSON object should have the following format:

```json
[
{
"unlockerKey": "<Unlocker_Private_Key>", // Optional: Use either this or gckmsKeyId, not both.
"gckmsKeyId": "<GCKMS_Key_ID>", // Optional: Use either this or unlockerKey, not both.
},...
]
```

Note: If an Oval instance has an instance specific configuration, it will take precedence over the shared configuration.

### 2. Build & run the Oval Node:

Build the JS with:
Expand Down
16 changes: 14 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@types/uuid": "^9.0.8",
"@uma/logger": "^1.1.0",
"axios": "^1.5.1",
"bluebird": "^3.7.2",
"body-parser": "^1.20.2",
"ethers": "^6.8.0",
"express": "^4.18.2",
Expand All @@ -26,16 +27,27 @@
"typescript": "^5.2.2"
},
"devDependencies": {
"@typechain/ethers-v6": "^0.5.1",
"@types/bluebird": "^3.5.42",
"@types/chai": "^4.3.16",
"@types/eventsource": "^1.1.11",
"@types/mocha": "^10.0.7",
"@types/node": "^18.14.4",
"@types/sinon": "^17.0.3",
"@typescript-eslint/eslint-plugin": "^5.56.0",
"@typescript-eslint/parser": "^5.56.0",
"dotenv": "^16.3.1"
"chai": "^4.4.1",
"dotenv": "^16.3.1",
"mocha": "^10.6.0",
"sinon": "^18.0.0",
"typechain": "^8.3.2"
},
"scripts": {
"dev": "nodemon",
"build": "tsc",
"test": " mocha",
"start": "node ./out/index.js",
"lint": "prettier './**/*.ts' --write"
"lint": "prettier './**/*.ts' --write",
"generate-contract-types": "rm -rf src/contract-types && mkdir -p src/contract-types && typechain --target ethers-v6 --out-dir src/contract-types 'src/abi/*.json'"
}
}
1 change: 1 addition & 0 deletions src/abi/PermissionProxy.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/abi/StandardChainlinkFactory.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/abi/StandardChronicleFactory.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/abi/StandardCoinbaseFactory.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/abi/StandardPythFactory.json

Large diffs are not rendered by default.

249 changes: 249 additions & 0 deletions src/contract-types/PermissionProxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
/* Autogenerated file. Do not edit manually. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't these be gitignored and generated as part of build?

Also, for the sake of consistency, maybe we can also add Oval abi to this flow (currently its abi is in ts)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup

/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BytesLike,
FunctionFragment,
Result,
Interface,
EventFragment,
AddressLike,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedLogDescription,
TypedListener,
TypedContractMethod,
} from "./common";

export interface PermissionProxyInterface extends Interface {
getFunction(
nameOrSignature:
| "execute"
| "multicall"
| "owner"
| "renounceOwnership"
| "senders"
| "setSender"
| "transferOwnership"
): FunctionFragment;

getEvent(
nameOrSignatureOrTopic: "OwnershipTransferred" | "SenderSet"
): EventFragment;

encodeFunctionData(
functionFragment: "execute",
values: [AddressLike, BytesLike]
): string;
encodeFunctionData(
functionFragment: "multicall",
values: [BytesLike[]]
): string;
encodeFunctionData(functionFragment: "owner", values?: undefined): string;
encodeFunctionData(
functionFragment: "renounceOwnership",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "senders",
values: [AddressLike]
): string;
encodeFunctionData(
functionFragment: "setSender",
values: [AddressLike, boolean]
): string;
encodeFunctionData(
functionFragment: "transferOwnership",
values: [AddressLike]
): string;

decodeFunctionResult(functionFragment: "execute", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "multicall", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "renounceOwnership",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "senders", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "setSender", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "transferOwnership",
data: BytesLike
): Result;
}

export namespace OwnershipTransferredEvent {
export type InputTuple = [previousOwner: AddressLike, newOwner: AddressLike];
export type OutputTuple = [previousOwner: string, newOwner: string];
export interface OutputObject {
previousOwner: string;
newOwner: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}

export namespace SenderSetEvent {
export type InputTuple = [sender: AddressLike, allowed: boolean];
export type OutputTuple = [sender: string, allowed: boolean];
export interface OutputObject {
sender: string;
allowed: boolean;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}

export interface PermissionProxy extends BaseContract {
connect(runner?: ContractRunner | null): PermissionProxy;
waitForDeployment(): Promise<this>;

interface: PermissionProxyInterface;

queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;

on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;

once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;

listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;

execute: TypedContractMethod<
[target: AddressLike, callData: BytesLike],
[string],
"nonpayable"
>;

multicall: TypedContractMethod<[data: BytesLike[]], [string[]], "nonpayable">;

owner: TypedContractMethod<[], [string], "view">;

renounceOwnership: TypedContractMethod<[], [void], "nonpayable">;

senders: TypedContractMethod<[arg0: AddressLike], [boolean], "view">;

setSender: TypedContractMethod<
[sender: AddressLike, allowed: boolean],
[void],
"nonpayable"
>;

transferOwnership: TypedContractMethod<
[newOwner: AddressLike],
[void],
"nonpayable"
>;

getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;

getFunction(
nameOrSignature: "execute"
): TypedContractMethod<
[target: AddressLike, callData: BytesLike],
[string],
"nonpayable"
>;
getFunction(
nameOrSignature: "multicall"
): TypedContractMethod<[data: BytesLike[]], [string[]], "nonpayable">;
getFunction(
nameOrSignature: "owner"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "renounceOwnership"
): TypedContractMethod<[], [void], "nonpayable">;
getFunction(
nameOrSignature: "senders"
): TypedContractMethod<[arg0: AddressLike], [boolean], "view">;
getFunction(
nameOrSignature: "setSender"
): TypedContractMethod<
[sender: AddressLike, allowed: boolean],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "transferOwnership"
): TypedContractMethod<[newOwner: AddressLike], [void], "nonpayable">;

getEvent(
key: "OwnershipTransferred"
): TypedContractEvent<
OwnershipTransferredEvent.InputTuple,
OwnershipTransferredEvent.OutputTuple,
OwnershipTransferredEvent.OutputObject
>;
getEvent(
key: "SenderSet"
): TypedContractEvent<
SenderSetEvent.InputTuple,
SenderSetEvent.OutputTuple,
SenderSetEvent.OutputObject
>;

filters: {
"OwnershipTransferred(address,address)": TypedContractEvent<
OwnershipTransferredEvent.InputTuple,
OwnershipTransferredEvent.OutputTuple,
OwnershipTransferredEvent.OutputObject
>;
OwnershipTransferred: TypedContractEvent<
OwnershipTransferredEvent.InputTuple,
OwnershipTransferredEvent.OutputTuple,
OwnershipTransferredEvent.OutputObject
>;

"SenderSet(address,bool)": TypedContractEvent<
SenderSetEvent.InputTuple,
SenderSetEvent.OutputTuple,
SenderSetEvent.OutputObject
>;
SenderSet: TypedContractEvent<
SenderSetEvent.InputTuple,
SenderSetEvent.OutputTuple,
SenderSetEvent.OutputObject
>;
};
}
Loading
Loading