Skip to content

Commit

Permalink
- Update to work with latest version of codebase
Browse files Browse the repository at this point in the history
  • Loading branch information
clowestab committed Oct 18, 2024
1 parent 31bc21c commit f824225
Show file tree
Hide file tree
Showing 15 changed files with 180 additions and 140 deletions.
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@

![Resolution Demo](https://github.com/unruggable-labs/unruggable-gateways-ens-resolution-demos/actions/workflows/resolution-demo.yml/badge.svg)

This demo demonstrates a full end to end implementation of the [Unruggable Gateways](https://github.com/unruggable-labs/unruggable-gateways) codebase for resolving an ENS name using data stored on Optimism mainnnet.
This demo demonstrates a full end to end implementations of the [Unruggable Gateways](https://github.com/unruggable-labs/unruggable-gateways) codebase for resolving an ENS name using data stored on [Arbitrum](https://arbiscan.io/address/0xCC344B12fcc8512cc5639CeD6556064a8907c8a1#code), [Base](https://basescan.org/address/0x0C49361E151BC79899A9DD31B8B0CCdE4F6fd2f6#code), and [Optimism](https://optimistic.etherscan.io/address/0xf9d79d8c09d24e0C47E32778c830C545e78512CF#code).

It utilises [Foundry](https://github.com/foundry-rs) (through [blocksmith.js](https://github.com/adraffy/blocksmith.js)) to fork **Ethereum mainnet** and deploy an instance of `OPFaultVerifier`. This verifier is used to verify proofs returned by Unruggable's Optimism gateway running at `https://op-gateway.unruggable.com`.
It utilises [Foundry](https://github.com/foundry-rs) (through [blocksmith.js](https://github.com/adraffy/blocksmith.js)) to fork **Ethereum mainnet** and deploy an instance of the respective chain specific verifier. This verifier is used to verify proofs returned by Unruggable's gateways running at:

The gateway is fetching data proofs from the **real** Optimism Mainnet. This repo includes:

- `ExampleResolver.sol` which resolves against an address stored in our standard `SlotDataContract` (deployed [here](https://optimistic.etherscan.io/address/0xf9d79d8c09d24e0C47E32778c830C545e78512CF#code)).

- `OPResolver.sol` which resolves against a [storage contract](https://optimistic.etherscan.io/address/0xc695404735E0F1587A5398a06cAB34D7d7b009Da#code) that implements a PoC of the complex resolution logic outlined in the ENS v2 specification.
- [https://arbitrum-one.gateway.unruggable.com](https://arbitrum-one.gateway.unruggable.com)
- [https://base.gateway.unruggable.com](https://base.gateway.unruggable.com)
- [https://optimism.gateway.unruggable.com](https://optimism.gateway.unruggable.com)

The gateway is fetching data proofs from the **real** chains.

To install dependencies:

Expand All @@ -31,5 +30,7 @@ Copy `.env.example` to `.env` and input API keys for your node provider (Alchemy
To run:

```bash
bun run index.ts
bun run arbitrum-one.ts
bun run base.ts
bun run optimism.ts
```
2 changes: 1 addition & 1 deletion another.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const NODE = ethers.namehash('opdemo.eth');
const SLOT = solidityFollowSlot(0, NODE) + 1n;

//This is the address of the SlotDataContract deployed on the L2 (that we fork)
const EXAMPLE_CONTRACT_ADDRESS = '0x9720E17D90202c20449D07AFEA22Bd85de674bA9';
const EXAMPLE_CONTRACT_ADDRESS = '0xf9d79d8c09d24e0C47E32778c830C545e78512CF';

// Test with the ExampleResolver that reads a value from our live deployed SlotDataContract
// Uncomment this block, and comment the block below to test with the ExampleResolver
Expand Down
45 changes: 25 additions & 20 deletions arbitrum-one.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { NitroRollup } from '@unruggable/gateways';
import { createProviderPair, providerURL } from './providers';
import { runExample } from './example-base';
import { runExample, type VerifierArgsType } from './example-base';
import { type ConfigItem } from './utils';
import { Wallet } from 'ethers';

const config = NitroRollup.arb1MainnetConfig;

Expand All @@ -14,26 +15,30 @@ const rollup = await new NitroRollup(
createProviderPair(config),
config
);
const hooksPath = `@unruggable/contracts/eth/EthVerifierHooks.sol`;
const verifierPath = `@unruggable/contracts/nitro/NitroVerifier.sol`;
const verifierArgs: any[] = [];
const GATEWAY_URL = 'https://arbitrum-one.gateway.unruggable.com';

const verifierArgs: VerifierArgsType = async (smith, deployerWallet) => {

const ethHooksArgs: any[] = [];

const hooks = await smith.deploy({
import: hooksPath,
args: ethHooksArgs,
});

const verifierArgs: any[] = [
[GATEWAY_URL],
rollup.defaultWindow,
hooks.target,
rollup.L2Rollup.target
];

return verifierArgs;
}

//This is the address of the SlotDataContract deployed on the L2 (that we fork)
const EXAMPLE_CONTRACT_ADDRESS = '0xCC344B12fcc8512cc5639CeD6556064a8907c8a1'; //Arb
const configurationToSet: ConfigItem[] = [
{
getter: 'getWindow',
setter: 'setWindow',
value: rollup.defaultWindow,
},
{
getter: 'gatewayURLs',
setter: 'setGatewayURLs',
value: [GATEWAY_URL],
},
{
setter: 'setRollup',
value: rollup.L2Rollup.target,
},
];

runExample(provider, verifierPath, verifierArgs, configurationToSet, EXAMPLE_CONTRACT_ADDRESS);

runExample(provider, verifierPath, verifierArgs, EXAMPLE_CONTRACT_ADDRESS);
45 changes: 25 additions & 20 deletions base.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { OPRollup, Gateway } from '@unruggable/gateways';
import { createProviderPair, providerURL } from './providers';
import { runExample } from './example-base';
import type { ConfigItem } from './utils';
import type { VerifierArgsType } from './utils';

const config = OPRollup.baseMainnetConfig;

Expand All @@ -15,26 +15,31 @@ const rollup = await new OPRollup(createProviderPair(config),
const gateway = new Gateway(rollup);
const commit = await gateway.getLatestCommit();

const hooksPath = `@unruggable/contracts/eth/EthVerifierHooks.sol`;
const verifierPath = `@unruggable/contracts/op/OPVerifier.sol`;
const verifierArgs: any[] = [];

const GATEWAY_URL = 'https://base.gateway.unruggable.com';
const EXAMPLE_CONTRACT_ADDRESS = '0x0C49361E151BC79899A9DD31B8B0CCdE4F6fd2f6'; //Base
const configurationToSet: ConfigItem[] = [
{
getter: 'getWindow',
setter: 'setWindow',
value: rollup.defaultWindow,
},
{
getter: 'gatewayURLs',
setter: 'setGatewayURLs',
value: [GATEWAY_URL],
},
{
setter: 'setOracle',
value: rollup.L2OutputOracle.target,
},
];

runExample(provider, verifierPath, verifierArgs, configurationToSet, EXAMPLE_CONTRACT_ADDRESS);

const verifierArgs: VerifierArgsType = async (smith, deployerWallet) => {

const ethHooksLibs = {};
const ethHooksArgs: any[] = [];

const hooks = await smith.deploy({
import: hooksPath,
args: ethHooksArgs,
});

const verifierArgs: any[] = [
[GATEWAY_URL],
rollup.defaultWindow,
hooks.target,
rollup.L2OutputOracle.target,
1
];

return verifierArgs;
}

runExample(provider, verifierPath, verifierArgs, EXAMPLE_CONTRACT_ADDRESS);
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion cache/solidity-files-cache.json

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions contracts/ExampleResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ import {IAddressResolver} from "@ensdomains/contracts/resolvers/profiles/IAddres
import {BytesUtils} from "@ensdomains/contracts/utils/BytesUtils.sol";
import {Strings} from "@unruggable/lib/openzeppelin-contracts/contracts/utils/Strings.sol";
import {GatewayFetcher, GatewayRequest} from "@unruggable/contracts/GatewayFetcher.sol";
import "@unruggable/contracts/GatewayProtocol.sol";

// bases
import {GatewayFetchTarget, IGatewayProofVerifier} from "@unruggable/contracts/GatewayFetchTarget.sol";
import {GatewayFetchTarget, IGatewayVerifier} from "@unruggable/contracts/GatewayFetchTarget.sol";

import "forge-std/console2.sol"; // DEBUG

Expand All @@ -23,10 +22,10 @@ contract ExampleResolver is IERC165, IExtendedResolver, GatewayFetchTarget {
using BytesUtils for bytes;
using GatewayFetcher for GatewayRequest;

IGatewayProofVerifier immutable _verifier;
IGatewayVerifier immutable _verifier;
address immutable _exampleAddress;

constructor(IGatewayProofVerifier verifier, address exampleAddress) {
constructor(IGatewayVerifier verifier, address exampleAddress) {
_verifier = verifier;
_exampleAddress = exampleAddress;
}
Expand All @@ -45,7 +44,7 @@ contract ExampleResolver is IERC165, IExtendedResolver, GatewayFetchTarget {
.debug("lol")
.setOutput(0);

fetch(_verifier, r, this.addrCallback.selector, '');
fetch(_verifier, r, this.addrCallback.selector);
return new bytes(64);
}

Expand Down
40 changes: 40 additions & 0 deletions contracts/L1SimpleResolver.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import {GatewayFetcher, GatewayRequest} from "@unruggable/contracts/GatewayFetcher.sol";
import {GatewayFetchTarget, IGatewayVerifier} from "@unruggable/contracts/GatewayFetchTarget.sol";

import "forge-std/console2.sol"; // DEBUG

contract L1SimpleResolver is GatewayFetchTarget {
using GatewayFetcher for GatewayRequest;

IGatewayVerifier immutable _verifier;
address immutable _exampleAddress;

constructor(IGatewayVerifier verifier, address exampleAddress) {
_verifier = verifier;
_exampleAddress = exampleAddress;
}

function supportsInterface(bytes4 x) external pure returns (bool) {
return x == 0x9061b923 ? false : true;
}

function addr(bytes32 node) public view returns (address) {

GatewayRequest memory r = GatewayFetcher
.newRequest(1)
.setTarget(_exampleAddress)
.setSlot(11)
.read()
.debug("lol")
.setOutput(0);

fetch(_verifier, r, this.addrCallback.selector);
}

function addrCallback(bytes[] calldata values, uint8, bytes calldata extraData) external pure returns (address) {
return abi.decode(values[0], (address));
}
}
16 changes: 9 additions & 7 deletions contracts/OPResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {IAddressResolver} from "@ensdomains/contracts/resolvers/profiles/IAddres

import {BytesUtils} from "@ensdomains/contracts/utils/BytesUtils.sol";
import {Strings} from "@unruggable/lib/openzeppelin-contracts/contracts/utils/Strings.sol";
import {GatewayFetcher, GatewayRequest} from "@unruggable/contracts/GatewayFetcher.sol";
import "@unruggable/contracts/GatewayProtocol.sol";
import {GatewayFetchTarget, IGatewayProofVerifier} from "@unruggable/contracts/GatewayFetchTarget.sol";
import {GatewayFetcher} from "@unruggable/contracts/GatewayFetcher.sol";
import {GatewayFetchTarget, IGatewayVerifier} from "@unruggable/contracts/GatewayFetchTarget.sol";
import {GatewayRequest, EvalFlag} from "@unruggable/contracts/GatewayRequest.sol";

import {console2 as console} from "forge-std/console2.sol"; // DEBUG

Expand All @@ -19,11 +19,11 @@ contract OPResolver is IERC165, IExtendedResolver, GatewayFetchTarget {
using BytesUtils for bytes;
using GatewayFetcher for GatewayRequest;

IGatewayProofVerifier immutable _verifier;
IGatewayVerifier immutable _verifier;

address constant STORAGE_CONTRACT_ADDRESS = 0xc695404735E0F1587A5398a06cAB34D7d7b009Da;

constructor(IGatewayProofVerifier verifier) {
constructor(IGatewayVerifier verifier) {
console.log("Constructing OPResolver..");
_verifier = verifier;
}
Expand Down Expand Up @@ -81,13 +81,15 @@ contract OPResolver is IERC165, IExtendedResolver, GatewayFetchTarget {
.setOutput(0); // save it


baseRequest.push(subRequest).evalLoop(STOP_ON_FAILURE); // loop until we get a failure
baseRequest.push(subRequest).evalLoop(EvalFlag.STOP_ON_FAILURE); // loop until we get a failure
baseRequest.pushOutput(1).requireNonzero(uint8(0)).target() // set target to resolver
.setSlot(0) // _nodes mapping (map[node])
.push(name.namehash(0)).follow()
.read().setOutput(2); // read resolved address into output 2

fetch(_verifier, baseRequest, this.addrCallback.selector, abi.encodePacked(selector));
string[] memory urls = new string[](0);

fetch(_verifier, baseRequest, this.addrCallback.selector, abi.encodePacked(selector), urls);
}

return new bytes(64);
Expand Down
49 changes: 18 additions & 31 deletions example-base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Foundry } from '@adraffy/blocksmith';
import { namehash, toBeHex, Contract } from 'ethers';
import { type ConfigItem, type VerifierArgsType } from './utils';
import { namehash, toBeHex, Contract, Wallet } from 'ethers';
import { type VerifierArgsType } from './utils';
import { solidityFollowSlot } from '@unruggable/gateways';

const NAME_TO_TEST = "unruggable.eth";
Expand All @@ -9,7 +9,6 @@ export const runExample = async (
chainLink: string,
verifierPath: string,
verifierArgs: VerifierArgsType,
configurationToSet: ConfigItem[],
exampleContractAddress: string
) => {

Expand All @@ -18,51 +17,39 @@ export const runExample = async (
procLog : true,
infoLog : true,
});

const deployerWallet = foundry.wallets.admin;


const verifierArgsToUse = typeof verifierArgs === 'function' ? await verifierArgs(foundry) : verifierArgs;

//Deploy verifier
const vmPath = `@unruggable/contracts/GatewayVM.sol`;

const GatewayVM = await foundry.deploy({
import: vmPath,
args: [],
});

const verifierLibs = {GatewayVM};

const verifier = await foundry.deploy({
import: verifierPath,
args: verifierArgsToUse,
libs: verifierLibs,
});

//Deploy proxy
const proxy = await foundry.deploy({
import: `@unruggable/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol`,
args: [verifier.target, deployerWallet.address, '0x'],
});

// Instantiate the proxy using the underlying verifier interface
const proxyUsingInterface = new Contract(
proxy.target,
verifier.interface,
deployerWallet
);

// Configure the verifier
for (const config of configurationToSet) {
await foundry.confirm(proxyUsingInterface[config.setter](config.value));
console.log(`Set ${config.setter} to ${config.value}`);
}


const ENS = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e';
const NODE = namehash(NAME_TO_TEST);
const SLOT = solidityFollowSlot(0, NODE) + 1n;

const arbitrumOneResolver = await foundry.deploy({
const resolver = await foundry.deploy({
file: 'ExampleResolver',
args: [proxy.target, exampleContractAddress],
args: [verifier.target, exampleContractAddress],
});

console.log('Arbitrum One Resolver deployment:', arbitrumOneResolver.target);
console.log('Resolver deployment:', resolver.target);

await foundry.provider.send('anvil_setStorageAt', [
ENS,
toBeHex(SLOT, 32),
toBeHex(arbitrumOneResolver.target, 32),
toBeHex(resolver.target, 32),
]);
const ens = new Contract(
ENS,
Expand Down
2 changes: 1 addition & 1 deletion lib/unruggable-gateways
Loading

0 comments on commit f824225

Please sign in to comment.