diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e6df966 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/unruggable-gateways"] + path = lib/unruggable-gateways + url = https://github.com/unruggable-labs/unruggable-gateways diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 4f57df9..cdbad75 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -1,13 +1,73 @@ # Deployment & Setup Guide -This guide walks you through deploying and configuring the `ConfigResolver` and `AddressSubnameRegistrar` contracts. +This guide walks you through deploying and configuring the `ConfigResolver`, `AddressSubnameRegistrar`, and `L1ConfigResolver` contracts. ## Overview | Contract | Purpose | | ------------------------- | --------------------------------------------------------------------- | | `ConfigResolver` | A general-purpose ENS resolver that allows name owners to set records | -| `AddressSubnameRegistrar` | Allows users to claim `
.yourname.eth` subnames | +| `AddressSubnameRegistrar` | Allows users to claim `0x
.yourname.eth` subnames | +| `L1ConfigResolver` | Reads L2 ConfigResolver records from L1 via CCIP-Read | + +## Architecture Options + +### Option A: L1 Claiming with L2 Storage (Recommended) + +Users claim subnames on L1 (Ethereum), but records are stored on L2 (Base) for lower gas costs. Users can optionally change their resolver. + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ L1 (Ethereum) │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────┐ ┌───────────────────────────────┐ │ +│ │ AddressSubnameRegistrar │ │ L1ConfigResolver │ │ +│ │ ───────────────────────── │ │ ─────────────────────────── │ │ +│ │ • Users call claim() │────▶│ • Default resolver for │ │ +│ │ • Creates ENS node on L1 │ │ claimed subnames │ │ +│ │ • Sets resolver to │ │ • Reads records via │ │ +│ │ L1ConfigResolver │ │ CCIP-Read from L2 │ │ +│ └─────────────────────────────┘ └───────────────┬───────────────┘ │ +│ │ │ +│ User owns ENS node → can change resolver if desired │ │ +│ │ │ +└───────────────────────────────────────────────────────┼──────────────────┘ + │ CCIP-Read + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ L2 (Base) │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ ConfigResolver │ │ +│ │ ───────────────────────────────────────────────────────────── │ │ +│ │ • Stores text, address, contenthash records │ │ +│ │ • Users set records here (low gas) │ │ +│ │ • Authorizes via reverse node (user's address) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +**User Flow:** + +1. User calls `claim()` on L1 `AddressSubnameRegistrar` → creates `0x
.parent.eth` in ENS +2. Subname is created with `L1ConfigResolver` as the resolver +3. User sets records on L2 `ConfigResolver` (low gas) +4. L1 resolution reads from L2 via CCIP-Read +5. User can change their L1 resolver anytime (they own the ENS node) + +### Option B: L2-Only with Wildcard Resolution + +Simpler setup where everything lives on L2, and L1 uses wildcard resolution. Users cannot change their resolver. + +``` +L1: Parent name resolver = L1ConfigResolver (wildcard ENSIP-10) +L2: ConfigResolver + AddressSubnameRegistrar +``` + +**Limitation:** Subnames don't exist in L1 ENS registry, so users cannot change their resolver. ## Prerequisites @@ -30,126 +90,141 @@ cast wallet list ## Contract Addresses -### Mainnet +### ENS Addresses (same on all networks) | Contract | Address | | ------------ | -------------------------------------------- | | ENS Registry | `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e` | -| NameWrapper | `0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401` | + +### Mainnet + +| Contract | Address | +| ---------------- | -------------------------------------------- | +| NameWrapper | `0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401` | +| Gateway Verifier | `0x0bC6c539e5fc1fb92F31dE34426f433557A9A5A2` | ### Sepolia -| Contract | Address | -| ------------ | -------------------------------------------- | -| ENS Registry | `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e` | -| NameWrapper | `0x0635513f179D50A207757E05759CbD106d7dFcE8` | +| Contract | Address | +| ---------------- | -------------------------------------------- | +| NameWrapper | `0x0635513f179D50A207757E05759CbD106d7dFcE8` | +| Gateway Verifier | `0x7F68510F0fD952184ec0b976De429a29A2Ec0FE3` | --- -## Step 1: Deploy ConfigResolver +## Step 1: Deploy Contracts -### Using the deploy script +### Deploy ConfigResolver + AddressSubnameRegistrar ```bash -# Deploy to Sepolia (default) -./script/deploy.sh +# Sepolia +PARENT_NODE=$(cast namehash "yourname.eth") \ + forge script script/Deploy.s.sol \ + --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify -# Deploy to Mainnet -./script/deploy.sh mainnet +# Mainnet +PARENT_NODE=$(cast namehash "yourname.eth") \ + forge script script/Deploy.s.sol \ + --rpc-url https://eth-mainnet.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify ``` -### Manual deployment +### Deploy ConfigResolver Only ```bash -# Set variables -export RPC_URL="https://sepolia.gateway.tenderly.co" -export ENS_REGISTRY="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" -export NAME_WRAPPER="0x0635513f179D50A207757E05759CbD106d7dFcE8" - -# Deploy -forge create src/ConfigResolver.sol:ConfigResolver \ +forge script script/Deploy.s.sol --sig "deployConfigResolver()" \ --rpc-url $RPC_URL \ --account deployer \ - --constructor-args $ENS_REGISTRY $NAME_WRAPPER \ - --verify \ - --etherscan-api-key $ETHERSCAN_API_KEY + --broadcast \ + --verify ``` -Save the deployed address as `CONFIG_RESOLVER`. - ---- - -## Step 2: Deploy AddressSubnameRegistrar +### Deploy L1ConfigResolver (CCIP-Read) -First, compute the namehash of your parent name: +For reading L2 records from L1: ```bash -# Compute namehash for "ethconfig.eth" -cast namehash "ethconfig.eth" -# Returns: 0x... (your parent node) -``` - -Then deploy: - -```bash -export PARENT_NODE=$(cast namehash "ethconfig.eth") -export CONFIG_RESOLVER="0x..." # From step 1 - -forge create src/AddressSubnameRegistrar.sol:AddressSubnameRegistrar \ +L2_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Resolver()" \ --rpc-url $RPC_URL \ --account deployer \ - --constructor-args $ENS_REGISTRY $NAME_WRAPPER $PARENT_NODE $CONFIG_RESOLVER \ - --verify \ - --etherscan-api-key $ETHERSCAN_API_KEY + --broadcast \ + --verify ``` -Save the deployed address as `REGISTRAR`. - ---- +**Environment Variables:** -## Step 3: Authorize the Registrar +| Variable | Required | Default | Description | +| -------------------- | -------- | ----------------- | ------------------------------- | +| `L2_CONFIG_RESOLVER` | Yes | - | Address of ConfigResolver on L2 | +| `VERIFIER` | No | Chain-dependent\* | Gateway verifier address | +| `L2_CHAIN_ID` | No | Chain-dependent\* | L2 chain ID | -The registrar needs permission to create subnames. First, check if your name is wrapped. +\*Defaults: Mainnet → Base (8453) with `0x0bC6c539e5fc1fb92F31dE34426f433557A9A5A2`, Sepolia → Base Sepolia (84532) with `0x7F68510F0fD952184ec0b976De429a29A2Ec0FE3` -### Check if your name is wrapped +**Custom L2 deployment (non-Base chains):** ```bash -# Check who owns the node in ENS Registry -cast call $ENS_REGISTRY "owner(bytes32)(address)" $PARENT_NODE --rpc-url $RPC_URL +# Example: Deploy for Arbitrum +VERIFIER=0x... \ +L2_CHAIN_ID=42161 \ +L2_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Resolver()" \ + --rpc-url $RPC_URL \ + --account deployer \ + --broadcast \ + --verify ``` -- If the result is the **NameWrapper address** → your name is **wrapped** (Option B) -- If the result is **your address** → your name is **unwrapped** (Option A) - -### Option A: Unwrapped Name +### Deploy L1 AddressSubnameRegistrar (Option A) -Transfer ownership of the parent name to the registrar: +For L1 claiming with L2 storage - deploy after L1ConfigResolver: ```bash -# Transfer ownership to the registrar -cast send $ENS_REGISTRY "setOwner(bytes32,address)" \ - $PARENT_NODE \ - $REGISTRAR \ - --rpc-url $RPC_URL \ - --account deployer +# Sepolia +PARENT_NODE=$(cast namehash "yourname.eth") \ +L1_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Registrar()" \ + --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify + +# Mainnet +PARENT_NODE=$(cast namehash "yourname.eth") \ +L1_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Registrar()" \ + --rpc-url https://eth-mainnet.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify ``` -> ⚠️ **Warning**: This transfers full control. Consider using a wrapper or approval instead. +Save the deployed addresses for the next steps. + +--- -### Option B: Wrapped Name (Recommended) +## Step 2: Authorize the Registrar -If your name is wrapped in NameWrapper, you need to approve the registrar as an operator. +The registrar needs permission to create subnames under your wrapped name. > ⚠️ **Important**: The approval must come from the **actual owner** of the wrapped name, not the deployer (unless they're the same). -**Step 1: Find the wrapped name owner** +### Find the wrapped name owner ```bash +export PARENT_NODE=$(cast namehash "yourname.eth") + # Check who owns the wrapped name cast call $NAME_WRAPPER "ownerOf(uint256)(address)" $PARENT_NODE --rpc-url $RPC_URL ``` -**Step 2: Approve the registrar (from the owner's account)** +### Approve the registrar ```bash # Approve registrar to manage your wrapped names @@ -161,31 +236,14 @@ cast send $NAME_WRAPPER "setApprovalForAll(address,bool)" \ --account # Must be the wrapped name owner ``` -For example, if the owner is in a keystore called `user`: - -```bash -cast send $NAME_WRAPPER "setApprovalForAll(address,bool)" \ - $REGISTRAR \ - true \ - --rpc-url $RPC_URL \ - --account user -``` - --- -## Step 4: Enable Wildcard Resolution (ENSIP-10) +## Step 3: Enable Wildcard Resolution (ENSIP-10) -The ConfigResolver supports wildcard resolution, allowing `
.yourname.eth` to resolve without users needing to claim the subname first. This enables: - -- **Address resolution**: `
.yourname.eth` automatically resolves to that address -- **Text records**: Users can set records that resolve via any parent name +The ConfigResolver supports wildcard resolution, allowing `0x
.yourname.eth` to resolve without users needing to claim the subname first. ### Set ConfigResolver as the parent name's resolver -For wildcard resolution to work, your parent name must use the ConfigResolver as its resolver. - -**For wrapped names (NameWrapper):** - ```bash # Set ConfigResolver as the resolver for your parent name # Run this from the wrapped name OWNER's account @@ -196,16 +254,6 @@ cast send $NAME_WRAPPER "setResolver(bytes32,address)" \ --account ``` -**For unwrapped names (ENS Registry):** - -```bash -cast send $ENS_REGISTRY "setResolver(bytes32,address)" \ - $PARENT_NODE \ - $CONFIG_RESOLVER \ - --rpc-url $RPC_URL \ - --account -``` - ### Verify wildcard support ```bash @@ -218,21 +266,9 @@ cast call $ENS_REGISTRY "resolver(bytes32)(address)" $PARENT_NODE --rpc-url $RPC # Should return: your CONFIG_RESOLVER address ``` -### How it works - -Once enabled, any lookup for `
.yourname.eth` will: - -1. ENS checks if the subname exists → it doesn't (not claimed) -2. ENS falls back to the parent's resolver (ConfigResolver) -3. ConfigResolver's `resolve()` function handles the request: - - For `addr()`: Returns the address from the subdomain label - - For `text()`: Looks up records stored under the user's reverse node - -This means users can set records once (via their reverse node) and have them resolve under any parent name that uses ConfigResolver. - --- -## Step 5: Verify Deployment +## Step 4: Verify Deployment ### Check ConfigResolver @@ -259,6 +295,23 @@ cast call $REGISTRAR "defaultResolver()" --rpc-url $RPC_URL cast call $REGISTRAR "available(address)" "0x8d25687829D6b85d9e0020B8c89e3Ca24dE20a89" --rpc-url $RPC_URL ``` +### Check L1ConfigResolver + +```bash +# Verify it supports IExtendedResolver +cast call $L1_RESOLVER "supportsInterface(bytes4)" "0x9061b923" --rpc-url $RPC_URL +# Should return: true (0x01) + +# Check the L2 chain ID +cast call $L1_RESOLVER "l2ChainId()(uint256)" --rpc-url $RPC_URL + +# Check the L2 target +cast call $L1_RESOLVER "l2ConfigResolver()(address)" --rpc-url $RPC_URL + +# Check the verifier +cast call $L1_RESOLVER "verifier()(address)" --rpc-url $RPC_URL +``` + --- ## Usage @@ -274,7 +327,7 @@ cast send $REGISTRAR "claim()" \ --account user-wallet ``` -This creates `
.ethconfig.eth` for the caller. +This creates `0x
.yourname.eth` for the caller (e.g., `0x8d25687829d6b85d9e0020b8c89e3ca24de20a89.yourname.eth`). ### Setting Records on Claimed Subnames @@ -389,33 +442,35 @@ const hash = await walletClient.writeContract({ ## Deployed Contracts -After deployment, update this section with your addresses: +### Testnets + +| Network | Contract | Address | +| ------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| Base Sepolia | ConfigResolver | [`0xA66c55a6b76967477af18A03F2f12d52251Dc2C0`](https://sepolia.basescan.org/address/0xA66c55a6b76967477af18A03F2f12d52251Dc2C0) | +| Sepolia | L1ConfigResolver | [`0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B`](https://sepolia.etherscan.io/address/0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B) | + +### Mainnet -| Network | Contract | Address | -| ------- | ----------------------- | ------- | -| Sepolia | ConfigResolver | `0x...` | -| Sepolia | AddressSubnameRegistrar | `0x...` | -| Mainnet | ConfigResolver | `0x...` | -| Mainnet | AddressSubnameRegistrar | `0x...` | +| Network | Contract | Address | +| -------- | ---------------- | ------- | +| Base | ConfigResolver | TBD | +| Ethereum | L1ConfigResolver | TBD | --- ## Troubleshooting -### "Unauthorised" error when claiming (wrapped names) +### "Unauthorised" error when claiming This is the most common issue. It means the registrar is not approved to create subnames. **Diagnosis:** ```bash -# 1. Check if the name is wrapped (owned by NameWrapper in registry) -cast call $ENS_REGISTRY "owner(bytes32)(address)" $PARENT_NODE --rpc-url $RPC_URL - -# 2. If wrapped, find the actual owner +# 1. Find the wrapped name owner cast call $NAME_WRAPPER "ownerOf(uint256)(address)" $PARENT_NODE --rpc-url $RPC_URL -# 3. Check if the registrar is approved by that owner +# 2. Check if the registrar is approved by that owner cast call $NAME_WRAPPER "isApprovedForAll(address,address)(bool)" \ \ $REGISTRAR \ @@ -444,7 +499,6 @@ cast send $NAME_WRAPPER "setApprovalForAll(address,bool)" \ ### Registrar can't create subnames -- Ensure the registrar is the owner of the parent node, OR - Ensure the registrar is approved via NameWrapper **by the wrapped name owner** ### Records not being set @@ -454,14 +508,138 @@ cast send $NAME_WRAPPER "setApprovalForAll(address,bool)" \ --- -## Security Considerations +## Full Deployment Workflow (Option A) + +This is the complete workflow for deploying the L1 claiming with L2 storage architecture. + +### Step 1: Deploy ConfigResolver on L2 (Base) + +```bash +# Base Sepolia +forge script script/Deploy.s.sol --sig "deployConfigResolver()" \ + --rpc-url https://base-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify + +# Base Mainnet +forge script script/Deploy.s.sol --sig "deployConfigResolver()" \ + --rpc-url https://base-mainnet.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify +``` + +Save the L2 ConfigResolver address as `L2_CONFIG_RESOLVER`. + +### Step 2: Deploy L1ConfigResolver on L1 + +```bash +# Sepolia +L2_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Resolver()" \ + --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify + +# Mainnet +L2_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Resolver()" \ + --rpc-url https://eth-mainnet.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify +``` + +Save the L1ConfigResolver address as `L1_CONFIG_RESOLVER`. + +### Step 3: Deploy L1 AddressSubnameRegistrar + +```bash +# Sepolia +PARENT_NODE=$(cast namehash "yourname.eth") \ +L1_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Registrar()" \ + --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify + +# Mainnet +PARENT_NODE=$(cast namehash "yourname.eth") \ +L1_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Registrar()" \ + --rpc-url https://eth-mainnet.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify +``` + +Save the L1 AddressSubnameRegistrar address as `L1_REGISTRAR`. -1. **Parent name ownership**: Once you transfer the parent name to the registrar, you lose direct control. Consider using NameWrapper approvals instead. +### Step 4: Authorize L1 Registrar + +The L1 registrar needs permission to create subnames under your wrapped parent name. + +```bash +# From the wrapped name owner's account +cast send $NAME_WRAPPER "setApprovalForAll(address,bool)" \ + $L1_REGISTRAR \ + true \ + --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account +``` + +### Step 5: User Claims on L1 + +Users can now claim their subname on L1: + +```bash +cast send $L1_REGISTRAR "claim()" \ + --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account user-wallet +``` + +### Step 6: User Sets Records on L2 + +Users set their records on the L2 ConfigResolver: + +```bash +# Get the user's node hash +USER_NODE=$(cast call $L1_REGISTRAR "node(address)(bytes32)" $USER_ADDRESS \ + --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY) + +# Set a text record on L2 +cast send $L2_CONFIG_RESOLVER "setText(bytes32,string,string)" \ + $USER_NODE \ + "url" \ + "https://example.com" \ + --rpc-url https://base-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account user-wallet +``` + +### Step 7: (Optional) User Changes Resolver + +Users who want a different resolver can change it on L1 (they own the wrapped subname): + +```bash +# User changes their resolver via NameWrapper +cast send $NAME_WRAPPER "setResolver(bytes32,address)" \ + $USER_NODE \ + $NEW_RESOLVER \ + --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account user-wallet +``` + +--- + +## Security Considerations -2. **Subname ownership**: Users fully own their claimed subnames and can set any records. +1. **Subname ownership**: Users fully own their claimed subnames and can set any records. -3. **No fees**: This implementation doesn't charge fees. Add payment logic if needed. +2. **No fees**: This implementation doesn't charge fees. Add payment logic if needed. -4. **No expiry**: Subnames don't expire unless the parent expires. Consider adding reclaim logic. +3. **No expiry**: Subnames don't expire unless the parent expires. Consider adding reclaim logic. -5. **Wrapped names**: If the parent is wrapped, subnames will be wrapped too with inherited fuses. +4. **Wrapped subnames**: Since the parent is wrapped, subnames will be wrapped too with inherited fuses. diff --git a/README.md b/README.md index 5d48fa0..e6a1648 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,42 @@ # ENS Config Resolver -A set of ENS contracts that enable users to claim address-based subnames under your ENS name. +A set of ENS contracts that enable users to claim address-based subnames under your ENS name, with optional L1 → L2 CCIP-Read resolution. ## Overview -This project provides two main contracts: +This project provides three main contracts: | Contract | Description | | --------------------------- | ------------------------------------------------------------------------------------- | | **ConfigResolver** | A general-purpose ENS resolver for setting records (text, address, contenthash, etc.) | -| **AddressSubnameRegistrar** | Enables users to claim `.yourname.eth` subnames | +| **AddressSubnameRegistrar** | Enables users to claim `0x
.yourname.eth` subnames | +| **L1ConfigResolver** | Reads L2 ConfigResolver records from L1 via CCIP-Read (Unruggable Gateways) | + +## Deployments + +### Testnets + +| Contract | Network | Address | +| ---------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------- | +| ConfigResolver | Base Sepolia | [`0xA66c55a6b76967477af18A03F2f12d52251Dc2C0`](https://sepolia.basescan.org/address/0xA66c55a6b76967477af18A03F2f12d52251Dc2C0) | +| L1ConfigResolver | Sepolia | [`0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B`](https://sepolia.etherscan.io/address/0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B) | + +### Mainnet + +| Contract | Network | Address | +| ---------------- | -------- | ------- | +| ConfigResolver | Base | TBD | +| L1ConfigResolver | Ethereum | TBD | ### Example If you own `ethconfig.eth`, users can claim subnames like: ``` -8d25687829d6b85d9e0020b8c89e3ca24de20a89.ethconfig.eth +0x8d25687829d6b85d9e0020b8c89e3ca24de20a89.ethconfig.eth ``` -The address is normalized to lowercase hex (40 characters, no `0x` prefix). +The address is normalized to lowercase hex with the `0x` prefix (42 characters total). ## Quick Start @@ -37,12 +54,57 @@ forge test ### Deploy +Deploy ConfigResolver + AddressSubnameRegistrar: + ```bash -# Deploy to Sepolia -./script/deploy.sh +# Sepolia +PARENT_NODE=$(cast namehash "yourname.eth") \ + forge script script/Deploy.s.sol \ + --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify + +# Mainnet +PARENT_NODE=$(cast namehash "yourname.eth") \ + forge script script/Deploy.s.sol \ + --rpc-url https://eth-mainnet.g.alchemy.com/v2/$ALCHEMY_API_KEY \ + --account deployer \ + --broadcast \ + --verify +``` -# Deploy to Mainnet -./script/deploy.sh mainnet +Deploy ConfigResolver only: + +```bash +forge script script/Deploy.s.sol --sig "deployConfigResolver()" \ + --rpc-url $RPC_URL \ + --account deployer \ + --broadcast \ + --verify +``` + +Deploy L1ConfigResolver (for reading L2 records from L1): + +```bash +L2_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Resolver()" \ + --rpc-url $RPC_URL \ + --account deployer \ + --broadcast \ + --verify +``` + +Deploy L1 AddressSubnameRegistrar (for L1 claiming with L2 storage): + +```bash +PARENT_NODE=$(cast namehash "yourname.eth") \ +L1_CONFIG_RESOLVER=0x... \ + forge script script/Deploy.s.sol --sig "deployL1Registrar()" \ + --rpc-url $RPC_URL \ + --account deployer \ + --broadcast \ + --verify ``` See [DEPLOYMENT.md](./DEPLOYMENT.md) for the full deployment and setup guide. @@ -84,12 +146,38 @@ registrar.claimForAddr(addr, owner); registrar.available(addr); // Get the label for an address -registrar.getLabel(addr); // "8d25687829d6b85d9e0020b8c89e3ca24de20a89" +registrar.getLabel(addr); // "0x8d25687829d6b85d9e0020b8c89e3ca24de20a89" // Get the node hash registrar.node(addr); ``` +### L1ConfigResolver + +An L1 resolver that reads ENS records from a ConfigResolver deployed on L2 (Base) using CCIP-Read. Implements the `IL1ConfigResolver` interface. + +```solidity +// Supports standard ENS resolution methods +resolver.addr(node); // Get ETH address +resolver.text(node, "url"); // Get text record +resolver.contenthash(node); // Get contenthash + +// Also supports ENSIP-10 extended resolution +resolver.resolve(name, data); + +// IL1ConfigResolver interface +resolver.l2ChainId(); // Get the L2 chain ID +resolver.l2ConfigResolver(); // Get the L2 ConfigResolver address +``` + +**Default Verifiers (Base):** +| Network | Verifier | L2 Chain ID | +|---------|----------|-------------| +| Sepolia | `0x7F68510F0fD952184ec0b976De429a29A2Ec0FE3` | 84532 (Base Sepolia) | +| Mainnet | `0x0bC6c539e5fc1fb92F31dE34426f433557A9A5A2` | 8453 (Base) | + +Custom verifiers and L2 chain IDs can be specified via environment variables during deployment. + ## Development ### Prerequisites @@ -123,25 +211,68 @@ forge snapshot ## Architecture +### L1 Claiming with L2 Storage (Recommended) + +Users claim subnames on L1 (Ethereum) and can change their resolver. Records are stored on L2 (Base) for lower gas costs. + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ L1 (Ethereum) │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────┐ ┌───────────────────────────────┐ │ +│ │ AddressSubnameRegistrar │ │ L1ConfigResolver │ │ +│ │ ───────────────────────── │ │ ─────────────────────────── │ │ +│ │ • Users call claim() │────▶│ • Default resolver for │ │ +│ │ • Creates ENS node on L1 │ │ claimed subnames │ │ +│ │ │ │ • Reads via CCIP-Read │ │ +│ └─────────────────────────────┘ └───────────────┬───────────────┘ │ +│ │ │ +│ User owns ENS node → can change resolver if desired │ │ +└───────────────────────────────────────────────────────┼──────────────────┘ + │ CCIP-Read + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ L2 (Base) │ +├─────────────────────────────────────────────────────────────────────────┤ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ ConfigResolver - stores records (text, address, contenthash) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +**User Flow:** + +1. Claim subname on L1 → `registrar.claim()` +2. Set records on L2 → `resolver.setText(node, "url", "https://...")` +3. L1 resolution reads from L2 via CCIP-Read +4. Optionally change resolver on L1 (user owns the ENS node) + +### CCIP-Read Flow + ``` -┌─────────────────────────────────────────────────────────────┐ -│ User's Wallet │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ AddressSubnameRegistrar │ -│ ┌─────────────────────────────────────────────────────┐ │ -│ │ claim() → creates
.parent.eth │ │ -│ └─────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ - │ - ┌───────────────┴───────────────┐ - ▼ ▼ -┌─────────────────────────┐ ┌─────────────────────────────┐ -│ ENS Registry │ │ ConfigResolver │ -│ (stores ownership) │ │ (stores records) │ -└─────────────────────────┘ └─────────────────────────────┘ +┌──────────────────┐ 1. Call ┌─────────────────────┐ +│ Your dApp │ ───────────────► │ L1ConfigResolver │ +│ (Frontend) │ │ (Ethereum L1) │ +└──────────────────┘ └────────┬────────────┘ + ▲ │ + │ 2. Reverts with + │ OffchainLookup + │ │ + │ 5. Return ▼ + │ verified ┌─────────────────────────────┐ + │ data │ Gateway (off-chain) │ + │ └─────────────┬───────────────┘ + │ │ + │ 3. Fetch proofs from L2 + │ │ + │ ▼ + │ ┌─────────────────────────────┐ + │ │ ConfigResolver (Base L2) │ + │ └─────────────────────────────┘ + │ │ + │ 4. Return proofs + └─────────────────────────────────┘ ``` ## License diff --git a/broadcast/Deploy.s.sol/11155111/deployL1Registrar-latest.json b/broadcast/Deploy.s.sol/11155111/deployL1Registrar-latest.json new file mode 100644 index 0000000..0156cc9 --- /dev/null +++ b/broadcast/Deploy.s.sol/11155111/deployL1Registrar-latest.json @@ -0,0 +1,56 @@ +{ + "transactions": [ + { + "hash": "0xc643d5af5b42aae00933dd0d76df862b2ea4e14e9c2cd6742c7f5f7f66c924ab", + "transactionType": "CREATE", + "contractName": "AddressSubnameRegistrar", + "contractAddress": "0x8b82d2af30062e0461c8c3bd1a6ced1df650a5e9", + "function": null, + "arguments": [ + "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", + "0x0635513f179D50A207757E05759CbD106d7dFcE8", + "0xfd49266f604c6bc93ead36965d74c1cf766a3f0f896faa27a2038a75118625c1", + "0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B" + ], + "transaction": { + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "gas": "0x1a4eae", + "value": "0x0", + "input": "0x610100604052348015610010575f80fd5b50604051611a10380380611a10833981810160405281019061003291906101e6565b8373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508273ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250508160c081815250508073ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250505050505061024a565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61010c826100e3565b9050919050565b5f61011d82610102565b9050919050565b61012d81610113565b8114610137575f80fd5b50565b5f8151905061014881610124565b92915050565b5f61015882610102565b9050919050565b6101688161014e565b8114610172575f80fd5b50565b5f815190506101838161015f565b92915050565b5f819050919050565b61019b81610189565b81146101a5575f80fd5b50565b5f815190506101b681610192565b92915050565b6101c581610102565b81146101cf575f80fd5b50565b5f815190506101e0816101bc565b92915050565b5f805f80608085870312156101fe576101fd6100df565b5b5f61020b8782880161013a565b945050602061021c87828801610175565b935050604061022d878288016101a8565b925050606061023e878288016101d2565b91505092959194509250565b60805160a05160c05160e0516116f261031e5f395f8181610c7201528181610ee60152610fd201525f818161078a01528181610ac201528181610cbb01528181610d1301528181610df901528181610ec30152610faf01525f81816102ea0152818161032a01528181610396015281816108ba015281816108fa0152818161096601528181610b5701528181610b9701528181610c9601528181610dbd0152610e8701525f81816101fb0152818161064e015281816106aa015281816107d601528181610a860152610f7301526116f25ff3fe608060405234801561000f575f80fd5b5060043610610091575f3560e01c80634e71d92d116100645780634e71d92d14610143578063828eab0e14610161578063a8e5fbc01461017f578063bffbe61c1461019d578063f3068a00146101cd57610091565b806310098ad51461009557806328a249b0146100c55780633f15457f146100f55780634709bf4b14610113575b5f80fd5b6100af60048036038101906100aa91906110a1565b6101eb565b6040516100bc91906110e6565b60405180910390f35b6100df60048036038101906100da91906110a1565b610459565b6040516100ec919061116f565b60405180910390f35b6100fd61064c565b60405161010a91906111ea565b60405180910390f35b61012d60048036038101906101289190611203565b610670565b60405161013a9190611259565b60405180910390f35b61014b610c60565b6040516101589190611259565b60405180910390f35b610169610c70565b6040516101769190611281565b60405180910390f35b610187610c94565b60405161019491906112ba565b60405180910390f35b6101b760048036038101906101b291906110a1565b610cb8565b6040516101c49190611259565b60405180910390f35b6101d5610d11565b6040516101e29190611259565b60405180910390f35b5f806101f683610cb8565b90505f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b81526004016102529190611259565b602060405180830381865afa15801561026d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061029191906112e7565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036102d157600192505050610454565b5f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161415801561037857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b1561044e575f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636352211e845f1c6040518263ffffffff1660e01b81526004016103ef919061132a565b602060405180830381865afa15801561040a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042e91906112e7565b73ffffffffffffffffffffffffffffffffffffffff161492505050610454565b5f925050505b919050565b60605f602867ffffffffffffffff81111561047757610476611343565b5b6040519080825280601f01601f1916602001820160405280156104a95781602001600182028036833780820191505090505b5090505f8390505f602890505b5f811115610641578080600190039150507f30313233343536373839616263646566000000000000000000000000000000005f1b600f831673ffffffffffffffffffffffffffffffffffffffff166020811061051557610514611370565b5b1a60f81b60f81c60f81b83828151811061053257610531611370565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060048273ffffffffffffffffffffffffffffffffffffffff16901c91508080600190039150507f30313233343536373839616263646566000000000000000000000000000000005f1b600f831673ffffffffffffffffffffffffffffffffffffffff16602081106105d4576105d3611370565b5b1a60f81b60f81c60f81b8382815181106105f1576105f0611370565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060048273ffffffffffffffffffffffffffffffffffffffff16901c91506104b6565b508192505050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561074457507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e985e9c584336040518363ffffffff1660e01b815260040161070392919061139d565b602060405180830381865afa15801561071e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061074291906113ee565b155b1561077b576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61078584610d35565b90505f7f0000000000000000000000000000000000000000000000000000000000000000826040516020016107bb929190611439565b6040516020818303038152906040528051906020012090505f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b815260040161082d9190611259565b602060405180830381865afa158015610848573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061086c91906112e7565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a83575f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161415801561094857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b15610a50575f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636352211e845f1c6040518263ffffffff1660e01b81526004016109bf919061132a565b602060405180830381865afa1580156109da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109fe91906112e7565b73ffffffffffffffffffffffffffffffffffffffff1614610a4b576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a82565b6040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166302571be37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610afd9190611259565b602060405180830381865afa158015610b18573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3c91906112e7565b90505f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1614158015610be557507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b15610bf957610bf48787610dba565b610c04565b610c038487610f71565b5b828773ffffffffffffffffffffffffffffffffffffffff167f1b2af9453f54ccc027b7454c98ebdf2e7bc4b762f1a1c5dd221d1affdb9fe03e88604051610c4b9190611281565b60405180910390a38294505050505092915050565b5f610c6b3333610670565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f0000000000000000000000000000000000000000000000000000000000000000610ce383610d35565b604051602001610cf4929190611439565b604051602081830303815290604052805190602001209050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f60285b5f811115610dae576001810390507f3031323334353637383961626364656600000000000000000000000000000000600f84161a81536010830492506001810390507f3031323334353637383961626364656600000000000000000000000000000000600f84161a8153601083049250610d39565b5060285f209050919050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630178fe3f7f00000000000000000000000000000000000000000000000000000000000000005f1c6040518263ffffffff1660e01b8152600401610e36919061132a565b606060405180830381865afa158015610e51573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e7591906114da565b925050505f610e8384610459565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166324c1af447f000000000000000000000000000000000000000000000000000000000000000083867f00000000000000000000000000000000000000000000000000000000000000005f80896040518863ffffffff1660e01b8152600401610f2a97969594939291906115a2565b6020604051808303815f875af1158015610f46573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f6a9190611640565b5050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635ef2c7f07f000000000000000000000000000000000000000000000000000000000000000084847f00000000000000000000000000000000000000000000000000000000000000005f6040518663ffffffff1660e01b815260040161101295949392919061166b565b5f604051808303815f87803b158015611029575f80fd5b505af115801561103b573d5f803e3d5ffd5b505050505050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61107082611047565b9050919050565b61108081611066565b811461108a575f80fd5b50565b5f8135905061109b81611077565b92915050565b5f602082840312156110b6576110b5611043565b5b5f6110c38482850161108d565b91505092915050565b5f8115159050919050565b6110e0816110cc565b82525050565b5f6020820190506110f95f8301846110d7565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611141826110ff565b61114b8185611109565b935061115b818560208601611119565b61116481611127565b840191505092915050565b5f6020820190508181035f8301526111878184611137565b905092915050565b5f819050919050565b5f6111b26111ad6111a884611047565b61118f565b611047565b9050919050565b5f6111c382611198565b9050919050565b5f6111d4826111b9565b9050919050565b6111e4816111ca565b82525050565b5f6020820190506111fd5f8301846111db565b92915050565b5f806040838503121561121957611218611043565b5b5f6112268582860161108d565b92505060206112378582860161108d565b9150509250929050565b5f819050919050565b61125381611241565b82525050565b5f60208201905061126c5f83018461124a565b92915050565b61127b81611066565b82525050565b5f6020820190506112945f830184611272565b92915050565b5f6112a4826111b9565b9050919050565b6112b48161129a565b82525050565b5f6020820190506112cd5f8301846112ab565b92915050565b5f815190506112e181611077565b92915050565b5f602082840312156112fc576112fb611043565b5b5f611309848285016112d3565b91505092915050565b5f819050919050565b61132481611312565b82525050565b5f60208201905061133d5f83018461131b565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6040820190506113b05f830185611272565b6113bd6020830184611272565b9392505050565b6113cd816110cc565b81146113d7575f80fd5b50565b5f815190506113e8816113c4565b92915050565b5f6020828403121561140357611402611043565b5b5f611410848285016113da565b91505092915050565b5f819050919050565b61143361142e82611241565b611419565b82525050565b5f6114448285611422565b6020820191506114548284611422565b6020820191508190509392505050565b5f63ffffffff82169050919050565b61147c81611464565b8114611486575f80fd5b50565b5f8151905061149781611473565b92915050565b5f67ffffffffffffffff82169050919050565b6114b98161149d565b81146114c3575f80fd5b50565b5f815190506114d4816114b0565b92915050565b5f805f606084860312156114f1576114f0611043565b5b5f6114fe868287016112d3565b935050602061150f86828701611489565b9250506040611520868287016114c6565b9150509250925092565b5f819050919050565b5f61154d6115486115438461152a565b61118f565b61149d565b9050919050565b61155d81611533565b82525050565b5f61157d6115786115738461152a565b61118f565b611464565b9050919050565b61158d81611563565b82525050565b61159c8161149d565b82525050565b5f60e0820190506115b55f83018a61124a565b81810360208301526115c78189611137565b90506115d66040830188611272565b6115e36060830187611272565b6115f06080830186611554565b6115fd60a0830185611584565b61160a60c0830184611593565b98975050505050505050565b61161f81611241565b8114611629575f80fd5b50565b5f8151905061163a81611616565b92915050565b5f6020828403121561165557611654611043565b5b5f6116628482850161162c565b91505092915050565b5f60a08201905061167e5f83018861124a565b61168b602083018761124a565b6116986040830186611272565b6116a56060830185611272565b6116b26080830184611554565b969550505050505056fea26469706673582212209d8af90115ac87cd7e89fc6bba07881800c0312acfa22d66dd65718d2e00b17e64736f6c6343000819003300000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e0000000000000000000000000635513f179d50a207757e05759cbd106d7dfce8fd49266f604c6bc93ead36965d74c1cf766a3f0f896faa27a2038a75118625c1000000000000000000000000380e926f5d78f21b80a6efef2b3cef9ccc89356b", + "nonce": "0x13", + "chainId": "0xaa36a7" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0xecd1c1", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0xc643d5af5b42aae00933dd0d76df862b2ea4e14e9c2cd6742c7f5f7f66c924ab", + "transactionIndex": "0x3d", + "blockHash": "0x0c13e7c28a4beaf8da7140b25b1d8037eb3b9a009f1b283d80c0dd4bd8f84b00", + "blockNumber": "0x9725ae", + "gasUsed": "0x143c86", + "effectiveGasPrice": "0xa4c8cc", + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "to": null, + "contractAddress": "0x8b82d2af30062e0461c8c3bd1a6ced1df650a5e9" + } + ], + "libraries": [], + "pending": [], + "returns": { + "registrar": { + "internal_type": "contract AddressSubnameRegistrar", + "value": "0x8b82D2aF30062e0461c8C3bd1a6CEd1DF650a5E9" + } + }, + "timestamp": 1766581608807, + "chain": 11155111, + "commit": "c437ed7" +} \ No newline at end of file diff --git a/broadcast/Deploy.s.sol/11155111/deployL1Resolver-latest.json b/broadcast/Deploy.s.sol/11155111/deployL1Resolver-latest.json new file mode 100644 index 0000000..1839f4e --- /dev/null +++ b/broadcast/Deploy.s.sol/11155111/deployL1Resolver-latest.json @@ -0,0 +1,54 @@ +{ + "transactions": [ + { + "hash": "0x6225756eafbb061e5389a06964071312993bb716b723ff69e487d9dc0d3299b8", + "transactionType": "CREATE", + "contractName": "L1ConfigResolver", + "contractAddress": "0x380e926f5d78f21b80a6efef2b3cef9ccc89356b", + "function": null, + "arguments": [ + "0x7F68510F0fD952184ec0b976De429a29A2Ec0FE3", + "0xA66c55a6b76967477af18A03F2f12d52251Dc2C0" + ], + "transaction": { + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "gas": "0x3e69d6", + "value": "0x0", + "input": "0x60c060405234801561000f575f80fd5b506040516139b43803806139b483398181016040528101906100319190610139565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610177565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100cd826100a4565b9050919050565b5f6100de826100c3565b9050919050565b6100ee816100d4565b81146100f8575f80fd5b50565b5f81519050610109816100e5565b92915050565b610118816100c3565b8114610122575f80fd5b50565b5f815190506101338161010f565b92915050565b5f806040838503121561014f5761014e6100a0565b5b5f61015c858286016100fb565b925050602061016d85828601610125565b9150509250929050565b60805160a0516137eb6101c95f395f81816111c6015281816114ae015281816117b40152611acd01525f81816105f8015281816109a701528181610a9f01528181610dc90152610f3b01526137eb5ff3fe608060405234801561000f575f80fd5b50600436106100b2575f3560e01c80637105614d1161006f5780637105614d146101c45780639061b923146101f4578063a52b657e14610224578063bc1c58d114610254578063e31844fe14610284578063e341c27e146102a0576100b2565b806301ffc9a7146100b6578063232826a9146100e65780632b7ac3f3146101165780633026580c146101345780633b3b57de1461016457806359d1d43c14610194575b5f80fd5b6100d060048036038101906100cb91906121a9565b6102be565b6040516100dd91906121ee565b60405180910390f35b61010060048036038101906100fb91906122f3565b61052f565b60405161010d91906123f4565b60405180910390f35b61011e6105f6565b60405161012b919061248e565b60405180910390f35b61014e600480360381019061014991906122f3565b61061a565b60405161015b91906124f9565b60405180910390f35b61017e6004803603810190610179919061254c565b610993565b60405161018b9190612597565b60405180910390f35b6101ae60048036038101906101a99190612605565b610a48565b6040516101bb91906123f4565b60405180910390f35b6101de60048036038101906101d991906122f3565b610b31565b6040516101eb9190612597565b60405180910390f35b61020e60048036038101906102099190612662565b610bb5565b60405161021b91906124f9565b60405180910390f35b61023e600480360381019061023991906122f3565b610e93565b60405161024b91906124f9565b60405180910390f35b61026e6004803603810190610269919061254c565b610f28565b60405161027b91906124f9565b60405180910390f35b61029e60048036038101906102999190612662565b610fcb565b005b6102a86111c4565b6040516102b59190612597565b60405180910390f35b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061038857507f9061b923000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103f057507f3b3b57de000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061045857507ff1cb7e06000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806104c057507f59d1d43c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061052857507fbc1c58d1000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60605f8460ff1614158061056857505f86865f818110610552576105516126e0565b5b90506020028101906105649190612719565b9050145b156105835760405180602001604052805f81525090506105ed565b85855f818110610596576105956126e0565b5b90506020028101906105a89190612719565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505b95945050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60605f8460ff16146106425761063b8383906106369190612791565b6111e8565b905061098a565b5f8383906106509190612791565b9050633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361076e575f87875f8181106106b2576106b16126e0565b5b90506020028101906106c49190612719565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505f815103610739575f6040516020016107219190612597565b6040516020818303038152906040529250505061098a565b806107439061283d565b60601c6040516020016107569190612597565b6040516020818303038152906040529250505061098a565b63f1cb7e0660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036108075786865f8181106107cd576107cc6126e0565b5b90506020028101906107df9190612719565b6040516020016107f09291906128dd565b60405160208183030381529060405291505061098a565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036108a05786865f818110610866576108656126e0565b5b90506020028101906108789190612719565b60405160200161088992919061292b565b60405160208183030381529060405291505061098a565b63bc1c58d160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036109395786865f8181106108ff576108fe6126e0565b5b90506020028101906109119190612719565b6040516020016109229291906128dd565b60405160208183030381529060405291505061098a565b5f67ffffffffffffffff8111156109535761095261294d565b5b6040519080825280601f01601f1916602001820160405280156109855781602001600182028036833780820191505090505b509150505b95945050505050565b5f806109a083603c6114a1565b9050610a427f000000000000000000000000000000000000000000000000000000000000000082637105614d60e01b866040516020016109e09190612989565b6040516020818303038152906040525f67ffffffffffffffff811115610a0957610a0861294d565b5b604051908082528060200260200182016040528015610a3c57816020015b6060815260200190600190039081610a275790505b5061159c565b50919050565b60605f610a988585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050506117a7565b9050610b297f00000000000000000000000000000000000000000000000000000000000000008263232826a960e01b60405180602001604052805f8152505f67ffffffffffffffff811115610af057610aef61294d565b5b604051908082528060200260200182016040528015610b2357816020015b6060815260200190600190039081610b0e5790505b5061159c565b509392505050565b5f808460ff16141580610b6957505f86865f818110610b5357610b526126e0565b5b9050602002810190610b659190612719565b9050145b15610b76575f9050610bac565b85855f818110610b8957610b886126e0565b5b9050602002810190610b9b9190612719565b90610ba691906129a2565b60601c90505b95945050505050565b60605f838390610bc59190612791565b90505f633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c5f575063bc1c58d160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15610c8b5784846004908092610c7793929190612a08565b810190610c84919061254c565b9050610db6565b63f1cb7e0660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610d015784846004908092610cea93929190612a08565b810190610cf79190612a75565b5080915050610db5565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610d775784846004908092610d6093929190612a08565b810190610d6d9190612ba0565b5080915050610db4565b816040517fa519a14f000000000000000000000000000000000000000000000000000000008152600401610dab9190612c09565b60405180910390fd5b5b5b5f610dc28287876118a2565b9050610e887f000000000000000000000000000000000000000000000000000000000000000082633026580c60e01b89898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050505f67ffffffffffffffff811115610e4f57610e4e61294d565b5b604051908082528060200260200182016040528015610e8257816020015b6060815260200190600190039081610e6d5790505b5061159c565b505050949350505050565b60605f8460ff1614610eb55760405180602001604052805f8152509050610f1f565b85855f818110610ec857610ec76126e0565b5b9050602002810190610eda9190612719565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505b95945050505050565b60605f610f3483611ac0565b9050610fc57f00000000000000000000000000000000000000000000000000000000000000008263a52b657e60e01b60405180602001604052805f8152505f67ffffffffffffffff811115610f8c57610f8b61294d565b5b604051908082528060200260200182016040528015610fbf57816020015b6060815260200190600190039081610faa5790505b5061159c565b50919050565b5f601f858590501614611027575f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050509050805160208201fd5b5f82828101906110379190612e35565b90505f80825f015173ffffffffffffffffffffffffffffffffffffffff1663e3d1666e846020015185604001518a8a6040518563ffffffff1660e01b81526004016110859493929190612eeb565b5f60405180830381865afa15801561109f573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906110c79190613097565b915091505f803073ffffffffffffffffffffffffffffffffffffffff16856060015185858860800151604051602401611102939291906131bb565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161116c9190613238565b5f60405180830381855afa9150503d805f81146111a4576040519150601f19603f3d011682016040523d82523d5f602084013e6111a9565b606091505b509150915081156111bc57805160208201f35b805160208201fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b6060633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361125d575f6040516020016112479190612597565b604051602081830303815290604052905061149c565b63f1cb7e0660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361131c575f67ffffffffffffffff8111156112c3576112c261294d565b5b6040519080825280601f01601f1916602001820160405280156112f55781602001600182028036833780820191505090505b5060405160200161130691906124f9565b604051602081830303815290604052905061149c565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361138d5760405160200161137790613271565b604051602081830303815290604052905061149c565b63bc1c58d160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361144c575f67ffffffffffffffff8111156113f3576113f261294d565b5b6040519080825280601f01601f1916602001820160405280156114255781602001600182028036833780820191505090505b5060405160200161143691906124f9565b604051602081830303815290604052905061149c565b5f67ffffffffffffffff8111156114665761146561294d565b5b6040519080825280601f01601f1916602001820160405280156114985781602001600182028036833780820191505090505b5090505b919050565b6114a9612130565b6114e57f00000000000000000000000000000000000000000000000000000000000000006114d76001611b9d565b611bc690919063ffffffff16565b905061151c611517611512856115045f86611bf190919063ffffffff16565b611c1c90919063ffffffff16565b611c41565b611c64565b9050611532600282611bf190919063ffffffff16565b905061153d81611c41565b905061155a6115558483611c1c90919063ffffffff16565b611c41565b90506115776115728383611c8790919063ffffffff16565b611c41565b90506115945f61158683611d68565b611d8b90919063ffffffff16565b905092915050565b5f8573ffffffffffffffffffffffffffffffffffffffff166387c484fe6040518163ffffffff1660e01b81526004015f60405180830381865afa1580156115e5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061160d919061328f565b90505f82510361168a578573ffffffffffffffffffffffffffffffffffffffff1663b50f2fbc6040518163ffffffff1660e01b81526004015f60405180830381865afa15801561165f573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906116879190613422565b91505b3082828760405160240161169f929190613469565b6040516020818303038152906040526331c1980f60e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505063e31844fe60e01b6040518060a001604052808b73ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018a8152602001897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001888152506040516020016117589190613564565b6040516020818303038152906040526040517f556f183000000000000000000000000000000000000000000000000000000000815260040161179e959493929190613687565b60405180910390fd5b6117af612130565b6117eb7f00000000000000000000000000000000000000000000000000000000000000006117dd6001611b9d565b611bc690919063ffffffff16565b905061182261181d6118188561180a5f86611bf190919063ffffffff16565b611c1c90919063ffffffff16565b611c41565b611c64565b9050611838600a82611bf190919063ffffffff16565b905061184381611c41565b905061186061185b8483611c1c90919063ffffffff16565b611c41565b905061187d6118788383611db990919063ffffffff16565b611c41565b905061189a5f61188c83611d68565b611d8b90919063ffffffff16565b905092915050565b6118aa612130565b5f8383906118b89190612791565b9050633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036119195761191185603c6114a1565b915050611ab9565b63f1cb7e0660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361199c575f8484600490809261197993929190612a08565b8101906119869190612a75565b91505061199386826114a1565b92505050611ab9565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611a1f575f848460049080926119fc93929190612a08565b810190611a099190612ba0565b915050611a1686826117a7565b92505050611ab9565b63bc1c58d160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611a7c57611a7485611ac0565b915050611ab9565b806040517fa519a14f000000000000000000000000000000000000000000000000000000008152600401611ab09190612c09565b60405180910390fd5b9392505050565b611ac8612130565b611b047f0000000000000000000000000000000000000000000000000000000000000000611af66001611b9d565b611bc690919063ffffffff16565b9050611b3b611b36611b3184611b235f86611bf190919063ffffffff16565b611c1c90919063ffffffff16565b611c41565b611c64565b9050611b51600382611bf190919063ffffffff16565b9050611b5c81611c41565b9050611b79611b748383611c1c90919063ffffffff16565b611c41565b9050611b965f611b8883611d68565b611d8b90919063ffffffff16565b9050919050565b611ba5612130565b611bbf82611bb1611ddc565b611e4e90919063ffffffff16565b9050919050565b611bce612130565b611be9611be48385611eb690919063ffffffff16565b611eef565b905092915050565b611bf9612130565b611c14611c0f8385611c8790919063ffffffff16565b611f12565b905092915050565b611c24612130565b611c39825f1c84611c8790919063ffffffff16565b905092915050565b611c49612130565b611c5d604883611e4e90919063ffffffff16565b9050919050565b611c6c612130565b611c80603c83611e4e90919063ffffffff16565b9050919050565b611c8f612130565b5f8203611cb057611ca95f84611e4e90919063ffffffff16565b9050611d62565b5f611cba83611f35565b905060038160ff16901b60ff1683901b9250806020611cd9919061371a565b9050611cf9815f611cea919061374e565b85611e4e90919063ffffffff16565b505f845f015190506120008260ff168251611d149190613782565b1115611d4c576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051848160208401015282810182525084925050505b92915050565b611d70612130565b611d84603d83611e4e90919063ffffffff16565b9050919050565b611d93612130565b611db1611dac8360ff1685611c8790919063ffffffff16565b612028565b905092915050565b611dc1612130565b611dd4828461204b90919063ffffffff16565b905092915050565b611de4612130565b5f61200067ffffffffffffffff811115611e0157611e0061294d565b5b6040519080825280601f01601f191660200182016040528015611e335781602001600182028036833780820191505090505b5090505f815260405180602001604052808281525091505090565b611e56612130565b5f835f015190505f815190506120008110611e9d576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001810182528381602084010153849250505092915050565b611ebe612130565b611ee78273ffffffffffffffffffffffffffffffffffffffff1684611c8790919063ffffffff16565b905092915050565b611ef7612130565b611f0b603283611e4e90919063ffffffff16565b9050919050565b611f1a612130565b611f2e604683611e4e90919063ffffffff16565b9050919050565b5f700100000000000000000000000000000000821015611f5d57608082901b91506010811790505b7801000000000000000000000000000000000000000000000000821015611f8c57604082901b91506008811790505b7c0100000000000000000000000000000000000000000000000000000000821015611fbf57602082901b91506004811790505b7e01000000000000000000000000000000000000000000000000000000000000821015611ff457601082901b91506002811790505b7f0100000000000000000000000000000000000000000000000000000000000000821015612023576001811790505b919050565b612030612130565b612044603383611e4e90919063ffffffff16565b9050919050565b612053612130565b61208c8261207e8451612070602888611e4e90919063ffffffff16565b611c8790919063ffffffff16565b61209490919063ffffffff16565b905092915050565b61209c612130565b5f835f015190506120008351855f0151516120b79190613782565b11156120ef576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051602082010160208401845181015b8082101561211c57815183526020820191506020830192506120ff565b508451835101835250508391505092915050565b6040518060200160405280606081525090565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61218881612154565b8114612192575f80fd5b50565b5f813590506121a38161217f565b92915050565b5f602082840312156121be576121bd61214c565b5b5f6121cb84828501612195565b91505092915050565b5f8115159050919050565b6121e8816121d4565b82525050565b5f6020820190506122015f8301846121df565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261222857612227612207565b5b8235905067ffffffffffffffff8111156122455761224461220b565b5b6020830191508360208202830111156122615761226061220f565b5b9250929050565b5f60ff82169050919050565b61227d81612268565b8114612287575f80fd5b50565b5f8135905061229881612274565b92915050565b5f8083601f8401126122b3576122b2612207565b5b8235905067ffffffffffffffff8111156122d0576122cf61220b565b5b6020830191508360018202830111156122ec576122eb61220f565b5b9250929050565b5f805f805f6060868803121561230c5761230b61214c565b5b5f86013567ffffffffffffffff81111561232957612328612150565b5b61233588828901612213565b955095505060206123488882890161228a565b935050604086013567ffffffffffffffff81111561236957612368612150565b5b6123758882890161229e565b92509250509295509295909350565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6123c682612384565b6123d0818561238e565b93506123e081856020860161239e565b6123e9816123ac565b840191505092915050565b5f6020820190508181035f83015261240c81846123bc565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f819050919050565b5f61245661245161244c84612414565b612433565b612414565b9050919050565b5f6124678261243c565b9050919050565b5f6124788261245d565b9050919050565b6124888161246e565b82525050565b5f6020820190506124a15f83018461247f565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f6124cb826124a7565b6124d581856124b1565b93506124e581856020860161239e565b6124ee816123ac565b840191505092915050565b5f6020820190508181035f83015261251181846124c1565b905092915050565b5f819050919050565b61252b81612519565b8114612535575f80fd5b50565b5f8135905061254681612522565b92915050565b5f602082840312156125615761256061214c565b5b5f61256e84828501612538565b91505092915050565b5f61258182612414565b9050919050565b61259181612577565b82525050565b5f6020820190506125aa5f830184612588565b92915050565b5f8083601f8401126125c5576125c4612207565b5b8235905067ffffffffffffffff8111156125e2576125e161220b565b5b6020830191508360018202830111156125fe576125fd61220f565b5b9250929050565b5f805f6040848603121561261c5761261b61214c565b5b5f61262986828701612538565b935050602084013567ffffffffffffffff81111561264a57612649612150565b5b612656868287016125b0565b92509250509250925092565b5f805f806040858703121561267a5761267961214c565b5b5f85013567ffffffffffffffff81111561269757612696612150565b5b6126a38782880161229e565b9450945050602085013567ffffffffffffffff8111156126c6576126c5612150565b5b6126d28782880161229e565b925092505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f80fd5b5f80fd5b5f80fd5b5f80833560016020038436030381126127355761273461270d565b5b80840192508235915067ffffffffffffffff82111561275757612756612711565b5b60208301925060018202360383131561277357612772612715565b5b509250929050565b5f82905092915050565b5f82821b905092915050565b5f61279c838361277b565b826127a78135612154565b925060048210156127e7576127e27fffffffff0000000000000000000000000000000000000000000000000000000083600403600802612785565b831692505b505092915050565b5f819050602082019050919050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f61283482516127fe565b80915050919050565b5f612847826124a7565b82612851846127ef565b905061285c81612829565b9250601482101561289c576128977fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802612785565b831692505b5050919050565b828183375f83830152505050565b5f6128bc83856124b1565b93506128c98385846128a3565b6128d2836123ac565b840190509392505050565b5f6020820190508181035f8301526128f68184866128b1565b90509392505050565b5f61290a838561238e565b93506129178385846128a3565b612920836123ac565b840190509392505050565b5f6020820190508181035f8301526129448184866128ff565b90509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61298381612519565b82525050565b5f60208201905061299c5f83018461297a565b92915050565b5f6129ad838361277b565b826129b881356127fe565b925060148210156129f8576129f37fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802612785565b831692505b505092915050565b5f80fd5b5f80fd5b5f8085851115612a1b57612a1a612a00565b5b83861115612a2c57612a2b612a04565b5b6001850283019150848603905094509492505050565b5f819050919050565b612a5481612a42565b8114612a5e575f80fd5b50565b5f81359050612a6f81612a4b565b92915050565b5f8060408385031215612a8b57612a8a61214c565b5b5f612a9885828601612538565b9250506020612aa985828601612a61565b9150509250929050565b5f80fd5b612ac0826123ac565b810181811067ffffffffffffffff82111715612adf57612ade61294d565b5b80604052505050565b5f612af1612143565b9050612afd8282612ab7565b919050565b5f67ffffffffffffffff821115612b1c57612b1b61294d565b5b612b25826123ac565b9050602081019050919050565b5f612b44612b3f84612b02565b612ae8565b905082815260208101848484011115612b6057612b5f612ab3565b5b612b6b8482856128a3565b509392505050565b5f82601f830112612b8757612b86612207565b5b8135612b97848260208601612b32565b91505092915050565b5f8060408385031215612bb657612bb561214c565b5b5f612bc385828601612538565b925050602083013567ffffffffffffffff811115612be457612be3612150565b5b612bf085828601612b73565b9150509250929050565b612c0381612154565b82525050565b5f602082019050612c1c5f830184612bfa565b92915050565b5f80fd5b5f80fd5b5f612c3482612577565b9050919050565b612c4481612c2a565b8114612c4e575f80fd5b50565b5f81359050612c5f81612c3b565b92915050565b5f67ffffffffffffffff821115612c7f57612c7e61294d565b5b612c88826123ac565b9050602081019050919050565b5f612ca7612ca284612c65565b612ae8565b905082815260208101848484011115612cc357612cc2612ab3565b5b612cce8482856128a3565b509392505050565b5f82601f830112612cea57612ce9612207565b5b8135612cfa848260208601612c95565b91505092915050565b5f60208284031215612d1857612d17612c22565b5b612d226020612ae8565b90505f82013567ffffffffffffffff811115612d4157612d40612c26565b5b612d4d84828501612cd6565b5f8301525092915050565b5f60a08284031215612d6d57612d6c612c22565b5b612d7760a0612ae8565b90505f612d8684828501612c51565b5f83015250602082013567ffffffffffffffff811115612da957612da8612c26565b5b612db584828501612cd6565b602083015250604082013567ffffffffffffffff811115612dd957612dd8612c26565b5b612de584828501612d03565b6040830152506060612df984828501612195565b606083015250608082013567ffffffffffffffff811115612e1d57612e1c612c26565b5b612e2984828501612cd6565b60808301525092915050565b5f60208284031215612e4a57612e4961214c565b5b5f82013567ffffffffffffffff811115612e6757612e66612150565b5b612e7384828501612d58565b91505092915050565b5f82825260208201905092915050565b5f612e96826124a7565b612ea08185612e7c565b9350612eb081856020860161239e565b612eb9816123ac565b840191505092915050565b5f602083015f8301518482035f860152612ede8282612e8c565b9150508091505092915050565b5f6060820190508181035f830152612f0381876124c1565b90508181036020830152612f178186612ec4565b90508181036040830152612f2c8184866128b1565b905095945050505050565b5f67ffffffffffffffff821115612f5157612f5061294d565b5b602082029050602081019050919050565b5f612f74612f6f84612c65565b612ae8565b905082815260208101848484011115612f9057612f8f612ab3565b5b612f9b84828561239e565b509392505050565b5f82601f830112612fb757612fb6612207565b5b8151612fc7848260208601612f62565b91505092915050565b5f612fe2612fdd84612f37565b612ae8565b905080838252602082019050602084028301858111156130055761300461220f565b5b835b8181101561304c57805167ffffffffffffffff81111561302a57613029612207565b5b8086016130378982612fa3565b85526020850194505050602081019050613007565b5050509392505050565b5f82601f83011261306a57613069612207565b5b815161307a848260208601612fd0565b91505092915050565b5f8151905061309181612274565b92915050565b5f80604083850312156130ad576130ac61214c565b5b5f83015167ffffffffffffffff8111156130ca576130c9612150565b5b6130d685828601613056565b92505060206130e785828601613083565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f6131258383612e8c565b905092915050565b5f602082019050919050565b5f613143826130f1565b61314d81856130fb565b93508360208202850161315f8561310b565b805f5b8581101561319a578484038952815161317b858261311a565b94506131868361312d565b925060208a01995050600181019050613162565b50829750879550505050505092915050565b6131b581612268565b82525050565b5f6060820190508181035f8301526131d38186613139565b90506131e260208301856131ac565b81810360408301526131f481846124c1565b9050949350505050565b5f81905092915050565b5f613212826124a7565b61321c81856131fe565b935061322c81856020860161239e565b80840191505092915050565b5f6132438284613208565b915081905092915050565b50565b5f61325c5f8361238e565b91506132678261324e565b5f82019050919050565b5f6020820190508181035f83015261328881613251565b9050919050565b5f602082840312156132a4576132a361214c565b5b5f82015167ffffffffffffffff8111156132c1576132c0612150565b5b6132cd84828501612fa3565b91505092915050565b5f67ffffffffffffffff8211156132f0576132ef61294d565b5b602082029050602081019050919050565b5f61331361330e84612b02565b612ae8565b90508281526020810184848401111561332f5761332e612ab3565b5b61333a84828561239e565b509392505050565b5f82601f83011261335657613355612207565b5b8151613366848260208601613301565b91505092915050565b5f61338161337c846132d6565b612ae8565b905080838252602082019050602084028301858111156133a4576133a361220f565b5b835b818110156133eb57805167ffffffffffffffff8111156133c9576133c8612207565b5b8086016133d68982613342565b855260208501945050506020810190506133a6565b5050509392505050565b5f82601f83011261340957613408612207565b5b815161341984826020860161336f565b91505092915050565b5f602082840312156134375761343661214c565b5b5f82015167ffffffffffffffff81111561345457613453612150565b5b613460848285016133f5565b91505092915050565b5f6040820190508181035f83015261348181856124c1565b905081810360208301526134958184612ec4565b90509392505050565b6134a78161246e565b82525050565b5f602083015f8301518482035f8601526134c78282612e8c565b9150508091505092915050565b6134dd81612154565b82525050565b5f60a083015f8301516134f85f86018261349e565b50602083015184820360208601526135108282612e8c565b9150506040830151848203604086015261352a82826134ad565b915050606083015161353f60608601826134d4565b50608083015184820360808601526135578282612e8c565b9150508091505092915050565b5f6020820190508181035f83015261357c81846134e3565b905092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f82825260208201905092915050565b5f6135c782612384565b6135d181856135ad565b93506135e181856020860161239e565b6135ea816123ac565b840191505092915050565b5f61360083836135bd565b905092915050565b5f602082019050919050565b5f61361e82613584565b613628818561358e565b93508360208202850161363a8561359e565b805f5b85811015613675578484038952815161365685826135f5565b945061366183613608565b925060208a0199505060018101905061363d565b50829750879550505050505092915050565b5f60a08201905061369a5f830188612588565b81810360208301526136ac8187613614565b905081810360408301526136c081866124c1565b90506136cf6060830185612bfa565b81810360808301526136e181846124c1565b90509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61372482612268565b915061372f83612268565b9250828203905060ff811115613748576137476136ed565b5b92915050565b5f61375882612268565b915061376383612268565b9250828201905060ff81111561377c5761377b6136ed565b5b92915050565b5f61378c82612a42565b915061379783612a42565b92508282019050808211156137af576137ae6136ed565b5b9291505056fea2646970667358221220fc3387b0a1b580f3ece0e2cdbea2825a1c9f9869d63dc29ded4a4b1ee4d76d3364736f6c634300081900330000000000000000000000007f68510f0fd952184ec0b976de429a29a2ec0fe3000000000000000000000000a66c55a6b76967477af18a03f2f12d52251dc2c0", + "nonce": "0x12", + "chainId": "0xaa36a7" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x265b371", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0x6225756eafbb061e5389a06964071312993bb716b723ff69e487d9dc0d3299b8", + "transactionIndex": "0xbd", + "blockHash": "0xeafc533b11906cc1da0c5bd3a868639d97a30a1fc34236b4d70f14aa80b2b807", + "blockNumber": "0x9724f5", + "gasUsed": "0x3002a5", + "effectiveGasPrice": "0x22e4b39", + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "to": null, + "contractAddress": "0x380e926f5d78f21b80a6efef2b3cef9ccc89356b" + } + ], + "libraries": [], + "pending": [], + "returns": { + "resolver": { + "internal_type": "contract L1ConfigResolver", + "value": "0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B" + } + }, + "timestamp": 1766579077262, + "chain": 11155111, + "commit": "c437ed7" +} \ No newline at end of file diff --git a/broadcast/Deploy.s.sol/11155111/run-1766579077262.json b/broadcast/Deploy.s.sol/11155111/run-1766579077262.json new file mode 100644 index 0000000..1839f4e --- /dev/null +++ b/broadcast/Deploy.s.sol/11155111/run-1766579077262.json @@ -0,0 +1,54 @@ +{ + "transactions": [ + { + "hash": "0x6225756eafbb061e5389a06964071312993bb716b723ff69e487d9dc0d3299b8", + "transactionType": "CREATE", + "contractName": "L1ConfigResolver", + "contractAddress": "0x380e926f5d78f21b80a6efef2b3cef9ccc89356b", + "function": null, + "arguments": [ + "0x7F68510F0fD952184ec0b976De429a29A2Ec0FE3", + "0xA66c55a6b76967477af18A03F2f12d52251Dc2C0" + ], + "transaction": { + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "gas": "0x3e69d6", + "value": "0x0", + "input": "0x60c060405234801561000f575f80fd5b506040516139b43803806139b483398181016040528101906100319190610139565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610177565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100cd826100a4565b9050919050565b5f6100de826100c3565b9050919050565b6100ee816100d4565b81146100f8575f80fd5b50565b5f81519050610109816100e5565b92915050565b610118816100c3565b8114610122575f80fd5b50565b5f815190506101338161010f565b92915050565b5f806040838503121561014f5761014e6100a0565b5b5f61015c858286016100fb565b925050602061016d85828601610125565b9150509250929050565b60805160a0516137eb6101c95f395f81816111c6015281816114ae015281816117b40152611acd01525f81816105f8015281816109a701528181610a9f01528181610dc90152610f3b01526137eb5ff3fe608060405234801561000f575f80fd5b50600436106100b2575f3560e01c80637105614d1161006f5780637105614d146101c45780639061b923146101f4578063a52b657e14610224578063bc1c58d114610254578063e31844fe14610284578063e341c27e146102a0576100b2565b806301ffc9a7146100b6578063232826a9146100e65780632b7ac3f3146101165780633026580c146101345780633b3b57de1461016457806359d1d43c14610194575b5f80fd5b6100d060048036038101906100cb91906121a9565b6102be565b6040516100dd91906121ee565b60405180910390f35b61010060048036038101906100fb91906122f3565b61052f565b60405161010d91906123f4565b60405180910390f35b61011e6105f6565b60405161012b919061248e565b60405180910390f35b61014e600480360381019061014991906122f3565b61061a565b60405161015b91906124f9565b60405180910390f35b61017e6004803603810190610179919061254c565b610993565b60405161018b9190612597565b60405180910390f35b6101ae60048036038101906101a99190612605565b610a48565b6040516101bb91906123f4565b60405180910390f35b6101de60048036038101906101d991906122f3565b610b31565b6040516101eb9190612597565b60405180910390f35b61020e60048036038101906102099190612662565b610bb5565b60405161021b91906124f9565b60405180910390f35b61023e600480360381019061023991906122f3565b610e93565b60405161024b91906124f9565b60405180910390f35b61026e6004803603810190610269919061254c565b610f28565b60405161027b91906124f9565b60405180910390f35b61029e60048036038101906102999190612662565b610fcb565b005b6102a86111c4565b6040516102b59190612597565b60405180910390f35b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061038857507f9061b923000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103f057507f3b3b57de000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061045857507ff1cb7e06000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806104c057507f59d1d43c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061052857507fbc1c58d1000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60605f8460ff1614158061056857505f86865f818110610552576105516126e0565b5b90506020028101906105649190612719565b9050145b156105835760405180602001604052805f81525090506105ed565b85855f818110610596576105956126e0565b5b90506020028101906105a89190612719565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505b95945050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60605f8460ff16146106425761063b8383906106369190612791565b6111e8565b905061098a565b5f8383906106509190612791565b9050633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361076e575f87875f8181106106b2576106b16126e0565b5b90506020028101906106c49190612719565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505f815103610739575f6040516020016107219190612597565b6040516020818303038152906040529250505061098a565b806107439061283d565b60601c6040516020016107569190612597565b6040516020818303038152906040529250505061098a565b63f1cb7e0660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036108075786865f8181106107cd576107cc6126e0565b5b90506020028101906107df9190612719565b6040516020016107f09291906128dd565b60405160208183030381529060405291505061098a565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036108a05786865f818110610866576108656126e0565b5b90506020028101906108789190612719565b60405160200161088992919061292b565b60405160208183030381529060405291505061098a565b63bc1c58d160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036109395786865f8181106108ff576108fe6126e0565b5b90506020028101906109119190612719565b6040516020016109229291906128dd565b60405160208183030381529060405291505061098a565b5f67ffffffffffffffff8111156109535761095261294d565b5b6040519080825280601f01601f1916602001820160405280156109855781602001600182028036833780820191505090505b509150505b95945050505050565b5f806109a083603c6114a1565b9050610a427f000000000000000000000000000000000000000000000000000000000000000082637105614d60e01b866040516020016109e09190612989565b6040516020818303038152906040525f67ffffffffffffffff811115610a0957610a0861294d565b5b604051908082528060200260200182016040528015610a3c57816020015b6060815260200190600190039081610a275790505b5061159c565b50919050565b60605f610a988585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050506117a7565b9050610b297f00000000000000000000000000000000000000000000000000000000000000008263232826a960e01b60405180602001604052805f8152505f67ffffffffffffffff811115610af057610aef61294d565b5b604051908082528060200260200182016040528015610b2357816020015b6060815260200190600190039081610b0e5790505b5061159c565b509392505050565b5f808460ff16141580610b6957505f86865f818110610b5357610b526126e0565b5b9050602002810190610b659190612719565b9050145b15610b76575f9050610bac565b85855f818110610b8957610b886126e0565b5b9050602002810190610b9b9190612719565b90610ba691906129a2565b60601c90505b95945050505050565b60605f838390610bc59190612791565b90505f633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c5f575063bc1c58d160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15610c8b5784846004908092610c7793929190612a08565b810190610c84919061254c565b9050610db6565b63f1cb7e0660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610d015784846004908092610cea93929190612a08565b810190610cf79190612a75565b5080915050610db5565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610d775784846004908092610d6093929190612a08565b810190610d6d9190612ba0565b5080915050610db4565b816040517fa519a14f000000000000000000000000000000000000000000000000000000008152600401610dab9190612c09565b60405180910390fd5b5b5b5f610dc28287876118a2565b9050610e887f000000000000000000000000000000000000000000000000000000000000000082633026580c60e01b89898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050505f67ffffffffffffffff811115610e4f57610e4e61294d565b5b604051908082528060200260200182016040528015610e8257816020015b6060815260200190600190039081610e6d5790505b5061159c565b505050949350505050565b60605f8460ff1614610eb55760405180602001604052805f8152509050610f1f565b85855f818110610ec857610ec76126e0565b5b9050602002810190610eda9190612719565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505b95945050505050565b60605f610f3483611ac0565b9050610fc57f00000000000000000000000000000000000000000000000000000000000000008263a52b657e60e01b60405180602001604052805f8152505f67ffffffffffffffff811115610f8c57610f8b61294d565b5b604051908082528060200260200182016040528015610fbf57816020015b6060815260200190600190039081610faa5790505b5061159c565b50919050565b5f601f858590501614611027575f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050509050805160208201fd5b5f82828101906110379190612e35565b90505f80825f015173ffffffffffffffffffffffffffffffffffffffff1663e3d1666e846020015185604001518a8a6040518563ffffffff1660e01b81526004016110859493929190612eeb565b5f60405180830381865afa15801561109f573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906110c79190613097565b915091505f803073ffffffffffffffffffffffffffffffffffffffff16856060015185858860800151604051602401611102939291906131bb565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161116c9190613238565b5f60405180830381855afa9150503d805f81146111a4576040519150601f19603f3d011682016040523d82523d5f602084013e6111a9565b606091505b509150915081156111bc57805160208201f35b805160208201fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b6060633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361125d575f6040516020016112479190612597565b604051602081830303815290604052905061149c565b63f1cb7e0660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361131c575f67ffffffffffffffff8111156112c3576112c261294d565b5b6040519080825280601f01601f1916602001820160405280156112f55781602001600182028036833780820191505090505b5060405160200161130691906124f9565b604051602081830303815290604052905061149c565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361138d5760405160200161137790613271565b604051602081830303815290604052905061149c565b63bc1c58d160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361144c575f67ffffffffffffffff8111156113f3576113f261294d565b5b6040519080825280601f01601f1916602001820160405280156114255781602001600182028036833780820191505090505b5060405160200161143691906124f9565b604051602081830303815290604052905061149c565b5f67ffffffffffffffff8111156114665761146561294d565b5b6040519080825280601f01601f1916602001820160405280156114985781602001600182028036833780820191505090505b5090505b919050565b6114a9612130565b6114e57f00000000000000000000000000000000000000000000000000000000000000006114d76001611b9d565b611bc690919063ffffffff16565b905061151c611517611512856115045f86611bf190919063ffffffff16565b611c1c90919063ffffffff16565b611c41565b611c64565b9050611532600282611bf190919063ffffffff16565b905061153d81611c41565b905061155a6115558483611c1c90919063ffffffff16565b611c41565b90506115776115728383611c8790919063ffffffff16565b611c41565b90506115945f61158683611d68565b611d8b90919063ffffffff16565b905092915050565b5f8573ffffffffffffffffffffffffffffffffffffffff166387c484fe6040518163ffffffff1660e01b81526004015f60405180830381865afa1580156115e5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061160d919061328f565b90505f82510361168a578573ffffffffffffffffffffffffffffffffffffffff1663b50f2fbc6040518163ffffffff1660e01b81526004015f60405180830381865afa15801561165f573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906116879190613422565b91505b3082828760405160240161169f929190613469565b6040516020818303038152906040526331c1980f60e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505063e31844fe60e01b6040518060a001604052808b73ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018a8152602001897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001888152506040516020016117589190613564565b6040516020818303038152906040526040517f556f183000000000000000000000000000000000000000000000000000000000815260040161179e959493929190613687565b60405180910390fd5b6117af612130565b6117eb7f00000000000000000000000000000000000000000000000000000000000000006117dd6001611b9d565b611bc690919063ffffffff16565b905061182261181d6118188561180a5f86611bf190919063ffffffff16565b611c1c90919063ffffffff16565b611c41565b611c64565b9050611838600a82611bf190919063ffffffff16565b905061184381611c41565b905061186061185b8483611c1c90919063ffffffff16565b611c41565b905061187d6118788383611db990919063ffffffff16565b611c41565b905061189a5f61188c83611d68565b611d8b90919063ffffffff16565b905092915050565b6118aa612130565b5f8383906118b89190612791565b9050633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036119195761191185603c6114a1565b915050611ab9565b63f1cb7e0660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361199c575f8484600490809261197993929190612a08565b8101906119869190612a75565b91505061199386826114a1565b92505050611ab9565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611a1f575f848460049080926119fc93929190612a08565b810190611a099190612ba0565b915050611a1686826117a7565b92505050611ab9565b63bc1c58d160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611a7c57611a7485611ac0565b915050611ab9565b806040517fa519a14f000000000000000000000000000000000000000000000000000000008152600401611ab09190612c09565b60405180910390fd5b9392505050565b611ac8612130565b611b047f0000000000000000000000000000000000000000000000000000000000000000611af66001611b9d565b611bc690919063ffffffff16565b9050611b3b611b36611b3184611b235f86611bf190919063ffffffff16565b611c1c90919063ffffffff16565b611c41565b611c64565b9050611b51600382611bf190919063ffffffff16565b9050611b5c81611c41565b9050611b79611b748383611c1c90919063ffffffff16565b611c41565b9050611b965f611b8883611d68565b611d8b90919063ffffffff16565b9050919050565b611ba5612130565b611bbf82611bb1611ddc565b611e4e90919063ffffffff16565b9050919050565b611bce612130565b611be9611be48385611eb690919063ffffffff16565b611eef565b905092915050565b611bf9612130565b611c14611c0f8385611c8790919063ffffffff16565b611f12565b905092915050565b611c24612130565b611c39825f1c84611c8790919063ffffffff16565b905092915050565b611c49612130565b611c5d604883611e4e90919063ffffffff16565b9050919050565b611c6c612130565b611c80603c83611e4e90919063ffffffff16565b9050919050565b611c8f612130565b5f8203611cb057611ca95f84611e4e90919063ffffffff16565b9050611d62565b5f611cba83611f35565b905060038160ff16901b60ff1683901b9250806020611cd9919061371a565b9050611cf9815f611cea919061374e565b85611e4e90919063ffffffff16565b505f845f015190506120008260ff168251611d149190613782565b1115611d4c576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051848160208401015282810182525084925050505b92915050565b611d70612130565b611d84603d83611e4e90919063ffffffff16565b9050919050565b611d93612130565b611db1611dac8360ff1685611c8790919063ffffffff16565b612028565b905092915050565b611dc1612130565b611dd4828461204b90919063ffffffff16565b905092915050565b611de4612130565b5f61200067ffffffffffffffff811115611e0157611e0061294d565b5b6040519080825280601f01601f191660200182016040528015611e335781602001600182028036833780820191505090505b5090505f815260405180602001604052808281525091505090565b611e56612130565b5f835f015190505f815190506120008110611e9d576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001810182528381602084010153849250505092915050565b611ebe612130565b611ee78273ffffffffffffffffffffffffffffffffffffffff1684611c8790919063ffffffff16565b905092915050565b611ef7612130565b611f0b603283611e4e90919063ffffffff16565b9050919050565b611f1a612130565b611f2e604683611e4e90919063ffffffff16565b9050919050565b5f700100000000000000000000000000000000821015611f5d57608082901b91506010811790505b7801000000000000000000000000000000000000000000000000821015611f8c57604082901b91506008811790505b7c0100000000000000000000000000000000000000000000000000000000821015611fbf57602082901b91506004811790505b7e01000000000000000000000000000000000000000000000000000000000000821015611ff457601082901b91506002811790505b7f0100000000000000000000000000000000000000000000000000000000000000821015612023576001811790505b919050565b612030612130565b612044603383611e4e90919063ffffffff16565b9050919050565b612053612130565b61208c8261207e8451612070602888611e4e90919063ffffffff16565b611c8790919063ffffffff16565b61209490919063ffffffff16565b905092915050565b61209c612130565b5f835f015190506120008351855f0151516120b79190613782565b11156120ef576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051602082010160208401845181015b8082101561211c57815183526020820191506020830192506120ff565b508451835101835250508391505092915050565b6040518060200160405280606081525090565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61218881612154565b8114612192575f80fd5b50565b5f813590506121a38161217f565b92915050565b5f602082840312156121be576121bd61214c565b5b5f6121cb84828501612195565b91505092915050565b5f8115159050919050565b6121e8816121d4565b82525050565b5f6020820190506122015f8301846121df565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261222857612227612207565b5b8235905067ffffffffffffffff8111156122455761224461220b565b5b6020830191508360208202830111156122615761226061220f565b5b9250929050565b5f60ff82169050919050565b61227d81612268565b8114612287575f80fd5b50565b5f8135905061229881612274565b92915050565b5f8083601f8401126122b3576122b2612207565b5b8235905067ffffffffffffffff8111156122d0576122cf61220b565b5b6020830191508360018202830111156122ec576122eb61220f565b5b9250929050565b5f805f805f6060868803121561230c5761230b61214c565b5b5f86013567ffffffffffffffff81111561232957612328612150565b5b61233588828901612213565b955095505060206123488882890161228a565b935050604086013567ffffffffffffffff81111561236957612368612150565b5b6123758882890161229e565b92509250509295509295909350565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6123c682612384565b6123d0818561238e565b93506123e081856020860161239e565b6123e9816123ac565b840191505092915050565b5f6020820190508181035f83015261240c81846123bc565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f819050919050565b5f61245661245161244c84612414565b612433565b612414565b9050919050565b5f6124678261243c565b9050919050565b5f6124788261245d565b9050919050565b6124888161246e565b82525050565b5f6020820190506124a15f83018461247f565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f6124cb826124a7565b6124d581856124b1565b93506124e581856020860161239e565b6124ee816123ac565b840191505092915050565b5f6020820190508181035f83015261251181846124c1565b905092915050565b5f819050919050565b61252b81612519565b8114612535575f80fd5b50565b5f8135905061254681612522565b92915050565b5f602082840312156125615761256061214c565b5b5f61256e84828501612538565b91505092915050565b5f61258182612414565b9050919050565b61259181612577565b82525050565b5f6020820190506125aa5f830184612588565b92915050565b5f8083601f8401126125c5576125c4612207565b5b8235905067ffffffffffffffff8111156125e2576125e161220b565b5b6020830191508360018202830111156125fe576125fd61220f565b5b9250929050565b5f805f6040848603121561261c5761261b61214c565b5b5f61262986828701612538565b935050602084013567ffffffffffffffff81111561264a57612649612150565b5b612656868287016125b0565b92509250509250925092565b5f805f806040858703121561267a5761267961214c565b5b5f85013567ffffffffffffffff81111561269757612696612150565b5b6126a38782880161229e565b9450945050602085013567ffffffffffffffff8111156126c6576126c5612150565b5b6126d28782880161229e565b925092505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f80fd5b5f80fd5b5f80fd5b5f80833560016020038436030381126127355761273461270d565b5b80840192508235915067ffffffffffffffff82111561275757612756612711565b5b60208301925060018202360383131561277357612772612715565b5b509250929050565b5f82905092915050565b5f82821b905092915050565b5f61279c838361277b565b826127a78135612154565b925060048210156127e7576127e27fffffffff0000000000000000000000000000000000000000000000000000000083600403600802612785565b831692505b505092915050565b5f819050602082019050919050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f61283482516127fe565b80915050919050565b5f612847826124a7565b82612851846127ef565b905061285c81612829565b9250601482101561289c576128977fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802612785565b831692505b5050919050565b828183375f83830152505050565b5f6128bc83856124b1565b93506128c98385846128a3565b6128d2836123ac565b840190509392505050565b5f6020820190508181035f8301526128f68184866128b1565b90509392505050565b5f61290a838561238e565b93506129178385846128a3565b612920836123ac565b840190509392505050565b5f6020820190508181035f8301526129448184866128ff565b90509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61298381612519565b82525050565b5f60208201905061299c5f83018461297a565b92915050565b5f6129ad838361277b565b826129b881356127fe565b925060148210156129f8576129f37fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802612785565b831692505b505092915050565b5f80fd5b5f80fd5b5f8085851115612a1b57612a1a612a00565b5b83861115612a2c57612a2b612a04565b5b6001850283019150848603905094509492505050565b5f819050919050565b612a5481612a42565b8114612a5e575f80fd5b50565b5f81359050612a6f81612a4b565b92915050565b5f8060408385031215612a8b57612a8a61214c565b5b5f612a9885828601612538565b9250506020612aa985828601612a61565b9150509250929050565b5f80fd5b612ac0826123ac565b810181811067ffffffffffffffff82111715612adf57612ade61294d565b5b80604052505050565b5f612af1612143565b9050612afd8282612ab7565b919050565b5f67ffffffffffffffff821115612b1c57612b1b61294d565b5b612b25826123ac565b9050602081019050919050565b5f612b44612b3f84612b02565b612ae8565b905082815260208101848484011115612b6057612b5f612ab3565b5b612b6b8482856128a3565b509392505050565b5f82601f830112612b8757612b86612207565b5b8135612b97848260208601612b32565b91505092915050565b5f8060408385031215612bb657612bb561214c565b5b5f612bc385828601612538565b925050602083013567ffffffffffffffff811115612be457612be3612150565b5b612bf085828601612b73565b9150509250929050565b612c0381612154565b82525050565b5f602082019050612c1c5f830184612bfa565b92915050565b5f80fd5b5f80fd5b5f612c3482612577565b9050919050565b612c4481612c2a565b8114612c4e575f80fd5b50565b5f81359050612c5f81612c3b565b92915050565b5f67ffffffffffffffff821115612c7f57612c7e61294d565b5b612c88826123ac565b9050602081019050919050565b5f612ca7612ca284612c65565b612ae8565b905082815260208101848484011115612cc357612cc2612ab3565b5b612cce8482856128a3565b509392505050565b5f82601f830112612cea57612ce9612207565b5b8135612cfa848260208601612c95565b91505092915050565b5f60208284031215612d1857612d17612c22565b5b612d226020612ae8565b90505f82013567ffffffffffffffff811115612d4157612d40612c26565b5b612d4d84828501612cd6565b5f8301525092915050565b5f60a08284031215612d6d57612d6c612c22565b5b612d7760a0612ae8565b90505f612d8684828501612c51565b5f83015250602082013567ffffffffffffffff811115612da957612da8612c26565b5b612db584828501612cd6565b602083015250604082013567ffffffffffffffff811115612dd957612dd8612c26565b5b612de584828501612d03565b6040830152506060612df984828501612195565b606083015250608082013567ffffffffffffffff811115612e1d57612e1c612c26565b5b612e2984828501612cd6565b60808301525092915050565b5f60208284031215612e4a57612e4961214c565b5b5f82013567ffffffffffffffff811115612e6757612e66612150565b5b612e7384828501612d58565b91505092915050565b5f82825260208201905092915050565b5f612e96826124a7565b612ea08185612e7c565b9350612eb081856020860161239e565b612eb9816123ac565b840191505092915050565b5f602083015f8301518482035f860152612ede8282612e8c565b9150508091505092915050565b5f6060820190508181035f830152612f0381876124c1565b90508181036020830152612f178186612ec4565b90508181036040830152612f2c8184866128b1565b905095945050505050565b5f67ffffffffffffffff821115612f5157612f5061294d565b5b602082029050602081019050919050565b5f612f74612f6f84612c65565b612ae8565b905082815260208101848484011115612f9057612f8f612ab3565b5b612f9b84828561239e565b509392505050565b5f82601f830112612fb757612fb6612207565b5b8151612fc7848260208601612f62565b91505092915050565b5f612fe2612fdd84612f37565b612ae8565b905080838252602082019050602084028301858111156130055761300461220f565b5b835b8181101561304c57805167ffffffffffffffff81111561302a57613029612207565b5b8086016130378982612fa3565b85526020850194505050602081019050613007565b5050509392505050565b5f82601f83011261306a57613069612207565b5b815161307a848260208601612fd0565b91505092915050565b5f8151905061309181612274565b92915050565b5f80604083850312156130ad576130ac61214c565b5b5f83015167ffffffffffffffff8111156130ca576130c9612150565b5b6130d685828601613056565b92505060206130e785828601613083565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f6131258383612e8c565b905092915050565b5f602082019050919050565b5f613143826130f1565b61314d81856130fb565b93508360208202850161315f8561310b565b805f5b8581101561319a578484038952815161317b858261311a565b94506131868361312d565b925060208a01995050600181019050613162565b50829750879550505050505092915050565b6131b581612268565b82525050565b5f6060820190508181035f8301526131d38186613139565b90506131e260208301856131ac565b81810360408301526131f481846124c1565b9050949350505050565b5f81905092915050565b5f613212826124a7565b61321c81856131fe565b935061322c81856020860161239e565b80840191505092915050565b5f6132438284613208565b915081905092915050565b50565b5f61325c5f8361238e565b91506132678261324e565b5f82019050919050565b5f6020820190508181035f83015261328881613251565b9050919050565b5f602082840312156132a4576132a361214c565b5b5f82015167ffffffffffffffff8111156132c1576132c0612150565b5b6132cd84828501612fa3565b91505092915050565b5f67ffffffffffffffff8211156132f0576132ef61294d565b5b602082029050602081019050919050565b5f61331361330e84612b02565b612ae8565b90508281526020810184848401111561332f5761332e612ab3565b5b61333a84828561239e565b509392505050565b5f82601f83011261335657613355612207565b5b8151613366848260208601613301565b91505092915050565b5f61338161337c846132d6565b612ae8565b905080838252602082019050602084028301858111156133a4576133a361220f565b5b835b818110156133eb57805167ffffffffffffffff8111156133c9576133c8612207565b5b8086016133d68982613342565b855260208501945050506020810190506133a6565b5050509392505050565b5f82601f83011261340957613408612207565b5b815161341984826020860161336f565b91505092915050565b5f602082840312156134375761343661214c565b5b5f82015167ffffffffffffffff81111561345457613453612150565b5b613460848285016133f5565b91505092915050565b5f6040820190508181035f83015261348181856124c1565b905081810360208301526134958184612ec4565b90509392505050565b6134a78161246e565b82525050565b5f602083015f8301518482035f8601526134c78282612e8c565b9150508091505092915050565b6134dd81612154565b82525050565b5f60a083015f8301516134f85f86018261349e565b50602083015184820360208601526135108282612e8c565b9150506040830151848203604086015261352a82826134ad565b915050606083015161353f60608601826134d4565b50608083015184820360808601526135578282612e8c565b9150508091505092915050565b5f6020820190508181035f83015261357c81846134e3565b905092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f82825260208201905092915050565b5f6135c782612384565b6135d181856135ad565b93506135e181856020860161239e565b6135ea816123ac565b840191505092915050565b5f61360083836135bd565b905092915050565b5f602082019050919050565b5f61361e82613584565b613628818561358e565b93508360208202850161363a8561359e565b805f5b85811015613675578484038952815161365685826135f5565b945061366183613608565b925060208a0199505060018101905061363d565b50829750879550505050505092915050565b5f60a08201905061369a5f830188612588565b81810360208301526136ac8187613614565b905081810360408301526136c081866124c1565b90506136cf6060830185612bfa565b81810360808301526136e181846124c1565b90509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61372482612268565b915061372f83612268565b9250828203905060ff811115613748576137476136ed565b5b92915050565b5f61375882612268565b915061376383612268565b9250828201905060ff81111561377c5761377b6136ed565b5b92915050565b5f61378c82612a42565b915061379783612a42565b92508282019050808211156137af576137ae6136ed565b5b9291505056fea2646970667358221220fc3387b0a1b580f3ece0e2cdbea2825a1c9f9869d63dc29ded4a4b1ee4d76d3364736f6c634300081900330000000000000000000000007f68510f0fd952184ec0b976de429a29a2ec0fe3000000000000000000000000a66c55a6b76967477af18a03f2f12d52251dc2c0", + "nonce": "0x12", + "chainId": "0xaa36a7" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x265b371", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0x6225756eafbb061e5389a06964071312993bb716b723ff69e487d9dc0d3299b8", + "transactionIndex": "0xbd", + "blockHash": "0xeafc533b11906cc1da0c5bd3a868639d97a30a1fc34236b4d70f14aa80b2b807", + "blockNumber": "0x9724f5", + "gasUsed": "0x3002a5", + "effectiveGasPrice": "0x22e4b39", + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "to": null, + "contractAddress": "0x380e926f5d78f21b80a6efef2b3cef9ccc89356b" + } + ], + "libraries": [], + "pending": [], + "returns": { + "resolver": { + "internal_type": "contract L1ConfigResolver", + "value": "0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B" + } + }, + "timestamp": 1766579077262, + "chain": 11155111, + "commit": "c437ed7" +} \ No newline at end of file diff --git a/broadcast/Deploy.s.sol/11155111/run-1766581608807.json b/broadcast/Deploy.s.sol/11155111/run-1766581608807.json new file mode 100644 index 0000000..0156cc9 --- /dev/null +++ b/broadcast/Deploy.s.sol/11155111/run-1766581608807.json @@ -0,0 +1,56 @@ +{ + "transactions": [ + { + "hash": "0xc643d5af5b42aae00933dd0d76df862b2ea4e14e9c2cd6742c7f5f7f66c924ab", + "transactionType": "CREATE", + "contractName": "AddressSubnameRegistrar", + "contractAddress": "0x8b82d2af30062e0461c8c3bd1a6ced1df650a5e9", + "function": null, + "arguments": [ + "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", + "0x0635513f179D50A207757E05759CbD106d7dFcE8", + "0xfd49266f604c6bc93ead36965d74c1cf766a3f0f896faa27a2038a75118625c1", + "0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B" + ], + "transaction": { + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "gas": "0x1a4eae", + "value": "0x0", + "input": "0x610100604052348015610010575f80fd5b50604051611a10380380611a10833981810160405281019061003291906101e6565b8373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508273ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250508160c081815250508073ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250505050505061024a565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61010c826100e3565b9050919050565b5f61011d82610102565b9050919050565b61012d81610113565b8114610137575f80fd5b50565b5f8151905061014881610124565b92915050565b5f61015882610102565b9050919050565b6101688161014e565b8114610172575f80fd5b50565b5f815190506101838161015f565b92915050565b5f819050919050565b61019b81610189565b81146101a5575f80fd5b50565b5f815190506101b681610192565b92915050565b6101c581610102565b81146101cf575f80fd5b50565b5f815190506101e0816101bc565b92915050565b5f805f80608085870312156101fe576101fd6100df565b5b5f61020b8782880161013a565b945050602061021c87828801610175565b935050604061022d878288016101a8565b925050606061023e878288016101d2565b91505092959194509250565b60805160a05160c05160e0516116f261031e5f395f8181610c7201528181610ee60152610fd201525f818161078a01528181610ac201528181610cbb01528181610d1301528181610df901528181610ec30152610faf01525f81816102ea0152818161032a01528181610396015281816108ba015281816108fa0152818161096601528181610b5701528181610b9701528181610c9601528181610dbd0152610e8701525f81816101fb0152818161064e015281816106aa015281816107d601528181610a860152610f7301526116f25ff3fe608060405234801561000f575f80fd5b5060043610610091575f3560e01c80634e71d92d116100645780634e71d92d14610143578063828eab0e14610161578063a8e5fbc01461017f578063bffbe61c1461019d578063f3068a00146101cd57610091565b806310098ad51461009557806328a249b0146100c55780633f15457f146100f55780634709bf4b14610113575b5f80fd5b6100af60048036038101906100aa91906110a1565b6101eb565b6040516100bc91906110e6565b60405180910390f35b6100df60048036038101906100da91906110a1565b610459565b6040516100ec919061116f565b60405180910390f35b6100fd61064c565b60405161010a91906111ea565b60405180910390f35b61012d60048036038101906101289190611203565b610670565b60405161013a9190611259565b60405180910390f35b61014b610c60565b6040516101589190611259565b60405180910390f35b610169610c70565b6040516101769190611281565b60405180910390f35b610187610c94565b60405161019491906112ba565b60405180910390f35b6101b760048036038101906101b291906110a1565b610cb8565b6040516101c49190611259565b60405180910390f35b6101d5610d11565b6040516101e29190611259565b60405180910390f35b5f806101f683610cb8565b90505f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b81526004016102529190611259565b602060405180830381865afa15801561026d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061029191906112e7565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036102d157600192505050610454565b5f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161415801561037857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b1561044e575f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636352211e845f1c6040518263ffffffff1660e01b81526004016103ef919061132a565b602060405180830381865afa15801561040a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042e91906112e7565b73ffffffffffffffffffffffffffffffffffffffff161492505050610454565b5f925050505b919050565b60605f602867ffffffffffffffff81111561047757610476611343565b5b6040519080825280601f01601f1916602001820160405280156104a95781602001600182028036833780820191505090505b5090505f8390505f602890505b5f811115610641578080600190039150507f30313233343536373839616263646566000000000000000000000000000000005f1b600f831673ffffffffffffffffffffffffffffffffffffffff166020811061051557610514611370565b5b1a60f81b60f81c60f81b83828151811061053257610531611370565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060048273ffffffffffffffffffffffffffffffffffffffff16901c91508080600190039150507f30313233343536373839616263646566000000000000000000000000000000005f1b600f831673ffffffffffffffffffffffffffffffffffffffff16602081106105d4576105d3611370565b5b1a60f81b60f81c60f81b8382815181106105f1576105f0611370565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060048273ffffffffffffffffffffffffffffffffffffffff16901c91506104b6565b508192505050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561074457507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e985e9c584336040518363ffffffff1660e01b815260040161070392919061139d565b602060405180830381865afa15801561071e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061074291906113ee565b155b1561077b576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61078584610d35565b90505f7f0000000000000000000000000000000000000000000000000000000000000000826040516020016107bb929190611439565b6040516020818303038152906040528051906020012090505f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b815260040161082d9190611259565b602060405180830381865afa158015610848573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061086c91906112e7565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a83575f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161415801561094857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b15610a50575f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636352211e845f1c6040518263ffffffff1660e01b81526004016109bf919061132a565b602060405180830381865afa1580156109da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109fe91906112e7565b73ffffffffffffffffffffffffffffffffffffffff1614610a4b576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a82565b6040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166302571be37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610afd9190611259565b602060405180830381865afa158015610b18573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3c91906112e7565b90505f73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1614158015610be557507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b15610bf957610bf48787610dba565b610c04565b610c038487610f71565b5b828773ffffffffffffffffffffffffffffffffffffffff167f1b2af9453f54ccc027b7454c98ebdf2e7bc4b762f1a1c5dd221d1affdb9fe03e88604051610c4b9190611281565b60405180910390a38294505050505092915050565b5f610c6b3333610670565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f0000000000000000000000000000000000000000000000000000000000000000610ce383610d35565b604051602001610cf4929190611439565b604051602081830303815290604052805190602001209050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f60285b5f811115610dae576001810390507f3031323334353637383961626364656600000000000000000000000000000000600f84161a81536010830492506001810390507f3031323334353637383961626364656600000000000000000000000000000000600f84161a8153601083049250610d39565b5060285f209050919050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630178fe3f7f00000000000000000000000000000000000000000000000000000000000000005f1c6040518263ffffffff1660e01b8152600401610e36919061132a565b606060405180830381865afa158015610e51573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e7591906114da565b925050505f610e8384610459565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166324c1af447f000000000000000000000000000000000000000000000000000000000000000083867f00000000000000000000000000000000000000000000000000000000000000005f80896040518863ffffffff1660e01b8152600401610f2a97969594939291906115a2565b6020604051808303815f875af1158015610f46573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f6a9190611640565b5050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635ef2c7f07f000000000000000000000000000000000000000000000000000000000000000084847f00000000000000000000000000000000000000000000000000000000000000005f6040518663ffffffff1660e01b815260040161101295949392919061166b565b5f604051808303815f87803b158015611029575f80fd5b505af115801561103b573d5f803e3d5ffd5b505050505050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61107082611047565b9050919050565b61108081611066565b811461108a575f80fd5b50565b5f8135905061109b81611077565b92915050565b5f602082840312156110b6576110b5611043565b5b5f6110c38482850161108d565b91505092915050565b5f8115159050919050565b6110e0816110cc565b82525050565b5f6020820190506110f95f8301846110d7565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611141826110ff565b61114b8185611109565b935061115b818560208601611119565b61116481611127565b840191505092915050565b5f6020820190508181035f8301526111878184611137565b905092915050565b5f819050919050565b5f6111b26111ad6111a884611047565b61118f565b611047565b9050919050565b5f6111c382611198565b9050919050565b5f6111d4826111b9565b9050919050565b6111e4816111ca565b82525050565b5f6020820190506111fd5f8301846111db565b92915050565b5f806040838503121561121957611218611043565b5b5f6112268582860161108d565b92505060206112378582860161108d565b9150509250929050565b5f819050919050565b61125381611241565b82525050565b5f60208201905061126c5f83018461124a565b92915050565b61127b81611066565b82525050565b5f6020820190506112945f830184611272565b92915050565b5f6112a4826111b9565b9050919050565b6112b48161129a565b82525050565b5f6020820190506112cd5f8301846112ab565b92915050565b5f815190506112e181611077565b92915050565b5f602082840312156112fc576112fb611043565b5b5f611309848285016112d3565b91505092915050565b5f819050919050565b61132481611312565b82525050565b5f60208201905061133d5f83018461131b565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6040820190506113b05f830185611272565b6113bd6020830184611272565b9392505050565b6113cd816110cc565b81146113d7575f80fd5b50565b5f815190506113e8816113c4565b92915050565b5f6020828403121561140357611402611043565b5b5f611410848285016113da565b91505092915050565b5f819050919050565b61143361142e82611241565b611419565b82525050565b5f6114448285611422565b6020820191506114548284611422565b6020820191508190509392505050565b5f63ffffffff82169050919050565b61147c81611464565b8114611486575f80fd5b50565b5f8151905061149781611473565b92915050565b5f67ffffffffffffffff82169050919050565b6114b98161149d565b81146114c3575f80fd5b50565b5f815190506114d4816114b0565b92915050565b5f805f606084860312156114f1576114f0611043565b5b5f6114fe868287016112d3565b935050602061150f86828701611489565b9250506040611520868287016114c6565b9150509250925092565b5f819050919050565b5f61154d6115486115438461152a565b61118f565b61149d565b9050919050565b61155d81611533565b82525050565b5f61157d6115786115738461152a565b61118f565b611464565b9050919050565b61158d81611563565b82525050565b61159c8161149d565b82525050565b5f60e0820190506115b55f83018a61124a565b81810360208301526115c78189611137565b90506115d66040830188611272565b6115e36060830187611272565b6115f06080830186611554565b6115fd60a0830185611584565b61160a60c0830184611593565b98975050505050505050565b61161f81611241565b8114611629575f80fd5b50565b5f8151905061163a81611616565b92915050565b5f6020828403121561165557611654611043565b5b5f6116628482850161162c565b91505092915050565b5f60a08201905061167e5f83018861124a565b61168b602083018761124a565b6116986040830186611272565b6116a56060830185611272565b6116b26080830184611554565b969550505050505056fea26469706673582212209d8af90115ac87cd7e89fc6bba07881800c0312acfa22d66dd65718d2e00b17e64736f6c6343000819003300000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e0000000000000000000000000635513f179d50a207757e05759cbd106d7dfce8fd49266f604c6bc93ead36965d74c1cf766a3f0f896faa27a2038a75118625c1000000000000000000000000380e926f5d78f21b80a6efef2b3cef9ccc89356b", + "nonce": "0x13", + "chainId": "0xaa36a7" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0xecd1c1", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0xc643d5af5b42aae00933dd0d76df862b2ea4e14e9c2cd6742c7f5f7f66c924ab", + "transactionIndex": "0x3d", + "blockHash": "0x0c13e7c28a4beaf8da7140b25b1d8037eb3b9a009f1b283d80c0dd4bd8f84b00", + "blockNumber": "0x9725ae", + "gasUsed": "0x143c86", + "effectiveGasPrice": "0xa4c8cc", + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "to": null, + "contractAddress": "0x8b82d2af30062e0461c8c3bd1a6ced1df650a5e9" + } + ], + "libraries": [], + "pending": [], + "returns": { + "registrar": { + "internal_type": "contract AddressSubnameRegistrar", + "value": "0x8b82D2aF30062e0461c8C3bd1a6CEd1DF650a5E9" + } + }, + "timestamp": 1766581608807, + "chain": 11155111, + "commit": "c437ed7" +} \ No newline at end of file diff --git a/broadcast/Deploy.s.sol/84532/deployConfigResolver-latest.json b/broadcast/Deploy.s.sol/84532/deployConfigResolver-latest.json new file mode 100644 index 0000000..a69a2af --- /dev/null +++ b/broadcast/Deploy.s.sol/84532/deployConfigResolver-latest.json @@ -0,0 +1,62 @@ +{ + "transactions": [ + { + "hash": "0x5349252e11494c3eb04faefde3b94b6a7e8abb41a89af880771ff6ac3bf7882d", + "transactionType": "CREATE", + "contractName": "ConfigResolver", + "contractAddress": "0xa66c55a6b76967477af18a03f2f12d52251dc2c0", + "function": null, + "arguments": [ + "0x0000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000" + ], + "transaction": { + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "gas": "0x68a33f", + "value": "0x0", + "input": "0x60c060405234801561000f575f80fd5b5060405161601e38038061601e8339818101604052810190610031919061014a565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610188565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100cd826100a4565b9050919050565b5f6100de826100c3565b9050919050565b6100ee816100d4565b81146100f8575f80fd5b50565b5f81519050610109816100e5565b92915050565b5f610119826100c3565b9050919050565b6101298161010f565b8114610133575f80fd5b50565b5f8151905061014481610120565b92915050565b5f80604083850312156101605761015f6100a0565b5b5f61016d858286016100fb565b925050602061017e85828601610136565b9150509250929050565b60805160a051615e6e6101b05f395f8181612bcc0152612c1f01525f612b320152615e6e5ff3fe608060405234801561000f575f80fd5b50600436106101f9575f3560e01c80637737221311610118578063bc1c58d1116100ab578063d700ff331161007a578063d700ff331461064f578063e32954eb1461067f578063e59d895d146106af578063e985e9c5146106cb578063f1cb7e06146106fb576101f9565b8063bc1c58d1146105b6578063c8690233146105e6578063ce3decdc14610617578063d5fa2b0014610633576101f9565b8063a4b91a01116100e7578063a4b91a011461050a578063a8fa568214610526578063a9784b3e14610556578063ac9650d814610586576101f9565b806377372213146104865780638b95dd71146104a25780639061b923146104be578063a22cb465146104ee576101f9565b80633603d758116101905780635c98042b1161015f5780635c98042b146103da578063623195b01461040a578063691f3431146104265780637315937d14610456576101f9565b80633603d7581461032e5780633b3b57de1461034a5780634cbf6ba41461037a57806359d1d43c146103aa576101f9565b80632203ab56116101cc5780632203ab561461029557806329cd62ea146102c6578063304e6ade146102e257806332f111d7146102fe576101f9565b806301ffc9a7146101fd5780630af179d71461022d57806310f13a8c14610249578063124a319c14610265575b5f80fd5b61021760048036038101906102129190613f96565b61072b565b6040516102249190613fdb565b60405180910390f35b61024760048036038101906102429190614088565b61076c565b005b610263600480360381019061025e919061413a565b6109bb565b005b61027f600480360381019061027a91906141cb565b610ab0565b60405161028c9190614248565b60405180910390f35b6102af60048036038101906102aa9190614294565b610ef1565b6040516102bd929190614351565b60405180910390f35b6102e060048036038101906102db919061437f565b61106a565b005b6102fc60048036038101906102f79190614088565b61113d565b005b61031860048036038101906103139190614294565b6111f6565b6040516103259190613fdb565b60405180910390f35b610348600480360381019061034391906143cf565b611274565b005b610364600480360381019061035f91906143cf565b61133f565b604051610371919061441a565b60405180910390f35b610394600480360381019061038f9190614433565b61135e565b6040516103a19190613fdb565b60405180910390f35b6103c460048036038101906103bf9190614471565b6113e2565b6040516103d19190614520565b60405180910390f35b6103f460048036038101906103ef91906143cf565b6114e9565b6040516104019190614540565b60405180910390f35b610424600480360381019061041f9190614560565b6115d0565b005b610440600480360381019061043b91906143cf565b6116a6565b60405161044d9190614520565b60405180910390f35b610470600480360381019061046b91906145fb565b61178d565b60405161047d9190614635565b60405180910390f35b6104a0600480360381019061049b9190614471565b611861565b005b6104bc60048036038101906104b79190614776565b61191a565b005b6104d860048036038101906104d391906147e2565b611a93565b6040516104e59190614540565b60405180910390f35b6105086004803603810190610503919061488a565b611ef1565b005b610524600480360381019061051f91906148c8565b612057565b005b610540600480360381019061053b919061494f565b6121ba565b60405161054d9190614540565b60405180910390f35b610570600480360381019061056b919061499f565b6122c9565b60405161057d9190613fdb565b60405180910390f35b6105a0600480360381019061059b9190614a44565b612367565b6040516105ad9190614b92565b60405180910390f35b6105d060048036038101906105cb91906143cf565b61237e565b6040516105dd9190614540565b60405180910390f35b61060060048036038101906105fb91906143cf565b612465565b60405161060e929190614bb2565b60405180910390f35b610631600480360381019061062c9190614088565b612507565b005b61064d60048036038101906106489190614bd9565b612686565b005b610669600480360381019061066491906143cf565b6126c8565b6040516106769190614c39565b60405180910390f35b61069960048036038101906106949190614c52565b6126eb565b6040516106a69190614b92565b60405180910390f35b6106c960048036038101906106c49190614caf565b612701565b005b6106e560048036038101906106e09190614cff565b612853565b6040516106f29190613fdb565b60405180910390f35b61071560048036038101906107109190614294565b6128e1565b6040516107229190614540565b60405180910390f35b5f639061b92360e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610765575061076482612a9d565b5b9050919050565b8261077681612b16565b61077e575f80fd5b5f806060805f805f808b81526020019081526020015f205f9054906101000a900467ffffffffffffffff1690505f6108025f8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612d1590919063ffffffff16565b90505b61080e81612d3e565b610940575f8761ffff1603610868578060400151965061082d81612d52565b9450846040516020016108409190614d77565b60405160208183030381529060405280519060200120925061086181612d87565b9350610932565b5f61087282612d52565b9050816040015161ffff168861ffff1614158061089f575061089d8187612dbf90919063ffffffff16565b155b15610930576109098c878a8e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508b8c88602001516108ff9190614dba565b5f8c51148a612de6565b81604001519750816020015196508095508580519060200120935061092d82612d87565b94505b505b61093b81613136565b610805565b505f845111156109af576109ae8a85888c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050898a8f8f90506109a49190614dba565b5f8a511488612de6565b5b50505050505050505050565b846109c581612b16565b6109cd575f80fd5b8282600a5f805f8b81526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8981526020019081526020015f208787604051610a36929190614e1b565b90815260200160405180910390209182610a51929190615037565b508484604051610a62929190614e1b565b6040518091039020867f448bc014f1536726cf8d54ff3d6481ed3cbc683c2591ca204274009afa09b1a187878787604051610aa09493929190615130565b60405180910390a3505050505050565b5f8060075f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bb45780915050610eeb565b5f610bbe8561133f565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610bfd575f92505050610eeb565b5f808273ffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000604051602401610c479190615178565b6040516020818303038152906040527f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610cd19190614d77565b5f60405180830381855afa9150503d805f8114610d09576040519150601f19603f3d011682016040523d82523d5f602084013e610d0e565b606091505b5091509150811580610d21575060208151105b80610d6e57505f60f81b81601f81518110610d3f57610d3e615191565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15610d7f575f945050505050610eeb565b8273ffffffffffffffffffffffffffffffffffffffff1686604051602401610da79190615178565b6040516020818303038152906040527f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610e319190614d77565b5f60405180830381855afa9150503d805f8114610e69576040519150601f19603f3d011682016040523d82523d5f602084013e610e6e565b606091505b508092508193505050811580610e85575060208151105b80610ed257505f60f81b81601f81518110610ea357610ea2615191565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15610ee3575f945050505050610eeb565b829450505050505b92915050565b5f60605f60015f805f8881526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f2090505f600190505b5f81118015610f635750848111155b1561104c575f85821614158015610f9557505f825f8381526020019081526020015f208054610f9190614e6a565b9050115b156110405780825f8381526020019081526020015f20808054610fb790614e6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610fe390614e6a565b801561102e5780601f106110055761010080835404028352916020019161102e565b820191905f5260205f20905b81548152906001019060200180831161101157829003601f168201915b50505050509050935093505050611063565b600181901b9050610f54565b505f60405180602001604052805f81525092509250505b9250929050565b8261107481612b16565b61107c575f80fd5b60405180604001604052808481526020018381525060095f805f8881526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f820151815f015560208201518160010155905050837f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46848460405161112f929190614bb2565b60405180910390a250505050565b8261114781612b16565b61114f575f80fd5b828260035f805f8981526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8781526020019081526020015f2091826111b5929190615220565b50837fe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d757884846040516111e8929190615319565b60405180910390a250505050565b5f8060025f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f8481526020019081526020015f20805461126990614e6a565b905011905092915050565b8061127e81612b16565b611286575f80fd5b5f808381526020019081526020015f205f81819054906101000a900467ffffffffffffffff16809291906112b99061533b565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050817fc6621ccb8f3f5a04bb6502154b2caf6adf5983fe76dfef1cfc9c42e3579db4445f808581526020019081526020015f205f9054906101000a900467ffffffffffffffff166040516113339190614c39565b60405180910390a25050565b5f61134b82603c6128e1565b611354906153b8565b60601c9050919050565b5f8060065f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f8481526020019081526020015f205f9054906101000a900461ffff1661ffff161415905092915050565b6060600a5f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f20838360405161144b929190614e1b565b9081526020016040518091039020805461146490614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461149090614e6a565b80156114db5780601f106114b2576101008083540402835291602001916114db565b820191905f5260205f20905b8154815290600101906020018083116114be57829003601f168201915b505050505090509392505050565b606060045f805f8581526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20805461154d90614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461157990614e6a565b80156115c45780601f1061159b576101008083540402835291602001916115c4565b820191905f5260205f20905b8154815290600101906020018083116115a757829003601f168201915b50505050509050919050565b836115da81612b16565b6115e2575f80fd5b5f846001866115f19190614dba565b16146115fb575f80fd5b828260015f805f8a81526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8881526020019081526020015f205f8781526020019081526020015f209182611670929190615220565b5083857faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe360405160405180910390a35050505050565b606060085f805f8581526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20805461170a90614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461173690614e6a565b80156117815780601f1061175857610100808354040283529160200191611781565b820191905f5260205f20905b81548152906001019060200180831161176457829003601f168201915b50505050509050919050565b5f8060285b5f811115611807576001810390507f3031323334353637383961626364656600000000000000000000000000000000600f85161a81536010840493506001810390507f3031323334353637383961626364656600000000000000000000000000000000600f85161a8153601084049350611792565b5060285f2090507f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e25f1b8160405160200161184392919061543e565b60405160208183030381529060405280519060200120915050919050565b8261186b81612b16565b611873575f80fd5b828260085f805f8981526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8781526020019081526020015f2091826118d9929190615037565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7848460405161190c929190615469565b60405180910390a250505050565b8261192481612b16565b61192c575f80fd5b5f82511415801561193f57506014825114155b8015611950575061194f83613274565b5b1561199257816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016119899190614540565b60405180910390fd5b837f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af75284846040516119c4929190614351565b60405180910390a2603c8303611a1957837f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd283611a00906153b8565b60601c604051611a109190614248565b60405180910390a25b8160025f805f8881526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f8581526020019081526020015f209081611a8c919061548b565b5050505050565b60605f85855f818110611aa957611aa8615191565b5b9050013560f81c60f81b60f81c60ff16905060288103611e32575f8686600190602992611ad893929190615562565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505f80611b345f60288561329b9092919063ffffffff16565b9150915080611b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6f906155e6565b60405180910390fd5b5f611b828361178d565b90505f88885f90600492611b9893929190615562565b90611ba39190615604565b9050633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611c1e5783604051602001611c029190614248565b6040516020818303038152906040529650505050505050611ee9565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611d3d575f89896004908092611c7e93929190615562565b810190611c8b9190615700565b9150505f3073ffffffffffffffffffffffffffffffffffffffff166359d1d43c85846040518363ffffffff1660e01b8152600401611cca92919061575a565b5f60405180830381865afa158015611ce4573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190611d0c91906157f6565b905080604051602001611d1f9190614520565b60405160208183030381529060405298505050505050505050611ee9565b5f81838b8b6024908092611d5393929190615562565b604051602001611d669493929190615881565b60405160208183030381529060405290505f803073ffffffffffffffffffffffffffffffffffffffff1683604051611d9e9190614d77565b5f60405180830381855afa9150503d805f8114611dd6576040519150601f19603f3d011682016040523d82523d5f602084013e611ddb565b606091505b50915091508115611df757809950505050505050505050611ee9565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e2990615905565b60405180910390fd5b5f803073ffffffffffffffffffffffffffffffffffffffff168686604051611e5b929190615923565b5f60405180830381855afa9150503d805f8114611e93576040519150601f19603f3d011682016040523d82523d5f602084013e611e98565b606091505b50915091508115611eae57809350505050611ee9565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee090615985565b60405180910390fd5b949350505050565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1603611f5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5690615a13565b60405180910390fd5b80600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161204b9190613fdb565b60405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036120c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120bc90615a7b565b60405180910390fd5b80600c5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508015158273ffffffffffffffffffffffffffffffffffffffff16847ff0ddb3b04746704017f9aa8bd728fcc2c1d11675041205350018915f5e4750a0336040516121ad9190614248565b60405180910390a4505050565b606060055f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f8481526020019081526020015f205f8361ffff1661ffff1681526020019081526020015f20805461224490614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461227090614e6a565b80156122bb5780601f10612292576101008083540402835291602001916122bb565b820191905f5260205f20905b81548152906001019060200180831161229e57829003601f168201915b505050505090509392505050565b5f600c5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1690509392505050565b60606123765f801b84846132de565b905092915050565b606060035f805f8581526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2080546123e290614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461240e90614e6a565b80156124595780601f1061243057610100808354040283529160200191612459565b820191905f5260205f20905b81548152906001019060200180831161243c57829003601f168201915b50505050509050919050565b5f805f805f8581526020019081526020015f205f9054906101000a900467ffffffffffffffff16905060095f8267ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f015460095f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f20600101549250925050915091565b8261251181612b16565b612519575f80fd5b5f805f8681526020019081526020015f205f9054906101000a900467ffffffffffffffff1690505f60045f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8781526020019081526020015f20805461258090614e6a565b80601f01602080910402602001604051908101604052809291908181526020018280546125ac90614e6a565b80156125f75780601f106125ce576101008083540402835291602001916125f7565b820191905f5260205f20905b8154815290600101906020018083116125da57829003601f168201915b50505050509050848460045f8567ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8981526020019081526020015f209182612641929190615220565b50857f8f15ed4b723ef428f250961da8315675b507046737e19319fc1a4d81bfe87f8582878760405161267693929190615a99565b60405180910390a2505050505050565b8161269081612b16565b612698575f80fd5b6126c383603c846040516020016126af9190615b15565b60405160208183030381529060405261191a565b505050565b5f602052805f5260405f205f915054906101000a900467ffffffffffffffff1681565b60606126f88484846132de565b90509392505050565b8261270b81612b16565b612713575f80fd5b8160075f805f8881526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847f7c69f06bea0bdef565b709e93a147836b0063ba2dd89f02d0b7e8d931e6a6daa846040516128459190614248565b60405180910390a350505050565b5f600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b60605f60025f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f209050805f8481526020019081526020015f20805461295890614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461298490614e6a565b80156129cf5780601f106129a6576101008083540402835291602001916129cf565b820191905f5260205f20905b8154815290600101906020018083116129b257829003601f168201915b505050505091505f82511480156129f357505f6129eb8461349f565b63ffffffff16115b15612a9657805f638000000081526020019081526020015f208054612a1790614e6a565b80601f0160208091040260200160405190810160405280929190818152602001828054612a4390614e6a565b8015612a8e5780601f10612a6557610100808354040283529160200191612a8e565b820191905f5260205f20905b815481529060010190602001808311612a7157829003601f168201915b505050505091505b5092915050565b5f7f59d1d43c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612b0f5750612b0e826134d5565b5b9050919050565b5f81612b213361178d565b03612b2f5760019050612d10565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b8152600401612b899190614635565b602060405180830381865afa158015612ba4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bc89190615b43565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612cba577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636352211e845f1c6040518263ffffffff1660e01b8152600401612c789190615b6e565b602060405180830381865afa158015612c93573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612cb79190615b43565b90505b3373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480612cfa5750612cf98133612853565b5b80612d0c5750612d0b8184336122c9565b5b9150505b919050565b612d1d613e93565b82815f0181905250818160c0018181525050612d3881613136565b92915050565b5f815f015151826020015110159050919050565b6060612d808260200151612d6d845f0151856020015161354e565b845f01516135c79092919063ffffffff16565b9050919050565b6060612db88260a001518360a001518460c00151612da59190614dba565b845f01516135c79092919063ffffffff16565b9050919050565b5f81518351148015612dde575081805190602001208380519060200120145b905092915050565b5f878051906020012090505f612e078686896135c79092919063ffffffff16565b90508315612f9c575f60055f8567ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8c81526020019081526020015f205f8481526020019081526020015f205f8a61ffff1661ffff1681526020019081526020015f208054612e7590614e6a565b905014612ef85760065f8467ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8b81526020019081526020015f205f8381526020019081526020015f205f81819054906101000a900461ffff1680929190612edc90615b87565b91906101000a81548161ffff021916908361ffff160217905550505b60055f8467ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8b81526020019081526020015f205f8381526020019081526020015f205f8961ffff1661ffff1681526020019081526020015f205f612f5d9190613ed8565b897f03528ed0c2a3ebc993b12ce3c16bb382f9c7d88ef7d8a1bf290eaf35955a12078a8a604051612f8f929190615bbd565b60405180910390a261312a565b5f60055f8567ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8c81526020019081526020015f205f8481526020019081526020015f205f8a61ffff1661ffff1681526020019081526020015f20805461300290614e6a565b9050036130855760065f8467ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8b81526020019081526020015f205f8381526020019081526020015f205f81819054906101000a900461ffff168092919061306990615beb565b91906101000a81548161ffff021916908361ffff160217905550505b8060055f8567ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8c81526020019081526020015f205f8481526020019081526020015f205f8a61ffff1661ffff1681526020019081526020015f2090816130ec919061548b565b50897f52a608b3303a48862d07a73d82fa221318c0027fbbcfb1b2329bface3f19ff2b8a8a8460405161312193929190615c14565b60405180910390a25b50505050505050505050565b8060c00151816020018181525050805f01515181602001511015613271575f613166825f0151836020015161354e565b82602001516131759190615c57565b905061318d81835f015161362c90919063ffffffff16565b826040019061ffff16908161ffff16815250506002816131ad9190615c57565b90506131c581835f015161362c90919063ffffffff16565b826060019061ffff16908161ffff16815250506002816131e59190615c57565b90506131fd81835f015161365590919063ffffffff16565b826080019063ffffffff16908163ffffffff16815250506004816132219190615c57565b90505f61323a82845f015161362c90919063ffffffff16565b61ffff16905060028261324d9190615c57565b9150818360a001818152505080826132659190615c57565b8360c001818152505050505b50565b5f638000000082148061329457505f61328c8361349f565b63ffffffff16115b9050919050565b5f80826028856132ab9190615c57565b146132bb575f80915091506132d6565b5f6132c786868661367e565b8093508192505050805f1c9250505b935093915050565b60608282905067ffffffffffffffff8111156132fd576132fc614652565b5b60405190808252806020026020018201604052801561333057816020015b606081526020019060019003908161331b5790505b5090505f5b83839050811015613497575f801b85146133d2575f84848381811061335d5761335c615191565b5b905060200281019061336f9190615c96565b60049060249261338193929190615562565b9061338c9190615cf8565b90508581146133d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133c790615dc6565b60405180910390fd5b505b5f803073ffffffffffffffffffffffffffffffffffffffff168686858181106133fe576133fd615191565b5b90506020028101906134109190615c96565b60405161341e929190615923565b5f60405180830381855af49150503d805f8114613456576040519150601f19603f3d011682016040523d82523d5f602084013e61345b565b606091505b509150915081613469575f80fd5b8084848151811061347d5761347c615191565b5b602002602001018190525050508080600101915050613335565b509392505050565b5f603c82036134b157600190506134d0565b638000000082189150638000000082106134cb575f6134cd565b815b90505b919050565b5f7fc8690233000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806135475750613546826136f9565b5b9050919050565b5f808290505b6001156135b2578351811061356c5761356b615de4565b5b5f613580828661377290919063ffffffff16565b60ff1690506001816135929190615c57565b8261359d9190615c57565b91505f81036135ac57506135b2565b50613554565b82816135be9190614dba565b91505092915050565b60608167ffffffffffffffff8111156135e3576135e2614652565b5b6040519080825280601f01601f1916602001820160405280156136155781602001600182028036833780820191505090505b5090506136258484835f866137b2565b9392505050565b5f6136438360028461363e9190615c57565b613802565b8160208401015160f01c905092915050565b5f61366c836004846136679190615c57565b613802565b8160208401015160e01c905092915050565b5f8083831015613693575f80915091506136f1565b5f84846136a09190614dba565b905060408111806136b15750855184115b156136c4575f801b5f92509250506136f1565b5f85602088010190506136d8815f8461384f565b92506001820160011c6020035f518160031b1c94505050505b935093915050565b5f7f691f3431000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061376b575061376a82613949565b5b9050919050565b5f613789836001846137849190615c57565b613802565b82828151811061379c5761379b615191565b5b602001015160f81c60f81b60f81c905092915050565b6137c78582866137c29190615c57565b613802565b6137dc8382846137d79190615c57565b613802565b6137fb826137e9856139c2565b01856137f4886139c2565b01836139ce565b5050505050565b815181111561384b578082516040517f8a3c1cfb000000000000000000000000000000000000000000000000000000008152600401613842929190615e11565b60405180910390fd5b5050565b5f6138b8565b5f81831a9150603a8210602f83111615613874576030820390506138b2565b6047821060408311161561389057600a604183030190506138b2565b606782106060831116156138ac57600a606183030190506138b2565b61010090505b92915050565b6001905081840160018316156138f4576138d35f8651613855565b80855360018601955060018501945060ff8111156138f2575f92508195505b505b5b8085101561394157845161390a600182613855565b6139145f83613855565b60041b1760ff81111561392b575f93505050613941565b80865350506002850194506001840193506138f5565b509392505050565b5f7f124a319c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806139bb57506139ba82613a1c565b5b9050919050565b5f602082019050919050565b5b601f8111156139f357815183526020830192506020820191506020810390506139cf565b8015613a17576001808260200360031b1b0380198351168185511680821786525050505b505050565b5f7fa8fa5682000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613ae657507f5c98042b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613af65750613af582613afd565b5b9050919050565b5f7fbc1c58d1000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613b6f5750613b6e82613b76565b5b9050919050565b5f817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f3b3b57de000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613c405750817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167ff1cb7e06000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613ca85750817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f32f111d7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613cb85750613cb782613cbf565b5b9050919050565b5f7f2203ab56000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613d315750613d3082613d38565b5b9050919050565b5f7fd700ff33000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613daa5750613da982613db1565b5b9050919050565b5f7f4fbf0433000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613e235750613e2282613e2a565b5b9050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6040518060e00160405280606081526020015f81526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f81526020015f81525090565b508054613ee490614e6a565b5f825580601f10613ef55750613f12565b601f0160209004905f5260205f2090810190613f119190613f15565b5b50565b5b80821115613f2c575f815f905550600101613f16565b5090565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613f7581613f41565b8114613f7f575f80fd5b50565b5f81359050613f9081613f6c565b92915050565b5f60208284031215613fab57613faa613f39565b5b5f613fb884828501613f82565b91505092915050565b5f8115159050919050565b613fd581613fc1565b82525050565b5f602082019050613fee5f830184613fcc565b92915050565b5f819050919050565b61400681613ff4565b8114614010575f80fd5b50565b5f8135905061402181613ffd565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261404857614047614027565b5b8235905067ffffffffffffffff8111156140655761406461402b565b5b6020830191508360018202830111156140815761408061402f565b5b9250929050565b5f805f6040848603121561409f5761409e613f39565b5b5f6140ac86828701614013565b935050602084013567ffffffffffffffff8111156140cd576140cc613f3d565b5b6140d986828701614033565b92509250509250925092565b5f8083601f8401126140fa576140f9614027565b5b8235905067ffffffffffffffff8111156141175761411661402b565b5b6020830191508360018202830111156141335761413261402f565b5b9250929050565b5f805f805f6060868803121561415357614152613f39565b5b5f61416088828901614013565b955050602086013567ffffffffffffffff81111561418157614180613f3d565b5b61418d888289016140e5565b9450945050604086013567ffffffffffffffff8111156141b0576141af613f3d565b5b6141bc888289016140e5565b92509250509295509295909350565b5f80604083850312156141e1576141e0613f39565b5b5f6141ee85828601614013565b92505060206141ff85828601613f82565b9150509250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61423282614209565b9050919050565b61424281614228565b82525050565b5f60208201905061425b5f830184614239565b92915050565b5f819050919050565b61427381614261565b811461427d575f80fd5b50565b5f8135905061428e8161426a565b92915050565b5f80604083850312156142aa576142a9613f39565b5b5f6142b785828601614013565b92505060206142c885828601614280565b9150509250929050565b6142db81614261565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f614323826142e1565b61432d81856142eb565b935061433d8185602086016142fb565b61434681614309565b840191505092915050565b5f6040820190506143645f8301856142d2565b81810360208301526143768184614319565b90509392505050565b5f805f6060848603121561439657614395613f39565b5b5f6143a386828701614013565b93505060206143b486828701614013565b92505060406143c586828701614013565b9150509250925092565b5f602082840312156143e4576143e3613f39565b5b5f6143f184828501614013565b91505092915050565b5f61440482614209565b9050919050565b614414816143fa565b82525050565b5f60208201905061442d5f83018461440b565b92915050565b5f806040838503121561444957614448613f39565b5b5f61445685828601614013565b925050602061446785828601614013565b9150509250929050565b5f805f6040848603121561448857614487613f39565b5b5f61449586828701614013565b935050602084013567ffffffffffffffff8111156144b6576144b5613f3d565b5b6144c2868287016140e5565b92509250509250925092565b5f81519050919050565b5f82825260208201905092915050565b5f6144f2826144ce565b6144fc81856144d8565b935061450c8185602086016142fb565b61451581614309565b840191505092915050565b5f6020820190508181035f83015261453881846144e8565b905092915050565b5f6020820190508181035f8301526145588184614319565b905092915050565b5f805f806060858703121561457857614577613f39565b5b5f61458587828801614013565b945050602061459687828801614280565b935050604085013567ffffffffffffffff8111156145b7576145b6613f3d565b5b6145c387828801614033565b925092505092959194509250565b6145da81614228565b81146145e4575f80fd5b50565b5f813590506145f5816145d1565b92915050565b5f602082840312156146105761460f613f39565b5b5f61461d848285016145e7565b91505092915050565b61462f81613ff4565b82525050565b5f6020820190506146485f830184614626565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61468882614309565b810181811067ffffffffffffffff821117156146a7576146a6614652565b5b80604052505050565b5f6146b9613f30565b90506146c5828261467f565b919050565b5f67ffffffffffffffff8211156146e4576146e3614652565b5b6146ed82614309565b9050602081019050919050565b828183375f83830152505050565b5f61471a614715846146ca565b6146b0565b9050828152602081018484840111156147365761473561464e565b5b6147418482856146fa565b509392505050565b5f82601f83011261475d5761475c614027565b5b813561476d848260208601614708565b91505092915050565b5f805f6060848603121561478d5761478c613f39565b5b5f61479a86828701614013565b93505060206147ab86828701614280565b925050604084013567ffffffffffffffff8111156147cc576147cb613f3d565b5b6147d886828701614749565b9150509250925092565b5f805f80604085870312156147fa576147f9613f39565b5b5f85013567ffffffffffffffff81111561481757614816613f3d565b5b61482387828801614033565b9450945050602085013567ffffffffffffffff81111561484657614845613f3d565b5b61485287828801614033565b925092505092959194509250565b61486981613fc1565b8114614873575f80fd5b50565b5f8135905061488481614860565b92915050565b5f80604083850312156148a05761489f613f39565b5b5f6148ad858286016145e7565b92505060206148be85828601614876565b9150509250929050565b5f805f606084860312156148df576148de613f39565b5b5f6148ec86828701614013565b93505060206148fd868287016145e7565b925050604061490e86828701614876565b9150509250925092565b5f61ffff82169050919050565b61492e81614918565b8114614938575f80fd5b50565b5f8135905061494981614925565b92915050565b5f805f6060848603121561496657614965613f39565b5b5f61497386828701614013565b935050602061498486828701614013565b92505060406149958682870161493b565b9150509250925092565b5f805f606084860312156149b6576149b5613f39565b5b5f6149c3868287016145e7565b93505060206149d486828701614013565b92505060406149e5868287016145e7565b9150509250925092565b5f8083601f840112614a0457614a03614027565b5b8235905067ffffffffffffffff811115614a2157614a2061402b565b5b602083019150836020820283011115614a3d57614a3c61402f565b5b9250929050565b5f8060208385031215614a5a57614a59613f39565b5b5f83013567ffffffffffffffff811115614a7757614a76613f3d565b5b614a83858286016149ef565b92509250509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f82825260208201905092915050565b5f614ad2826142e1565b614adc8185614ab8565b9350614aec8185602086016142fb565b614af581614309565b840191505092915050565b5f614b0b8383614ac8565b905092915050565b5f602082019050919050565b5f614b2982614a8f565b614b338185614a99565b935083602082028501614b4585614aa9565b805f5b85811015614b805784840389528151614b618582614b00565b9450614b6c83614b13565b925060208a01995050600181019050614b48565b50829750879550505050505092915050565b5f6020820190508181035f830152614baa8184614b1f565b905092915050565b5f604082019050614bc55f830185614626565b614bd26020830184614626565b9392505050565b5f8060408385031215614bef57614bee613f39565b5b5f614bfc85828601614013565b9250506020614c0d858286016145e7565b9150509250929050565b5f67ffffffffffffffff82169050919050565b614c3381614c17565b82525050565b5f602082019050614c4c5f830184614c2a565b92915050565b5f805f60408486031215614c6957614c68613f39565b5b5f614c7686828701614013565b935050602084013567ffffffffffffffff811115614c9757614c96613f3d565b5b614ca3868287016149ef565b92509250509250925092565b5f805f60608486031215614cc657614cc5613f39565b5b5f614cd386828701614013565b9350506020614ce486828701613f82565b9250506040614cf5868287016145e7565b9150509250925092565b5f8060408385031215614d1557614d14613f39565b5b5f614d22858286016145e7565b9250506020614d33858286016145e7565b9150509250929050565b5f81905092915050565b5f614d51826142e1565b614d5b8185614d3d565b9350614d6b8185602086016142fb565b80840191505092915050565b5f614d828284614d47565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614dc482614261565b9150614dcf83614261565b9250828203905081811115614de757614de6614d8d565b5b92915050565b5f81905092915050565b5f614e028385614ded565b9350614e0f8385846146fa565b82840190509392505050565b5f614e27828486614df7565b91508190509392505050565b5f82905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680614e8157607f821691505b602082108103614e9457614e93614e3d565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614ef67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614ebb565b614f008683614ebb565b95508019841693508086168417925050509392505050565b5f819050919050565b5f614f3b614f36614f3184614261565b614f18565b614261565b9050919050565b5f819050919050565b614f5483614f21565b614f68614f6082614f42565b848454614ec7565b825550505050565b5f90565b614f7c614f70565b614f87818484614f4b565b505050565b5b81811015614faa57614f9f5f82614f74565b600181019050614f8d565b5050565b601f821115614fef57614fc081614e9a565b614fc984614eac565b81016020851015614fd8578190505b614fec614fe485614eac565b830182614f8c565b50505b505050565b5f82821c905092915050565b5f61500f5f1984600802614ff4565b1980831691505092915050565b5f6150278383615000565b9150826002028217905092915050565b6150418383614e33565b67ffffffffffffffff81111561505a57615059614652565b5b6150648254614e6a565b61506f828285614fae565b5f601f83116001811461509c575f841561508a578287013590505b615094858261501c565b8655506150fb565b601f1984166150aa86614e9a565b5f5b828110156150d1578489013582556001820191506020850194506020810190506150ac565b868310156150ee57848901356150ea601f891682615000565b8355505b6001600288020188555050505b50505050505050565b5f61510f83856144d8565b935061511c8385846146fa565b61512583614309565b840190509392505050565b5f6040820190508181035f830152615149818688615104565b9050818103602083015261515e818486615104565b905095945050505050565b61517281613f41565b82525050565b5f60208201905061518b5f830184615169565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82905092915050565b5f819050815f5260205f209050919050565b601f82111561521b576151ec816151c8565b6151f584614eac565b81016020851015615204578190505b61521861521085614eac565b830182614f8c565b50505b505050565b61522a83836151be565b67ffffffffffffffff81111561524357615242614652565b5b61524d8254614e6a565b6152588282856151da565b5f601f831160018114615285575f8415615273578287013590505b61527d858261501c565b8655506152e4565b601f198416615293866151c8565b5f5b828110156152ba57848901358255600182019150602085019450602081019050615295565b868310156152d757848901356152d3601f891682615000565b8355505b6001600288020188555050505b50505050505050565b5f6152f883856142eb565b93506153058385846146fa565b61530e83614309565b840190509392505050565b5f6020820190508181035f8301526153328184866152ed565b90509392505050565b5f61534582614c17565b915067ffffffffffffffff820361535f5761535e614d8d565b5b600182019050919050565b5f819050602082019050919050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f6153af8251615379565b80915050919050565b5f6153c2826142e1565b826153cc8461536a565b90506153d7816153a4565b92506014821015615417576154127fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802614ebb565b831692505b5050919050565b5f819050919050565b61543861543382613ff4565b61541e565b82525050565b5f6154498285615427565b6020820191506154598284615427565b6020820191508190509392505050565b5f6020820190508181035f830152615482818486615104565b90509392505050565b615494826142e1565b67ffffffffffffffff8111156154ad576154ac614652565b5b6154b78254614e6a565b6154c28282856151da565b5f60209050601f8311600181146154f3575f84156154e1578287015190505b6154eb858261501c565b865550615552565b601f198416615501866151c8565b5f5b8281101561552857848901518255600182019150602085019450602081019050615503565b868310156155455784890151615541601f891682615000565b8355505b6001600288020188555050505b505050505050565b5f80fd5b5f80fd5b5f80858511156155755761557461555a565b5b838611156155865761558561555e565b5b6001850283019150848603905094509492505050565b7f496e76616c6964206865782061646472657373000000000000000000000000005f82015250565b5f6155d06013836144d8565b91506155db8261559c565b602082019050919050565b5f6020820190508181035f8301526155fd816155c4565b9050919050565b5f61560f83836151be565b8261561a8135613f41565b9250600482101561565a576156557fffffffff0000000000000000000000000000000000000000000000000000000083600403600802614ebb565b831692505b505092915050565b5f67ffffffffffffffff82111561567c5761567b614652565b5b61568582614309565b9050602081019050919050565b5f6156a461569f84615662565b6146b0565b9050828152602081018484840111156156c0576156bf61464e565b5b6156cb8482856146fa565b509392505050565b5f82601f8301126156e7576156e6614027565b5b81356156f7848260208601615692565b91505092915050565b5f806040838503121561571657615715613f39565b5b5f61572385828601614013565b925050602083013567ffffffffffffffff81111561574457615743613f3d565b5b615750858286016156d3565b9150509250929050565b5f60408201905061576d5f830185614626565b818103602083015261577f81846144e8565b90509392505050565b5f61579a61579584615662565b6146b0565b9050828152602081018484840111156157b6576157b561464e565b5b6157c18482856142fb565b509392505050565b5f82601f8301126157dd576157dc614027565b5b81516157ed848260208601615788565b91505092915050565b5f6020828403121561580b5761580a613f39565b5b5f82015167ffffffffffffffff81111561582857615827613f3d565b5b615834848285016157c9565b91505092915050565b5f819050919050565b61585761585282613f41565b61583d565b82525050565b5f6158688385614d3d565b93506158758385846146fa565b82840190509392505050565b5f61588c8287615846565b60048201915061589c8286615427565b6020820191506158ad82848661585d565b915081905095945050505050565b7f556e737570706f727465642066756e6374696f6e0000000000000000000000005f82015250565b5f6158ef6014836144d8565b91506158fa826158bb565b602082019050919050565b5f6020820190508181035f83015261591c816158e3565b9050919050565b5f61592f82848661585d565b91508190509392505050565b7f5265736f6c7574696f6e206661696c65640000000000000000000000000000005f82015250565b5f61596f6011836144d8565b915061597a8261593b565b602082019050919050565b5f6020820190508181035f83015261599c81615963565b9050919050565b7f455243313135353a2073657474696e6720617070726f76616c207374617475735f8201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b5f6159fd6029836144d8565b9150615a08826159a3565b604082019050919050565b5f6020820190508181035f830152615a2a816159f1565b9050919050565b7f53657474696e672064656c65676174652073746174757320666f722073656c665f82015250565b5f615a656020836144d8565b9150615a7082615a31565b602082019050919050565b5f6020820190508181035f830152615a9281615a59565b9050919050565b5f6040820190508181035f830152615ab18186614319565b90508181036020830152615ac68184866152ed565b9050949350505050565b5f8160601b9050919050565b5f615ae682615ad0565b9050919050565b5f615af782615adc565b9050919050565b615b0f615b0a82614228565b615aed565b82525050565b5f615b208284615afe565b60148201915081905092915050565b5f81519050615b3d816145d1565b92915050565b5f60208284031215615b5857615b57613f39565b5b5f615b6584828501615b2f565b91505092915050565b5f602082019050615b815f8301846142d2565b92915050565b5f615b9182614918565b91505f8203615ba357615ba2614d8d565b5b600182039050919050565b615bb781614918565b82525050565b5f6040820190508181035f830152615bd58185614319565b9050615be46020830184615bae565b9392505050565b5f615bf582614918565b915061ffff8203615c0957615c08614d8d565b5b600182019050919050565b5f6060820190508181035f830152615c2c8186614319565b9050615c3b6020830185615bae565b8181036040830152615c4d8184614319565b9050949350505050565b5f615c6182614261565b9150615c6c83614261565b9250828201905080821115615c8457615c83614d8d565b5b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083356001602003843603038112615cb257615cb1615c8a565b5b80840192508235915067ffffffffffffffff821115615cd457615cd3615c8e565b5b602083019250600182023603831315615cf057615cef615c92565b5b509250929050565b5f615d0383836151be565b82615d0e8135613ff4565b92506020821015615d4e57615d497fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802614ebb565b831692505b505092915050565b7f6d756c746963616c6c3a20416c6c207265636f726473206d75737420686176655f8201527f2061206d61746368696e67206e616d6568617368000000000000000000000000602082015250565b5f615db06034836144d8565b9150615dbb82615d56565b604082019050919050565b5f6020820190508181035f830152615ddd81615da4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b5f604082019050615e245f8301856142d2565b615e3160208301846142d2565b939250505056fea2646970667358221220666f59a975a4c8228cbda082edea45bee7ea37187b083599527ba9c97134fb6f64736f6c6343000819003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x3", + "chainId": "0x14a34" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x90dd05", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0x5349252e11494c3eb04faefde3b94b6a7e8abb41a89af880771ff6ac3bf7882d", + "transactionIndex": "0x9", + "blockHash": "0x168e9322c12cfb1991ad6c6208ba4be7c06f656991aecd33fec9084b493ad1be", + "blockNumber": "0x21c3e15", + "gasUsed": "0x507d93", + "effectiveGasPrice": "0xe0f3b8", + "blobGasUsed": "0x321408", + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "to": null, + "contractAddress": "0xa66c55a6b76967477af18a03f2f12d52251dc2c0", + "daFootprintGasScalar": "0x138", + "l1BaseFeeScalar": "0x44d", + "l1BlobBaseFee": "0x39aec6f64", + "l1BlobBaseFeeScalar": "0xa118b", + "l1Fee": "0x61c42bfc559d", + "l1GasPrice": "0x3a6b8fd", + "l1GasUsed": "0x2917e" + } + ], + "libraries": [], + "pending": [], + "returns": { + "resolver": { + "internal_type": "contract ConfigResolver", + "value": "0xA66c55a6b76967477af18A03F2f12d52251Dc2C0" + } + }, + "timestamp": 1766578976219, + "chain": 84532, + "commit": "c437ed7" +} \ No newline at end of file diff --git a/broadcast/Deploy.s.sol/84532/run-1766578976219.json b/broadcast/Deploy.s.sol/84532/run-1766578976219.json new file mode 100644 index 0000000..a69a2af --- /dev/null +++ b/broadcast/Deploy.s.sol/84532/run-1766578976219.json @@ -0,0 +1,62 @@ +{ + "transactions": [ + { + "hash": "0x5349252e11494c3eb04faefde3b94b6a7e8abb41a89af880771ff6ac3bf7882d", + "transactionType": "CREATE", + "contractName": "ConfigResolver", + "contractAddress": "0xa66c55a6b76967477af18a03f2f12d52251dc2c0", + "function": null, + "arguments": [ + "0x0000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000" + ], + "transaction": { + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "gas": "0x68a33f", + "value": "0x0", + "input": "0x60c060405234801561000f575f80fd5b5060405161601e38038061601e8339818101604052810190610031919061014a565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610188565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100cd826100a4565b9050919050565b5f6100de826100c3565b9050919050565b6100ee816100d4565b81146100f8575f80fd5b50565b5f81519050610109816100e5565b92915050565b5f610119826100c3565b9050919050565b6101298161010f565b8114610133575f80fd5b50565b5f8151905061014481610120565b92915050565b5f80604083850312156101605761015f6100a0565b5b5f61016d858286016100fb565b925050602061017e85828601610136565b9150509250929050565b60805160a051615e6e6101b05f395f8181612bcc0152612c1f01525f612b320152615e6e5ff3fe608060405234801561000f575f80fd5b50600436106101f9575f3560e01c80637737221311610118578063bc1c58d1116100ab578063d700ff331161007a578063d700ff331461064f578063e32954eb1461067f578063e59d895d146106af578063e985e9c5146106cb578063f1cb7e06146106fb576101f9565b8063bc1c58d1146105b6578063c8690233146105e6578063ce3decdc14610617578063d5fa2b0014610633576101f9565b8063a4b91a01116100e7578063a4b91a011461050a578063a8fa568214610526578063a9784b3e14610556578063ac9650d814610586576101f9565b806377372213146104865780638b95dd71146104a25780639061b923146104be578063a22cb465146104ee576101f9565b80633603d758116101905780635c98042b1161015f5780635c98042b146103da578063623195b01461040a578063691f3431146104265780637315937d14610456576101f9565b80633603d7581461032e5780633b3b57de1461034a5780634cbf6ba41461037a57806359d1d43c146103aa576101f9565b80632203ab56116101cc5780632203ab561461029557806329cd62ea146102c6578063304e6ade146102e257806332f111d7146102fe576101f9565b806301ffc9a7146101fd5780630af179d71461022d57806310f13a8c14610249578063124a319c14610265575b5f80fd5b61021760048036038101906102129190613f96565b61072b565b6040516102249190613fdb565b60405180910390f35b61024760048036038101906102429190614088565b61076c565b005b610263600480360381019061025e919061413a565b6109bb565b005b61027f600480360381019061027a91906141cb565b610ab0565b60405161028c9190614248565b60405180910390f35b6102af60048036038101906102aa9190614294565b610ef1565b6040516102bd929190614351565b60405180910390f35b6102e060048036038101906102db919061437f565b61106a565b005b6102fc60048036038101906102f79190614088565b61113d565b005b61031860048036038101906103139190614294565b6111f6565b6040516103259190613fdb565b60405180910390f35b610348600480360381019061034391906143cf565b611274565b005b610364600480360381019061035f91906143cf565b61133f565b604051610371919061441a565b60405180910390f35b610394600480360381019061038f9190614433565b61135e565b6040516103a19190613fdb565b60405180910390f35b6103c460048036038101906103bf9190614471565b6113e2565b6040516103d19190614520565b60405180910390f35b6103f460048036038101906103ef91906143cf565b6114e9565b6040516104019190614540565b60405180910390f35b610424600480360381019061041f9190614560565b6115d0565b005b610440600480360381019061043b91906143cf565b6116a6565b60405161044d9190614520565b60405180910390f35b610470600480360381019061046b91906145fb565b61178d565b60405161047d9190614635565b60405180910390f35b6104a0600480360381019061049b9190614471565b611861565b005b6104bc60048036038101906104b79190614776565b61191a565b005b6104d860048036038101906104d391906147e2565b611a93565b6040516104e59190614540565b60405180910390f35b6105086004803603810190610503919061488a565b611ef1565b005b610524600480360381019061051f91906148c8565b612057565b005b610540600480360381019061053b919061494f565b6121ba565b60405161054d9190614540565b60405180910390f35b610570600480360381019061056b919061499f565b6122c9565b60405161057d9190613fdb565b60405180910390f35b6105a0600480360381019061059b9190614a44565b612367565b6040516105ad9190614b92565b60405180910390f35b6105d060048036038101906105cb91906143cf565b61237e565b6040516105dd9190614540565b60405180910390f35b61060060048036038101906105fb91906143cf565b612465565b60405161060e929190614bb2565b60405180910390f35b610631600480360381019061062c9190614088565b612507565b005b61064d60048036038101906106489190614bd9565b612686565b005b610669600480360381019061066491906143cf565b6126c8565b6040516106769190614c39565b60405180910390f35b61069960048036038101906106949190614c52565b6126eb565b6040516106a69190614b92565b60405180910390f35b6106c960048036038101906106c49190614caf565b612701565b005b6106e560048036038101906106e09190614cff565b612853565b6040516106f29190613fdb565b60405180910390f35b61071560048036038101906107109190614294565b6128e1565b6040516107229190614540565b60405180910390f35b5f639061b92360e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610765575061076482612a9d565b5b9050919050565b8261077681612b16565b61077e575f80fd5b5f806060805f805f808b81526020019081526020015f205f9054906101000a900467ffffffffffffffff1690505f6108025f8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612d1590919063ffffffff16565b90505b61080e81612d3e565b610940575f8761ffff1603610868578060400151965061082d81612d52565b9450846040516020016108409190614d77565b60405160208183030381529060405280519060200120925061086181612d87565b9350610932565b5f61087282612d52565b9050816040015161ffff168861ffff1614158061089f575061089d8187612dbf90919063ffffffff16565b155b15610930576109098c878a8e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508b8c88602001516108ff9190614dba565b5f8c51148a612de6565b81604001519750816020015196508095508580519060200120935061092d82612d87565b94505b505b61093b81613136565b610805565b505f845111156109af576109ae8a85888c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050898a8f8f90506109a49190614dba565b5f8a511488612de6565b5b50505050505050505050565b846109c581612b16565b6109cd575f80fd5b8282600a5f805f8b81526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8981526020019081526020015f208787604051610a36929190614e1b565b90815260200160405180910390209182610a51929190615037565b508484604051610a62929190614e1b565b6040518091039020867f448bc014f1536726cf8d54ff3d6481ed3cbc683c2591ca204274009afa09b1a187878787604051610aa09493929190615130565b60405180910390a3505050505050565b5f8060075f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bb45780915050610eeb565b5f610bbe8561133f565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610bfd575f92505050610eeb565b5f808273ffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000604051602401610c479190615178565b6040516020818303038152906040527f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610cd19190614d77565b5f60405180830381855afa9150503d805f8114610d09576040519150601f19603f3d011682016040523d82523d5f602084013e610d0e565b606091505b5091509150811580610d21575060208151105b80610d6e57505f60f81b81601f81518110610d3f57610d3e615191565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15610d7f575f945050505050610eeb565b8273ffffffffffffffffffffffffffffffffffffffff1686604051602401610da79190615178565b6040516020818303038152906040527f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610e319190614d77565b5f60405180830381855afa9150503d805f8114610e69576040519150601f19603f3d011682016040523d82523d5f602084013e610e6e565b606091505b508092508193505050811580610e85575060208151105b80610ed257505f60f81b81601f81518110610ea357610ea2615191565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15610ee3575f945050505050610eeb565b829450505050505b92915050565b5f60605f60015f805f8881526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f2090505f600190505b5f81118015610f635750848111155b1561104c575f85821614158015610f9557505f825f8381526020019081526020015f208054610f9190614e6a565b9050115b156110405780825f8381526020019081526020015f20808054610fb790614e6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610fe390614e6a565b801561102e5780601f106110055761010080835404028352916020019161102e565b820191905f5260205f20905b81548152906001019060200180831161101157829003601f168201915b50505050509050935093505050611063565b600181901b9050610f54565b505f60405180602001604052805f81525092509250505b9250929050565b8261107481612b16565b61107c575f80fd5b60405180604001604052808481526020018381525060095f805f8881526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f820151815f015560208201518160010155905050837f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46848460405161112f929190614bb2565b60405180910390a250505050565b8261114781612b16565b61114f575f80fd5b828260035f805f8981526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8781526020019081526020015f2091826111b5929190615220565b50837fe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d757884846040516111e8929190615319565b60405180910390a250505050565b5f8060025f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f8481526020019081526020015f20805461126990614e6a565b905011905092915050565b8061127e81612b16565b611286575f80fd5b5f808381526020019081526020015f205f81819054906101000a900467ffffffffffffffff16809291906112b99061533b565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050817fc6621ccb8f3f5a04bb6502154b2caf6adf5983fe76dfef1cfc9c42e3579db4445f808581526020019081526020015f205f9054906101000a900467ffffffffffffffff166040516113339190614c39565b60405180910390a25050565b5f61134b82603c6128e1565b611354906153b8565b60601c9050919050565b5f8060065f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f8481526020019081526020015f205f9054906101000a900461ffff1661ffff161415905092915050565b6060600a5f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f20838360405161144b929190614e1b565b9081526020016040518091039020805461146490614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461149090614e6a565b80156114db5780601f106114b2576101008083540402835291602001916114db565b820191905f5260205f20905b8154815290600101906020018083116114be57829003601f168201915b505050505090509392505050565b606060045f805f8581526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20805461154d90614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461157990614e6a565b80156115c45780601f1061159b576101008083540402835291602001916115c4565b820191905f5260205f20905b8154815290600101906020018083116115a757829003601f168201915b50505050509050919050565b836115da81612b16565b6115e2575f80fd5b5f846001866115f19190614dba565b16146115fb575f80fd5b828260015f805f8a81526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8881526020019081526020015f205f8781526020019081526020015f209182611670929190615220565b5083857faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe360405160405180910390a35050505050565b606060085f805f8581526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20805461170a90614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461173690614e6a565b80156117815780601f1061175857610100808354040283529160200191611781565b820191905f5260205f20905b81548152906001019060200180831161176457829003601f168201915b50505050509050919050565b5f8060285b5f811115611807576001810390507f3031323334353637383961626364656600000000000000000000000000000000600f85161a81536010840493506001810390507f3031323334353637383961626364656600000000000000000000000000000000600f85161a8153601084049350611792565b5060285f2090507f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e25f1b8160405160200161184392919061543e565b60405160208183030381529060405280519060200120915050919050565b8261186b81612b16565b611873575f80fd5b828260085f805f8981526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8781526020019081526020015f2091826118d9929190615037565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7848460405161190c929190615469565b60405180910390a250505050565b8261192481612b16565b61192c575f80fd5b5f82511415801561193f57506014825114155b8015611950575061194f83613274565b5b1561199257816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016119899190614540565b60405180910390fd5b837f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af75284846040516119c4929190614351565b60405180910390a2603c8303611a1957837f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd283611a00906153b8565b60601c604051611a109190614248565b60405180910390a25b8160025f805f8881526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f8581526020019081526020015f209081611a8c919061548b565b5050505050565b60605f85855f818110611aa957611aa8615191565b5b9050013560f81c60f81b60f81c60ff16905060288103611e32575f8686600190602992611ad893929190615562565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505090505f80611b345f60288561329b9092919063ffffffff16565b9150915080611b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6f906155e6565b60405180910390fd5b5f611b828361178d565b90505f88885f90600492611b9893929190615562565b90611ba39190615604565b9050633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611c1e5783604051602001611c029190614248565b6040516020818303038152906040529650505050505050611ee9565b6359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611d3d575f89896004908092611c7e93929190615562565b810190611c8b9190615700565b9150505f3073ffffffffffffffffffffffffffffffffffffffff166359d1d43c85846040518363ffffffff1660e01b8152600401611cca92919061575a565b5f60405180830381865afa158015611ce4573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190611d0c91906157f6565b905080604051602001611d1f9190614520565b60405160208183030381529060405298505050505050505050611ee9565b5f81838b8b6024908092611d5393929190615562565b604051602001611d669493929190615881565b60405160208183030381529060405290505f803073ffffffffffffffffffffffffffffffffffffffff1683604051611d9e9190614d77565b5f60405180830381855afa9150503d805f8114611dd6576040519150601f19603f3d011682016040523d82523d5f602084013e611ddb565b606091505b50915091508115611df757809950505050505050505050611ee9565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e2990615905565b60405180910390fd5b5f803073ffffffffffffffffffffffffffffffffffffffff168686604051611e5b929190615923565b5f60405180830381855afa9150503d805f8114611e93576040519150601f19603f3d011682016040523d82523d5f602084013e611e98565b606091505b50915091508115611eae57809350505050611ee9565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee090615985565b60405180910390fd5b949350505050565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1603611f5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5690615a13565b60405180910390fd5b80600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161204b9190613fdb565b60405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036120c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120bc90615a7b565b60405180910390fd5b80600c5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508015158273ffffffffffffffffffffffffffffffffffffffff16847ff0ddb3b04746704017f9aa8bd728fcc2c1d11675041205350018915f5e4750a0336040516121ad9190614248565b60405180910390a4505050565b606060055f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f8481526020019081526020015f205f8361ffff1661ffff1681526020019081526020015f20805461224490614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461227090614e6a565b80156122bb5780601f10612292576101008083540402835291602001916122bb565b820191905f5260205f20905b81548152906001019060200180831161229e57829003601f168201915b505050505090509392505050565b5f600c5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1690509392505050565b60606123765f801b84846132de565b905092915050565b606060035f805f8581526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2080546123e290614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461240e90614e6a565b80156124595780601f1061243057610100808354040283529160200191612459565b820191905f5260205f20905b81548152906001019060200180831161243c57829003601f168201915b50505050509050919050565b5f805f805f8581526020019081526020015f205f9054906101000a900467ffffffffffffffff16905060095f8267ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f015460095f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f20600101549250925050915091565b8261251181612b16565b612519575f80fd5b5f805f8681526020019081526020015f205f9054906101000a900467ffffffffffffffff1690505f60045f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8781526020019081526020015f20805461258090614e6a565b80601f01602080910402602001604051908101604052809291908181526020018280546125ac90614e6a565b80156125f75780601f106125ce576101008083540402835291602001916125f7565b820191905f5260205f20905b8154815290600101906020018083116125da57829003601f168201915b50505050509050848460045f8567ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8981526020019081526020015f209182612641929190615220565b50857f8f15ed4b723ef428f250961da8315675b507046737e19319fc1a4d81bfe87f8582878760405161267693929190615a99565b60405180910390a2505050505050565b8161269081612b16565b612698575f80fd5b6126c383603c846040516020016126af9190615b15565b60405160208183030381529060405261191a565b505050565b5f602052805f5260405f205f915054906101000a900467ffffffffffffffff1681565b60606126f88484846132de565b90509392505050565b8261270b81612b16565b612713575f80fd5b8160075f805f8881526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847f7c69f06bea0bdef565b709e93a147836b0063ba2dd89f02d0b7e8d931e6a6daa846040516128459190614248565b60405180910390a350505050565b5f600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b60605f60025f805f8781526020019081526020015f205f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f209050805f8481526020019081526020015f20805461295890614e6a565b80601f016020809104026020016040519081016040528092919081815260200182805461298490614e6a565b80156129cf5780601f106129a6576101008083540402835291602001916129cf565b820191905f5260205f20905b8154815290600101906020018083116129b257829003601f168201915b505050505091505f82511480156129f357505f6129eb8461349f565b63ffffffff16115b15612a9657805f638000000081526020019081526020015f208054612a1790614e6a565b80601f0160208091040260200160405190810160405280929190818152602001828054612a4390614e6a565b8015612a8e5780601f10612a6557610100808354040283529160200191612a8e565b820191905f5260205f20905b815481529060010190602001808311612a7157829003601f168201915b505050505091505b5092915050565b5f7f59d1d43c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612b0f5750612b0e826134d5565b5b9050919050565b5f81612b213361178d565b03612b2f5760019050612d10565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b8152600401612b899190614635565b602060405180830381865afa158015612ba4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bc89190615b43565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612cba577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636352211e845f1c6040518263ffffffff1660e01b8152600401612c789190615b6e565b602060405180830381865afa158015612c93573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612cb79190615b43565b90505b3373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480612cfa5750612cf98133612853565b5b80612d0c5750612d0b8184336122c9565b5b9150505b919050565b612d1d613e93565b82815f0181905250818160c0018181525050612d3881613136565b92915050565b5f815f015151826020015110159050919050565b6060612d808260200151612d6d845f0151856020015161354e565b845f01516135c79092919063ffffffff16565b9050919050565b6060612db88260a001518360a001518460c00151612da59190614dba565b845f01516135c79092919063ffffffff16565b9050919050565b5f81518351148015612dde575081805190602001208380519060200120145b905092915050565b5f878051906020012090505f612e078686896135c79092919063ffffffff16565b90508315612f9c575f60055f8567ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8c81526020019081526020015f205f8481526020019081526020015f205f8a61ffff1661ffff1681526020019081526020015f208054612e7590614e6a565b905014612ef85760065f8467ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8b81526020019081526020015f205f8381526020019081526020015f205f81819054906101000a900461ffff1680929190612edc90615b87565b91906101000a81548161ffff021916908361ffff160217905550505b60055f8467ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8b81526020019081526020015f205f8381526020019081526020015f205f8961ffff1661ffff1681526020019081526020015f205f612f5d9190613ed8565b897f03528ed0c2a3ebc993b12ce3c16bb382f9c7d88ef7d8a1bf290eaf35955a12078a8a604051612f8f929190615bbd565b60405180910390a261312a565b5f60055f8567ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8c81526020019081526020015f205f8481526020019081526020015f205f8a61ffff1661ffff1681526020019081526020015f20805461300290614e6a565b9050036130855760065f8467ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8b81526020019081526020015f205f8381526020019081526020015f205f81819054906101000a900461ffff168092919061306990615beb565b91906101000a81548161ffff021916908361ffff160217905550505b8060055f8567ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f8c81526020019081526020015f205f8481526020019081526020015f205f8a61ffff1661ffff1681526020019081526020015f2090816130ec919061548b565b50897f52a608b3303a48862d07a73d82fa221318c0027fbbcfb1b2329bface3f19ff2b8a8a8460405161312193929190615c14565b60405180910390a25b50505050505050505050565b8060c00151816020018181525050805f01515181602001511015613271575f613166825f0151836020015161354e565b82602001516131759190615c57565b905061318d81835f015161362c90919063ffffffff16565b826040019061ffff16908161ffff16815250506002816131ad9190615c57565b90506131c581835f015161362c90919063ffffffff16565b826060019061ffff16908161ffff16815250506002816131e59190615c57565b90506131fd81835f015161365590919063ffffffff16565b826080019063ffffffff16908163ffffffff16815250506004816132219190615c57565b90505f61323a82845f015161362c90919063ffffffff16565b61ffff16905060028261324d9190615c57565b9150818360a001818152505080826132659190615c57565b8360c001818152505050505b50565b5f638000000082148061329457505f61328c8361349f565b63ffffffff16115b9050919050565b5f80826028856132ab9190615c57565b146132bb575f80915091506132d6565b5f6132c786868661367e565b8093508192505050805f1c9250505b935093915050565b60608282905067ffffffffffffffff8111156132fd576132fc614652565b5b60405190808252806020026020018201604052801561333057816020015b606081526020019060019003908161331b5790505b5090505f5b83839050811015613497575f801b85146133d2575f84848381811061335d5761335c615191565b5b905060200281019061336f9190615c96565b60049060249261338193929190615562565b9061338c9190615cf8565b90508581146133d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133c790615dc6565b60405180910390fd5b505b5f803073ffffffffffffffffffffffffffffffffffffffff168686858181106133fe576133fd615191565b5b90506020028101906134109190615c96565b60405161341e929190615923565b5f60405180830381855af49150503d805f8114613456576040519150601f19603f3d011682016040523d82523d5f602084013e61345b565b606091505b509150915081613469575f80fd5b8084848151811061347d5761347c615191565b5b602002602001018190525050508080600101915050613335565b509392505050565b5f603c82036134b157600190506134d0565b638000000082189150638000000082106134cb575f6134cd565b815b90505b919050565b5f7fc8690233000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806135475750613546826136f9565b5b9050919050565b5f808290505b6001156135b2578351811061356c5761356b615de4565b5b5f613580828661377290919063ffffffff16565b60ff1690506001816135929190615c57565b8261359d9190615c57565b91505f81036135ac57506135b2565b50613554565b82816135be9190614dba565b91505092915050565b60608167ffffffffffffffff8111156135e3576135e2614652565b5b6040519080825280601f01601f1916602001820160405280156136155781602001600182028036833780820191505090505b5090506136258484835f866137b2565b9392505050565b5f6136438360028461363e9190615c57565b613802565b8160208401015160f01c905092915050565b5f61366c836004846136679190615c57565b613802565b8160208401015160e01c905092915050565b5f8083831015613693575f80915091506136f1565b5f84846136a09190614dba565b905060408111806136b15750855184115b156136c4575f801b5f92509250506136f1565b5f85602088010190506136d8815f8461384f565b92506001820160011c6020035f518160031b1c94505050505b935093915050565b5f7f691f3431000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061376b575061376a82613949565b5b9050919050565b5f613789836001846137849190615c57565b613802565b82828151811061379c5761379b615191565b5b602001015160f81c60f81b60f81c905092915050565b6137c78582866137c29190615c57565b613802565b6137dc8382846137d79190615c57565b613802565b6137fb826137e9856139c2565b01856137f4886139c2565b01836139ce565b5050505050565b815181111561384b578082516040517f8a3c1cfb000000000000000000000000000000000000000000000000000000008152600401613842929190615e11565b60405180910390fd5b5050565b5f6138b8565b5f81831a9150603a8210602f83111615613874576030820390506138b2565b6047821060408311161561389057600a604183030190506138b2565b606782106060831116156138ac57600a606183030190506138b2565b61010090505b92915050565b6001905081840160018316156138f4576138d35f8651613855565b80855360018601955060018501945060ff8111156138f2575f92508195505b505b5b8085101561394157845161390a600182613855565b6139145f83613855565b60041b1760ff81111561392b575f93505050613941565b80865350506002850194506001840193506138f5565b509392505050565b5f7f124a319c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806139bb57506139ba82613a1c565b5b9050919050565b5f602082019050919050565b5b601f8111156139f357815183526020830192506020820191506020810390506139cf565b8015613a17576001808260200360031b1b0380198351168185511680821786525050505b505050565b5f7fa8fa5682000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613ae657507f5c98042b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613af65750613af582613afd565b5b9050919050565b5f7fbc1c58d1000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613b6f5750613b6e82613b76565b5b9050919050565b5f817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f3b3b57de000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613c405750817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167ff1cb7e06000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613ca85750817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f32f111d7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613cb85750613cb782613cbf565b5b9050919050565b5f7f2203ab56000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613d315750613d3082613d38565b5b9050919050565b5f7fd700ff33000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613daa5750613da982613db1565b5b9050919050565b5f7f4fbf0433000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613e235750613e2282613e2a565b5b9050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6040518060e00160405280606081526020015f81526020015f61ffff1681526020015f61ffff1681526020015f63ffffffff1681526020015f81526020015f81525090565b508054613ee490614e6a565b5f825580601f10613ef55750613f12565b601f0160209004905f5260205f2090810190613f119190613f15565b5b50565b5b80821115613f2c575f815f905550600101613f16565b5090565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613f7581613f41565b8114613f7f575f80fd5b50565b5f81359050613f9081613f6c565b92915050565b5f60208284031215613fab57613faa613f39565b5b5f613fb884828501613f82565b91505092915050565b5f8115159050919050565b613fd581613fc1565b82525050565b5f602082019050613fee5f830184613fcc565b92915050565b5f819050919050565b61400681613ff4565b8114614010575f80fd5b50565b5f8135905061402181613ffd565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261404857614047614027565b5b8235905067ffffffffffffffff8111156140655761406461402b565b5b6020830191508360018202830111156140815761408061402f565b5b9250929050565b5f805f6040848603121561409f5761409e613f39565b5b5f6140ac86828701614013565b935050602084013567ffffffffffffffff8111156140cd576140cc613f3d565b5b6140d986828701614033565b92509250509250925092565b5f8083601f8401126140fa576140f9614027565b5b8235905067ffffffffffffffff8111156141175761411661402b565b5b6020830191508360018202830111156141335761413261402f565b5b9250929050565b5f805f805f6060868803121561415357614152613f39565b5b5f61416088828901614013565b955050602086013567ffffffffffffffff81111561418157614180613f3d565b5b61418d888289016140e5565b9450945050604086013567ffffffffffffffff8111156141b0576141af613f3d565b5b6141bc888289016140e5565b92509250509295509295909350565b5f80604083850312156141e1576141e0613f39565b5b5f6141ee85828601614013565b92505060206141ff85828601613f82565b9150509250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61423282614209565b9050919050565b61424281614228565b82525050565b5f60208201905061425b5f830184614239565b92915050565b5f819050919050565b61427381614261565b811461427d575f80fd5b50565b5f8135905061428e8161426a565b92915050565b5f80604083850312156142aa576142a9613f39565b5b5f6142b785828601614013565b92505060206142c885828601614280565b9150509250929050565b6142db81614261565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f614323826142e1565b61432d81856142eb565b935061433d8185602086016142fb565b61434681614309565b840191505092915050565b5f6040820190506143645f8301856142d2565b81810360208301526143768184614319565b90509392505050565b5f805f6060848603121561439657614395613f39565b5b5f6143a386828701614013565b93505060206143b486828701614013565b92505060406143c586828701614013565b9150509250925092565b5f602082840312156143e4576143e3613f39565b5b5f6143f184828501614013565b91505092915050565b5f61440482614209565b9050919050565b614414816143fa565b82525050565b5f60208201905061442d5f83018461440b565b92915050565b5f806040838503121561444957614448613f39565b5b5f61445685828601614013565b925050602061446785828601614013565b9150509250929050565b5f805f6040848603121561448857614487613f39565b5b5f61449586828701614013565b935050602084013567ffffffffffffffff8111156144b6576144b5613f3d565b5b6144c2868287016140e5565b92509250509250925092565b5f81519050919050565b5f82825260208201905092915050565b5f6144f2826144ce565b6144fc81856144d8565b935061450c8185602086016142fb565b61451581614309565b840191505092915050565b5f6020820190508181035f83015261453881846144e8565b905092915050565b5f6020820190508181035f8301526145588184614319565b905092915050565b5f805f806060858703121561457857614577613f39565b5b5f61458587828801614013565b945050602061459687828801614280565b935050604085013567ffffffffffffffff8111156145b7576145b6613f3d565b5b6145c387828801614033565b925092505092959194509250565b6145da81614228565b81146145e4575f80fd5b50565b5f813590506145f5816145d1565b92915050565b5f602082840312156146105761460f613f39565b5b5f61461d848285016145e7565b91505092915050565b61462f81613ff4565b82525050565b5f6020820190506146485f830184614626565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61468882614309565b810181811067ffffffffffffffff821117156146a7576146a6614652565b5b80604052505050565b5f6146b9613f30565b90506146c5828261467f565b919050565b5f67ffffffffffffffff8211156146e4576146e3614652565b5b6146ed82614309565b9050602081019050919050565b828183375f83830152505050565b5f61471a614715846146ca565b6146b0565b9050828152602081018484840111156147365761473561464e565b5b6147418482856146fa565b509392505050565b5f82601f83011261475d5761475c614027565b5b813561476d848260208601614708565b91505092915050565b5f805f6060848603121561478d5761478c613f39565b5b5f61479a86828701614013565b93505060206147ab86828701614280565b925050604084013567ffffffffffffffff8111156147cc576147cb613f3d565b5b6147d886828701614749565b9150509250925092565b5f805f80604085870312156147fa576147f9613f39565b5b5f85013567ffffffffffffffff81111561481757614816613f3d565b5b61482387828801614033565b9450945050602085013567ffffffffffffffff81111561484657614845613f3d565b5b61485287828801614033565b925092505092959194509250565b61486981613fc1565b8114614873575f80fd5b50565b5f8135905061488481614860565b92915050565b5f80604083850312156148a05761489f613f39565b5b5f6148ad858286016145e7565b92505060206148be85828601614876565b9150509250929050565b5f805f606084860312156148df576148de613f39565b5b5f6148ec86828701614013565b93505060206148fd868287016145e7565b925050604061490e86828701614876565b9150509250925092565b5f61ffff82169050919050565b61492e81614918565b8114614938575f80fd5b50565b5f8135905061494981614925565b92915050565b5f805f6060848603121561496657614965613f39565b5b5f61497386828701614013565b935050602061498486828701614013565b92505060406149958682870161493b565b9150509250925092565b5f805f606084860312156149b6576149b5613f39565b5b5f6149c3868287016145e7565b93505060206149d486828701614013565b92505060406149e5868287016145e7565b9150509250925092565b5f8083601f840112614a0457614a03614027565b5b8235905067ffffffffffffffff811115614a2157614a2061402b565b5b602083019150836020820283011115614a3d57614a3c61402f565b5b9250929050565b5f8060208385031215614a5a57614a59613f39565b5b5f83013567ffffffffffffffff811115614a7757614a76613f3d565b5b614a83858286016149ef565b92509250509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f82825260208201905092915050565b5f614ad2826142e1565b614adc8185614ab8565b9350614aec8185602086016142fb565b614af581614309565b840191505092915050565b5f614b0b8383614ac8565b905092915050565b5f602082019050919050565b5f614b2982614a8f565b614b338185614a99565b935083602082028501614b4585614aa9565b805f5b85811015614b805784840389528151614b618582614b00565b9450614b6c83614b13565b925060208a01995050600181019050614b48565b50829750879550505050505092915050565b5f6020820190508181035f830152614baa8184614b1f565b905092915050565b5f604082019050614bc55f830185614626565b614bd26020830184614626565b9392505050565b5f8060408385031215614bef57614bee613f39565b5b5f614bfc85828601614013565b9250506020614c0d858286016145e7565b9150509250929050565b5f67ffffffffffffffff82169050919050565b614c3381614c17565b82525050565b5f602082019050614c4c5f830184614c2a565b92915050565b5f805f60408486031215614c6957614c68613f39565b5b5f614c7686828701614013565b935050602084013567ffffffffffffffff811115614c9757614c96613f3d565b5b614ca3868287016149ef565b92509250509250925092565b5f805f60608486031215614cc657614cc5613f39565b5b5f614cd386828701614013565b9350506020614ce486828701613f82565b9250506040614cf5868287016145e7565b9150509250925092565b5f8060408385031215614d1557614d14613f39565b5b5f614d22858286016145e7565b9250506020614d33858286016145e7565b9150509250929050565b5f81905092915050565b5f614d51826142e1565b614d5b8185614d3d565b9350614d6b8185602086016142fb565b80840191505092915050565b5f614d828284614d47565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614dc482614261565b9150614dcf83614261565b9250828203905081811115614de757614de6614d8d565b5b92915050565b5f81905092915050565b5f614e028385614ded565b9350614e0f8385846146fa565b82840190509392505050565b5f614e27828486614df7565b91508190509392505050565b5f82905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680614e8157607f821691505b602082108103614e9457614e93614e3d565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614ef67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614ebb565b614f008683614ebb565b95508019841693508086168417925050509392505050565b5f819050919050565b5f614f3b614f36614f3184614261565b614f18565b614261565b9050919050565b5f819050919050565b614f5483614f21565b614f68614f6082614f42565b848454614ec7565b825550505050565b5f90565b614f7c614f70565b614f87818484614f4b565b505050565b5b81811015614faa57614f9f5f82614f74565b600181019050614f8d565b5050565b601f821115614fef57614fc081614e9a565b614fc984614eac565b81016020851015614fd8578190505b614fec614fe485614eac565b830182614f8c565b50505b505050565b5f82821c905092915050565b5f61500f5f1984600802614ff4565b1980831691505092915050565b5f6150278383615000565b9150826002028217905092915050565b6150418383614e33565b67ffffffffffffffff81111561505a57615059614652565b5b6150648254614e6a565b61506f828285614fae565b5f601f83116001811461509c575f841561508a578287013590505b615094858261501c565b8655506150fb565b601f1984166150aa86614e9a565b5f5b828110156150d1578489013582556001820191506020850194506020810190506150ac565b868310156150ee57848901356150ea601f891682615000565b8355505b6001600288020188555050505b50505050505050565b5f61510f83856144d8565b935061511c8385846146fa565b61512583614309565b840190509392505050565b5f6040820190508181035f830152615149818688615104565b9050818103602083015261515e818486615104565b905095945050505050565b61517281613f41565b82525050565b5f60208201905061518b5f830184615169565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82905092915050565b5f819050815f5260205f209050919050565b601f82111561521b576151ec816151c8565b6151f584614eac565b81016020851015615204578190505b61521861521085614eac565b830182614f8c565b50505b505050565b61522a83836151be565b67ffffffffffffffff81111561524357615242614652565b5b61524d8254614e6a565b6152588282856151da565b5f601f831160018114615285575f8415615273578287013590505b61527d858261501c565b8655506152e4565b601f198416615293866151c8565b5f5b828110156152ba57848901358255600182019150602085019450602081019050615295565b868310156152d757848901356152d3601f891682615000565b8355505b6001600288020188555050505b50505050505050565b5f6152f883856142eb565b93506153058385846146fa565b61530e83614309565b840190509392505050565b5f6020820190508181035f8301526153328184866152ed565b90509392505050565b5f61534582614c17565b915067ffffffffffffffff820361535f5761535e614d8d565b5b600182019050919050565b5f819050602082019050919050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f6153af8251615379565b80915050919050565b5f6153c2826142e1565b826153cc8461536a565b90506153d7816153a4565b92506014821015615417576154127fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802614ebb565b831692505b5050919050565b5f819050919050565b61543861543382613ff4565b61541e565b82525050565b5f6154498285615427565b6020820191506154598284615427565b6020820191508190509392505050565b5f6020820190508181035f830152615482818486615104565b90509392505050565b615494826142e1565b67ffffffffffffffff8111156154ad576154ac614652565b5b6154b78254614e6a565b6154c28282856151da565b5f60209050601f8311600181146154f3575f84156154e1578287015190505b6154eb858261501c565b865550615552565b601f198416615501866151c8565b5f5b8281101561552857848901518255600182019150602085019450602081019050615503565b868310156155455784890151615541601f891682615000565b8355505b6001600288020188555050505b505050505050565b5f80fd5b5f80fd5b5f80858511156155755761557461555a565b5b838611156155865761558561555e565b5b6001850283019150848603905094509492505050565b7f496e76616c6964206865782061646472657373000000000000000000000000005f82015250565b5f6155d06013836144d8565b91506155db8261559c565b602082019050919050565b5f6020820190508181035f8301526155fd816155c4565b9050919050565b5f61560f83836151be565b8261561a8135613f41565b9250600482101561565a576156557fffffffff0000000000000000000000000000000000000000000000000000000083600403600802614ebb565b831692505b505092915050565b5f67ffffffffffffffff82111561567c5761567b614652565b5b61568582614309565b9050602081019050919050565b5f6156a461569f84615662565b6146b0565b9050828152602081018484840111156156c0576156bf61464e565b5b6156cb8482856146fa565b509392505050565b5f82601f8301126156e7576156e6614027565b5b81356156f7848260208601615692565b91505092915050565b5f806040838503121561571657615715613f39565b5b5f61572385828601614013565b925050602083013567ffffffffffffffff81111561574457615743613f3d565b5b615750858286016156d3565b9150509250929050565b5f60408201905061576d5f830185614626565b818103602083015261577f81846144e8565b90509392505050565b5f61579a61579584615662565b6146b0565b9050828152602081018484840111156157b6576157b561464e565b5b6157c18482856142fb565b509392505050565b5f82601f8301126157dd576157dc614027565b5b81516157ed848260208601615788565b91505092915050565b5f6020828403121561580b5761580a613f39565b5b5f82015167ffffffffffffffff81111561582857615827613f3d565b5b615834848285016157c9565b91505092915050565b5f819050919050565b61585761585282613f41565b61583d565b82525050565b5f6158688385614d3d565b93506158758385846146fa565b82840190509392505050565b5f61588c8287615846565b60048201915061589c8286615427565b6020820191506158ad82848661585d565b915081905095945050505050565b7f556e737570706f727465642066756e6374696f6e0000000000000000000000005f82015250565b5f6158ef6014836144d8565b91506158fa826158bb565b602082019050919050565b5f6020820190508181035f83015261591c816158e3565b9050919050565b5f61592f82848661585d565b91508190509392505050565b7f5265736f6c7574696f6e206661696c65640000000000000000000000000000005f82015250565b5f61596f6011836144d8565b915061597a8261593b565b602082019050919050565b5f6020820190508181035f83015261599c81615963565b9050919050565b7f455243313135353a2073657474696e6720617070726f76616c207374617475735f8201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b5f6159fd6029836144d8565b9150615a08826159a3565b604082019050919050565b5f6020820190508181035f830152615a2a816159f1565b9050919050565b7f53657474696e672064656c65676174652073746174757320666f722073656c665f82015250565b5f615a656020836144d8565b9150615a7082615a31565b602082019050919050565b5f6020820190508181035f830152615a9281615a59565b9050919050565b5f6040820190508181035f830152615ab18186614319565b90508181036020830152615ac68184866152ed565b9050949350505050565b5f8160601b9050919050565b5f615ae682615ad0565b9050919050565b5f615af782615adc565b9050919050565b615b0f615b0a82614228565b615aed565b82525050565b5f615b208284615afe565b60148201915081905092915050565b5f81519050615b3d816145d1565b92915050565b5f60208284031215615b5857615b57613f39565b5b5f615b6584828501615b2f565b91505092915050565b5f602082019050615b815f8301846142d2565b92915050565b5f615b9182614918565b91505f8203615ba357615ba2614d8d565b5b600182039050919050565b615bb781614918565b82525050565b5f6040820190508181035f830152615bd58185614319565b9050615be46020830184615bae565b9392505050565b5f615bf582614918565b915061ffff8203615c0957615c08614d8d565b5b600182019050919050565b5f6060820190508181035f830152615c2c8186614319565b9050615c3b6020830185615bae565b8181036040830152615c4d8184614319565b9050949350505050565b5f615c6182614261565b9150615c6c83614261565b9250828201905080821115615c8457615c83614d8d565b5b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083356001602003843603038112615cb257615cb1615c8a565b5b80840192508235915067ffffffffffffffff821115615cd457615cd3615c8e565b5b602083019250600182023603831315615cf057615cef615c92565b5b509250929050565b5f615d0383836151be565b82615d0e8135613ff4565b92506020821015615d4e57615d497fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802614ebb565b831692505b505092915050565b7f6d756c746963616c6c3a20416c6c207265636f726473206d75737420686176655f8201527f2061206d61746368696e67206e616d6568617368000000000000000000000000602082015250565b5f615db06034836144d8565b9150615dbb82615d56565b604082019050919050565b5f6020820190508181035f830152615ddd81615da4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b5f604082019050615e245f8301856142d2565b615e3160208301846142d2565b939250505056fea2646970667358221220666f59a975a4c8228cbda082edea45bee7ea37187b083599527ba9c97134fb6f64736f6c6343000819003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x3", + "chainId": "0x14a34" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x90dd05", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0x5349252e11494c3eb04faefde3b94b6a7e8abb41a89af880771ff6ac3bf7882d", + "transactionIndex": "0x9", + "blockHash": "0x168e9322c12cfb1991ad6c6208ba4be7c06f656991aecd33fec9084b493ad1be", + "blockNumber": "0x21c3e15", + "gasUsed": "0x507d93", + "effectiveGasPrice": "0xe0f3b8", + "blobGasUsed": "0x321408", + "from": "0x1f3484e712c4657436fdf03f4bc882daea1e3e00", + "to": null, + "contractAddress": "0xa66c55a6b76967477af18a03f2f12d52251dc2c0", + "daFootprintGasScalar": "0x138", + "l1BaseFeeScalar": "0x44d", + "l1BlobBaseFee": "0x39aec6f64", + "l1BlobBaseFeeScalar": "0xa118b", + "l1Fee": "0x61c42bfc559d", + "l1GasPrice": "0x3a6b8fd", + "l1GasUsed": "0x2917e" + } + ], + "libraries": [], + "pending": [], + "returns": { + "resolver": { + "internal_type": "contract ConfigResolver", + "value": "0xA66c55a6b76967477af18A03F2f12d52251Dc2C0" + } + }, + "timestamp": 1766578976219, + "chain": 84532, + "commit": "c437ed7" +} \ No newline at end of file diff --git a/foundry.lock b/foundry.lock new file mode 100644 index 0000000..3160688 --- /dev/null +++ b/foundry.lock @@ -0,0 +1,8 @@ +{ + "lib/unruggable-gateways": { + "tag": { + "name": "v1.3.3", + "rev": "8061d898dc86a390689a1d86b3d2690416379e50" + } + } +} \ No newline at end of file diff --git a/foundry.toml b/foundry.toml index 6f0ab54..08ab399 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,8 @@ [profile.default] src = "src" out = "out" -libs = ["node_modules"] +libs = ["node_modules", "lib"] +solc = "0.8.25" # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/lib/unruggable-gateways b/lib/unruggable-gateways new file mode 160000 index 0000000..8061d89 --- /dev/null +++ b/lib/unruggable-gateways @@ -0,0 +1 @@ +Subproject commit 8061d898dc86a390689a1d86b3d2690416379e50 diff --git a/remappings.txt b/remappings.txt index 5325089..dd26ae9 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,6 +1,6 @@ -forge-std/=node_modules/forge-std/src/ +forge-std/=lib/forge-std/src/ @ensdomains/ens-contracts/=node_modules/@ensdomains/ens-contracts/contracts/ -@unruggable/gateways/=node_modules/@unruggable/gateways/contracts +@unruggable/=lib/unruggable-gateways/ @openzeppelin/contracts-v5/=node_modules/@openzeppelin/contracts-v5/ @openzeppelin/contracts/=node_modules/@openzeppelin/contracts/ clones-with-immutable-args/=node_modules/clones-with-immutable-args/ diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol new file mode 100644 index 0000000..aaada37 --- /dev/null +++ b/script/Deploy.s.sol @@ -0,0 +1,465 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import {Script, console} from "forge-std/Script.sol"; +import {ConfigResolver} from "../src/ConfigResolver.sol"; +import {AddressSubnameRegistrar} from "../src/AddressSubnameRegistrar.sol"; +import {L1ConfigResolver} from "../src/L1ConfigResolver.sol"; +import {ENS} from "@ensdomains/ens-contracts/registry/ENS.sol"; +import {INameWrapper} from "@ensdomains/ens-contracts/wrapper/INameWrapper.sol"; +import {IGatewayVerifier} from "@unruggable/contracts/IGatewayVerifier.sol"; + +/// @title Deploy +/// @notice Unified deployment script for ENS Config Resolver contracts +/// @dev Supports deploying ConfigResolver, AddressSubnameRegistrar, and L1ConfigResolver +/// +/// Usage: +/// # Deploy ConfigResolver only +/// forge script script/Deploy.s.sol --sig "deployConfigResolver()" --rpc-url $RPC_URL --account deployer --broadcast --verify +/// +/// # Deploy ConfigResolver + AddressSubnameRegistrar +/// PARENT_NODE=$(cast namehash yourname.eth) forge script script/Deploy.s.sol --sig "deployAll()" --rpc-url $RPC_URL --account deployer --broadcast --verify +/// +/// # Deploy L1ConfigResolver (for reading L2 records from L1) +/// L2_CONFIG_RESOLVER=0x... forge script script/Deploy.s.sol --sig "deployL1Resolver()" --rpc-url $RPC_URL --account deployer --broadcast --verify +/// +/// # Deploy L1ConfigResolver with custom verifier/chain (e.g., for non-Base L2s) +/// VERIFIER=0x... L2_CHAIN_ID=42161 L2_CONFIG_RESOLVER=0x... forge script script/Deploy.s.sol --sig "deployL1Resolver()" --rpc-url $RPC_URL --account deployer --broadcast --verify +contract Deploy is Script { + // ============ Chain IDs ============ + uint256 constant MAINNET = 1; + uint256 constant SEPOLIA = 11155111; + uint256 constant BASE_MAINNET = 8453; + uint256 constant BASE_SEPOLIA = 84532; + + // ============ ENS Addresses ============ + // ENS Registry is the same on Mainnet and Sepolia + address constant ENS_REGISTRY = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e; + // On L2s without ENS, we use a dummy address (users can only use reverse nodes) + address constant DUMMY_ENS = address(0); + + // ============ NameWrapper Addresses ============ + address constant MAINNET_NAME_WRAPPER = + 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401; + address constant SEPOLIA_NAME_WRAPPER = + 0x0635513f179D50A207757E05759CbD106d7dFcE8; + address constant DUMMY_NAME_WRAPPER = address(0); + + // ============ Gateway Verifier Addresses ============ + // Sepolia verifier for Base Sepolia + IGatewayVerifier constant SEPOLIA_VERIFIER = + IGatewayVerifier(0x7F68510F0fD952184ec0b976De429a29A2Ec0FE3); + // Mainnet verifier for Base + IGatewayVerifier constant MAINNET_VERIFIER = + IGatewayVerifier(0x0bC6c539e5fc1fb92F31dE34426f433557A9A5A2); + + // ============ Network Detection ============ + + function _getENSRegistry() internal view returns (address) { + if (block.chainid == MAINNET || block.chainid == SEPOLIA) { + return ENS_REGISTRY; + } else if ( + block.chainid == BASE_MAINNET || block.chainid == BASE_SEPOLIA + ) { + // L2s don't have ENS - use dummy (only reverse node auth works) + return DUMMY_ENS; + } else { + revert("Unsupported chain"); + } + } + + function _getNameWrapper() internal view returns (address) { + if (block.chainid == MAINNET) { + return MAINNET_NAME_WRAPPER; + } else if (block.chainid == SEPOLIA) { + return SEPOLIA_NAME_WRAPPER; + } else if ( + block.chainid == BASE_MAINNET || block.chainid == BASE_SEPOLIA + ) { + // L2s don't have NameWrapper + return DUMMY_NAME_WRAPPER; + } else { + revert("Unsupported chain"); + } + } + + function _getDefaultVerifier() internal view returns (address) { + if (block.chainid == MAINNET) { + return address(MAINNET_VERIFIER); + } else if (block.chainid == SEPOLIA) { + return address(SEPOLIA_VERIFIER); + } else { + return address(0); + } + } + + function _getDefaultL2ChainId() internal view returns (uint256) { + if (block.chainid == MAINNET) { + return BASE_MAINNET; + } else if (block.chainid == SEPOLIA) { + return BASE_SEPOLIA; + } else { + return 0; + } + } + + function _getNetworkName() internal view returns (string memory) { + if (block.chainid == MAINNET) { + return "Ethereum Mainnet"; + } else if (block.chainid == SEPOLIA) { + return "Sepolia"; + } else if (block.chainid == BASE_MAINNET) { + return "Base Mainnet"; + } else if (block.chainid == BASE_SEPOLIA) { + return "Base Sepolia"; + } else { + return "Unknown"; + } + } + + function _isL2() internal view returns (bool) { + return block.chainid == BASE_MAINNET || block.chainid == BASE_SEPOLIA; + } + + // ============ Deploy ConfigResolver Only ============ + + /// @notice Deploy ConfigResolver contract + /// @return resolver The deployed ConfigResolver address + function deployConfigResolver() public returns (ConfigResolver resolver) { + address ensRegistry = _getENSRegistry(); + address nameWrapper = _getNameWrapper(); + + console.log(""); + console.log("=========================================="); + console.log("Deploying ConfigResolver"); + console.log("=========================================="); + console.log("Network:", _getNetworkName()); + console.log("Chain ID:", block.chainid); + console.log("ENS Registry:", ensRegistry); + console.log("NameWrapper:", nameWrapper); + if (_isL2()) { + console.log(""); + console.log("NOTE: On L2, only reverse node authorization works."); + console.log( + " Users can set records for their own address only." + ); + } + console.log(""); + + vm.startBroadcast(); + resolver = new ConfigResolver( + ENS(ensRegistry), + INameWrapper(nameWrapper) + ); + vm.stopBroadcast(); + + console.log("ConfigResolver deployed at:", address(resolver)); + console.log(""); + } + + // ============ Deploy ConfigResolver + AddressSubnameRegistrar ============ + + /// @notice Deploy ConfigResolver and AddressSubnameRegistrar + /// @dev Requires PARENT_NODE environment variable (use `cast namehash yourname.eth`) + /// Note: AddressSubnameRegistrar requires ENS, so only works on L1 + /// @return resolver The deployed ConfigResolver address + /// @return registrar The deployed AddressSubnameRegistrar address + function deployAll() + public + returns (ConfigResolver resolver, AddressSubnameRegistrar registrar) + { + if (_isL2()) { + revert( + "AddressSubnameRegistrar requires ENS. Use deployConfigResolver() on L2." + ); + } + + bytes32 parentNode = vm.envBytes32("PARENT_NODE"); + address ensRegistry = _getENSRegistry(); + address nameWrapper = _getNameWrapper(); + + console.log(""); + console.log("=========================================="); + console.log("Deploying ConfigResolver + AddressSubnameRegistrar"); + console.log("=========================================="); + console.log("Network:", _getNetworkName()); + console.log("Chain ID:", block.chainid); + console.log("ENS Registry:", ensRegistry); + console.log("NameWrapper:", nameWrapper); + console.log("Parent Node:", vm.toString(parentNode)); + console.log(""); + + vm.startBroadcast(); + + // Deploy ConfigResolver first + resolver = new ConfigResolver( + ENS(ensRegistry), + INameWrapper(nameWrapper) + ); + console.log("ConfigResolver deployed at:", address(resolver)); + + // Deploy AddressSubnameRegistrar with ConfigResolver as default resolver + registrar = new AddressSubnameRegistrar( + ENS(ensRegistry), + INameWrapper(nameWrapper), + parentNode, + address(resolver) + ); + console.log("AddressSubnameRegistrar deployed at:", address(registrar)); + + vm.stopBroadcast(); + + _printNextSteps( + parentNode, + address(resolver), + address(registrar), + nameWrapper + ); + } + + // ============ Deploy L1ConfigResolver (for CCIP-Read) ============ + + /// @notice Deploy L1ConfigResolver for reading L2 records from L1 + /// @dev Requires L2_CONFIG_RESOLVER environment variable + /// Optional overrides: VERIFIER, L2_CHAIN_ID + /// @return resolver The deployed L1ConfigResolver address + function deployL1Resolver() public returns (L1ConfigResolver resolver) { + address l2ConfigResolver = vm.envAddress("L2_CONFIG_RESOLVER"); + + // Get verifier (env override or default for chain) + address defaultVerifier = _getDefaultVerifier(); + address verifierAddr = vm.envOr("VERIFIER", defaultVerifier); + require( + verifierAddr != address(0), + "VERIFIER required: no default for this chain" + ); + IGatewayVerifier verifier = IGatewayVerifier(verifierAddr); + + // Get L2 chain ID (env override or default for chain) + uint256 defaultL2ChainId = _getDefaultL2ChainId(); + uint256 l2ChainId = vm.envOr("L2_CHAIN_ID", defaultL2ChainId); + require( + l2ChainId != 0, + "L2_CHAIN_ID required: no default for this chain" + ); + + console.log(""); + console.log("=========================================="); + console.log("Deploying L1ConfigResolver"); + console.log("=========================================="); + console.log("Network:", _getNetworkName()); + console.log("Chain ID:", block.chainid); + console.log("Gateway Verifier:", verifierAddr); + if (verifierAddr != defaultVerifier) { + console.log(" (overridden via VERIFIER env var)"); + } + console.log("L2 Chain ID:", l2ChainId); + if (l2ChainId != defaultL2ChainId) { + console.log(" (overridden via L2_CHAIN_ID env var)"); + } + console.log("L2 ConfigResolver:", l2ConfigResolver); + console.log(""); + + vm.startBroadcast(); + resolver = new L1ConfigResolver(verifier, l2ChainId, l2ConfigResolver); + vm.stopBroadcast(); + + console.log("L1ConfigResolver deployed at:", address(resolver)); + console.log(""); + } + + // ============ Deploy L1 AddressSubnameRegistrar (for L1 claiming) ============ + + /// @notice Deploy AddressSubnameRegistrar on L1 with L1ConfigResolver as default resolver + /// @dev This allows users to claim subnames on L1 that resolve via CCIP-Read to L2 records + /// Requires PARENT_NODE and L1_CONFIG_RESOLVER environment variables + /// @return registrar The deployed AddressSubnameRegistrar address + function deployL1Registrar() + public + returns (AddressSubnameRegistrar registrar) + { + if (_isL2()) { + revert( + "AddressSubnameRegistrar for L1 claiming must be deployed on L1" + ); + } + + bytes32 parentNode = vm.envBytes32("PARENT_NODE"); + address l1ConfigResolver = vm.envAddress("L1_CONFIG_RESOLVER"); + address ensRegistry = _getENSRegistry(); + address nameWrapper = _getNameWrapper(); + + console.log(""); + console.log("=========================================="); + console.log("Deploying L1 AddressSubnameRegistrar"); + console.log("=========================================="); + console.log("Network:", _getNetworkName()); + console.log("Chain ID:", block.chainid); + console.log("ENS Registry:", ensRegistry); + console.log("NameWrapper:", nameWrapper); + console.log("Parent Node:", vm.toString(parentNode)); + console.log("Default Resolver (L1ConfigResolver):", l1ConfigResolver); + console.log(""); + + vm.startBroadcast(); + registrar = new AddressSubnameRegistrar( + ENS(ensRegistry), + INameWrapper(nameWrapper), + parentNode, + l1ConfigResolver + ); + vm.stopBroadcast(); + + console.log("AddressSubnameRegistrar deployed at:", address(registrar)); + console.log(""); + + _printL1RegistrarNextSteps( + parentNode, + l1ConfigResolver, + address(registrar), + nameWrapper + ); + } + + // ============ Deploy Everything (L2 + L1) ============ + + /// @notice Deploy all contracts: ConfigResolver, AddressSubnameRegistrar, and L1ConfigResolver + /// @dev Requires PARENT_NODE and L2_CONFIG_RESOLVER environment variables + /// Note: L1ConfigResolver should typically be deployed on a different chain than ConfigResolver + function deployEverything() + public + returns ( + ConfigResolver configResolver, + AddressSubnameRegistrar registrar, + L1ConfigResolver l1Resolver + ) + { + (configResolver, registrar) = deployAll(); + l1Resolver = deployL1Resolver(); + } + + // ============ Helper Functions ============ + + function _printNextSteps( + bytes32 parentNode, + address resolver, + address registrar, + address nameWrapper + ) internal pure { + string memory rpcPlaceholder = "$RPC_URL"; + + console.log(""); + console.log("=========================================="); + console.log("Next Steps"); + console.log("=========================================="); + console.log(""); + console.log("1. Set ConfigResolver as the resolver for your ENS name:"); + console.log(""); + console.log(" # If your name is WRAPPED:"); + console.log(" cast send", vm.toString(nameWrapper), "\\"); + console.log(' "setResolver(bytes32,address)" \\'); + console.log(" ", vm.toString(parentNode), "\\"); + console.log(" ", vm.toString(resolver), "\\"); + console.log(" --rpc-url", rpcPlaceholder, "--account "); + console.log(""); + console.log(" # If your name is UNWRAPPED:"); + console.log(" cast send", vm.toString(ENS_REGISTRY), "\\"); + console.log(' "setResolver(bytes32,address)" \\'); + console.log(" ", vm.toString(parentNode), "\\"); + console.log(" ", vm.toString(resolver), "\\"); + console.log(" --rpc-url", rpcPlaceholder, "--account "); + console.log(""); + console.log("2. Authorize the registrar to create subnames:"); + console.log(""); + console.log(" # If your name is WRAPPED:"); + console.log(" cast send", vm.toString(nameWrapper), "\\"); + console.log(' "setApprovalForAll(address,bool)" \\'); + console.log(" ", vm.toString(registrar), "true \\"); + console.log(" --rpc-url", rpcPlaceholder, "--account "); + console.log(""); + console.log("3. Users can now:"); + console.log(" - Set records via their reverse node"); + console.log(" - Claim their address subname via registrar.claim()"); + console.log(""); + } + + function _printL1RegistrarNextSteps( + bytes32 parentNode, + address l1ConfigResolver, + address registrar, + address nameWrapper + ) internal pure { + string memory rpcPlaceholder = "$RPC_URL"; + + console.log(""); + console.log("=========================================="); + console.log("Next Steps (L1 Registrar with CCIP-Read)"); + console.log("=========================================="); + console.log(""); + console.log("1. Authorize the registrar to create subnames on L1:"); + console.log(""); + console.log(" # If your name is WRAPPED:"); + console.log(" cast send", vm.toString(nameWrapper), "\\"); + console.log(' "setApprovalForAll(address,bool)" \\'); + console.log(" ", vm.toString(registrar), "true \\"); + console.log(" --rpc-url", rpcPlaceholder, "--account "); + console.log(""); + console.log("2. Users can now:"); + console.log(" - Claim subnames on L1 via registrar.claim()"); + console.log(" - Subnames resolve via CCIP-Read to L2 records"); + console.log( + " - Users can change their resolver if desired (they own the ENS node)" + ); + console.log(""); + console.log( + "3. To set records, users interact with the L2 ConfigResolver" + ); + console.log( + " - Records are stored on L2, read via CCIP-Read from L1" + ); + console.log(""); + console.log("Default Resolver:", l1ConfigResolver); + console.log("Registrar:", registrar); + console.log("Parent Node:", vm.toString(parentNode)); + console.log(""); + } + + // ============ Default Entry Point ============ + + /// @notice Default run function + /// @dev On L2: deploys ConfigResolver only + /// On L1: deploys ConfigResolver + AddressSubnameRegistrar (requires PARENT_NODE) + function run() external { + // On L2, just deploy ConfigResolver + if (_isL2()) { + deployConfigResolver(); + return; + } + + // On L1, check if PARENT_NODE is set + try vm.envBytes32("PARENT_NODE") { + deployAll(); + } catch { + console.log(""); + console.log("ERROR: PARENT_NODE environment variable not set"); + console.log(""); + console.log("Usage:"); + console.log( + ' PARENT_NODE=$(cast namehash "yourname.eth") forge script script/Deploy.s.sol \\' + ); + console.log( + " --rpc-url $RPC_URL --account deployer --broadcast --verify" + ); + console.log(""); + console.log("Or deploy ConfigResolver only:"); + console.log( + ' forge script script/Deploy.s.sol --sig "deployConfigResolver()" \\' + ); + console.log( + " --rpc-url $RPC_URL --account deployer --broadcast --verify" + ); + console.log(""); + revert("PARENT_NODE not set"); + } + } +} diff --git a/script/DeployAddressSubnameRegistrar.s.sol b/script/DeployAddressSubnameRegistrar.s.sol deleted file mode 100644 index 35b6ef9..0000000 --- a/script/DeployAddressSubnameRegistrar.s.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.17 <0.9.0; - -import {Script, console} from "forge-std/Script.sol"; -import {AddressSubnameRegistrar} from "../src/AddressSubnameRegistrar.sol"; -import {ENS} from "@ensdomains/ens-contracts/registry/ENS.sol"; -import {INameWrapper} from "@ensdomains/ens-contracts/wrapper/INameWrapper.sol"; - -contract DeployAddressSubnameRegistrar is Script { - // ENS Registry is the same on all networks - address constant ENS_REGISTRY = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e; - - // Sepolia testnet addresses - address constant SEPOLIA_NAME_WRAPPER = 0x0635513f179D50A207757E05759CbD106d7dFcE8; - - // Mainnet addresses - address constant MAINNET_NAME_WRAPPER = 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401; - - function run() external { - // Load configuration from environment - bytes32 parentNode = vm.envBytes32("PARENT_NODE"); - address defaultResolver = vm.envAddress("DEFAULT_RESOLVER"); - - // Get chain ID to determine which network we're on - uint256 chainId = block.chainid; - address nameWrapper; - - if (chainId == 11155111) { - // Sepolia - nameWrapper = SEPOLIA_NAME_WRAPPER; - console.log("Deploying to Sepolia testnet"); - } else if (chainId == 1) { - // Mainnet - nameWrapper = MAINNET_NAME_WRAPPER; - console.log("Deploying to Ethereum mainnet"); - } else { - revert("Unsupported chain. Use Sepolia (11155111) or Mainnet (1)"); - } - - // Start broadcasting transactions - vm.startBroadcast(); - - // Deploy AddressSubnameRegistrar - AddressSubnameRegistrar registrar = - new AddressSubnameRegistrar(ENS(ENS_REGISTRY), INameWrapper(nameWrapper), parentNode, defaultResolver); - - vm.stopBroadcast(); - - // Log deployment information - console.log("AddressSubnameRegistrar deployed at:", address(registrar)); - console.log("ENS Registry:", ENS_REGISTRY); - console.log("NameWrapper:", nameWrapper); - console.log("Parent Node:", vm.toString(parentNode)); - console.log("Default Resolver:", defaultResolver); - console.log("Chain ID:", chainId); - } -} diff --git a/script/DeployConfigResolver.s.sol b/script/DeployConfigResolver.s.sol deleted file mode 100644 index b4ced35..0000000 --- a/script/DeployConfigResolver.s.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.17 <0.9.0; - -import {Script, console} from "forge-std/Script.sol"; -import {ConfigResolver} from "../src/ConfigResolver.sol"; -import {ENS} from "@ensdomains/ens-contracts/registry/ENS.sol"; -import {INameWrapper} from "@ensdomains/ens-contracts/wrapper/INameWrapper.sol"; - -contract DeployConfigResolver is Script { - // ENS Registry is the same on all networks - address constant ENS_REGISTRY = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e; - - // Sepolia testnet addresses - address constant SEPOLIA_NAME_WRAPPER = 0x0635513f179D50A207757E05759CbD106d7dFcE8; - - // Mainnet addresses - address constant MAINNET_NAME_WRAPPER = 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401; - - function run() external { - // Get chain ID to determine which network we're on - uint256 chainId = block.chainid; - address nameWrapper; - - if (chainId == 11155111) { - // Sepolia - nameWrapper = SEPOLIA_NAME_WRAPPER; - console.log("Deploying to Sepolia testnet"); - } else if (chainId == 1) { - // Mainnet - nameWrapper = MAINNET_NAME_WRAPPER; - console.log("Deploying to Ethereum mainnet"); - } else { - revert("Unsupported chain. Use Sepolia (11155111) or Mainnet (1)"); - } - - // Start broadcasting transactions using the 'deployer' account - vm.startBroadcast(); - - // Deploy ConfigResolver - ConfigResolver resolver = new ConfigResolver(ENS(ENS_REGISTRY), INameWrapper(nameWrapper)); - - vm.stopBroadcast(); - - // Log deployment information - console.log("ConfigResolver deployed at:", address(resolver)); - console.log("ENS Registry:", ENS_REGISTRY); - console.log("NameWrapper:", nameWrapper); - console.log("Chain ID:", chainId); - console.log("Deployer:", msg.sender); - } -} diff --git a/script/deploy-all.sh b/script/deploy-all.sh deleted file mode 100755 index cb19ae0..0000000 --- a/script/deploy-all.sh +++ /dev/null @@ -1,181 +0,0 @@ -#!/bin/bash - -# Deploy ConfigResolver and AddressSubnameRegistrar -# Usage: ./script/deploy-all.sh -# Example: ./script/deploy-all.sh sepolia ethconfig.eth - -set -e - -# Set required environment variables -export ETHERSCAN_API_KEY="253URMD24CWBW4CNU19BC1T8YMY145DJ9S" - -# Parse arguments -NETWORK=${1:-sepolia} -PARENT_NAME=${2:-""} - -if [ -z "$PARENT_NAME" ]; then - echo "Usage: ./script/deploy-all.sh " - echo "Example: ./script/deploy-all.sh sepolia ethconfig.eth" - exit 1 -fi - -# Network configuration -if [ "$NETWORK" == "sepolia" ]; then - RPC_URL="${RPC_URL:-https://sepolia.gateway.tenderly.co}" - CHAIN_ID=11155111 - EXPLORER_URL="https://sepolia.etherscan.io" - NETWORK_NAME="Sepolia" -elif [ "$NETWORK" == "mainnet" ]; then - RPC_URL="${RPC_URL:-https://eth.llamarpc.com}" - CHAIN_ID=1 - EXPLORER_URL="https://etherscan.io" - NETWORK_NAME="Ethereum Mainnet" -else - echo "Error: Unsupported network. Use 'sepolia' or 'mainnet'" - exit 1 -fi - -# Check if deployer account exists -if [ ! -f ~/.foundry/keystores/deployer ]; then - echo "Error: Foundry account 'deployer' not found." - echo "Create it with: cast wallet import deployer --interactive" - exit 1 -fi - -# Compute parent node -PARENT_NODE=$(cast namehash "$PARENT_NAME") - -echo "==========================================" -echo "Deploying to $NETWORK_NAME" -echo "==========================================" -echo "RPC URL: $RPC_URL" -echo "Parent Name: $PARENT_NAME" -echo "Parent Node: $PARENT_NODE" -echo "" - -# Step 1: Deploy ConfigResolver -echo "Step 1: Deploying ConfigResolver..." -echo "-----------------------------------" - -forge script script/DeployConfigResolver.s.sol:DeployConfigResolver \ - --rpc-url $RPC_URL \ - --account deployer \ - --broadcast \ - --verify \ - --etherscan-api-key $ETHERSCAN_API_KEY \ - -vvv - -# Get address from broadcast logs (most reliable method) -LATEST_RUN="broadcast/DeployConfigResolver.s.sol/$CHAIN_ID/run-latest.json" -if [ -f "$LATEST_RUN" ]; then - CONFIG_RESOLVER=$(jq -r '.transactions[] | select(.contractName == "ConfigResolver") | .contractAddress' "$LATEST_RUN" 2>/dev/null | head -1) -fi - -if [ -z "$CONFIG_RESOLVER" ]; then - echo "Error: Failed to deploy ConfigResolver - no address in broadcast logs" - exit 1 -fi - -echo "ConfigResolver deployed at: $CONFIG_RESOLVER" -echo "" - -# Step 2: Deploy AddressSubnameRegistrar -echo "Step 2: Deploying AddressSubnameRegistrar..." -echo "---------------------------------------------" - -export PARENT_NODE -export DEFAULT_RESOLVER=$CONFIG_RESOLVER - -forge script script/DeployAddressSubnameRegistrar.s.sol:DeployAddressSubnameRegistrar \ - --rpc-url $RPC_URL \ - --account deployer \ - --broadcast \ - --verify \ - --etherscan-api-key $ETHERSCAN_API_KEY \ - -vvv - -# Get address from broadcast logs -LATEST_RUN="broadcast/DeployAddressSubnameRegistrar.s.sol/$CHAIN_ID/run-latest.json" -if [ -f "$LATEST_RUN" ]; then - REGISTRAR=$(jq -r '.transactions[] | select(.contractName == "AddressSubnameRegistrar") | .contractAddress' "$LATEST_RUN" 2>/dev/null | head -1) -fi - -if [ -z "$REGISTRAR" ]; then - echo "Error: Failed to deploy AddressSubnameRegistrar - no address in broadcast logs" - exit 1 -fi - -echo "AddressSubnameRegistrar deployed at: $REGISTRAR" -echo "" - -# Summary -echo "==========================================" -echo "Deployment Complete!" -echo "==========================================" -echo "" -echo "Network: $NETWORK_NAME" -echo "Parent Name: $PARENT_NAME" -echo "Parent Node: $PARENT_NODE" -echo "" -echo "Contracts:" -echo " ConfigResolver: $CONFIG_RESOLVER" -echo " AddressSubnameRegistrar: $REGISTRAR" -echo "" -echo "Etherscan:" -echo " ConfigResolver: $EXPLORER_URL/address/$CONFIG_RESOLVER" -echo " AddressSubnameRegistrar: $EXPLORER_URL/address/$REGISTRAR" -echo "" -echo "==========================================" -echo "Next Steps" -echo "==========================================" -echo "" -echo "1. Enable wildcard resolution (set ConfigResolver as parent's resolver):" -echo "" -echo " # If your name is WRAPPED:" -if [ "$NETWORK" == "sepolia" ]; then - NAME_WRAPPER="0x0635513f179D50A207757E05759CbD106d7dFcE8" -else - NAME_WRAPPER="0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401" -fi -echo " cast send $NAME_WRAPPER \\" -echo " \"setResolver(bytes32,address)\" \\" -echo " $PARENT_NODE \\" -echo " $CONFIG_RESOLVER \\" -echo " --rpc-url $RPC_URL \\" -echo " --account " -echo "" -echo " # If your name is UNWRAPPED:" -echo " cast send 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e \\" -echo " \"setResolver(bytes32,address)\" \\" -echo " $PARENT_NODE \\" -echo " $CONFIG_RESOLVER \\" -echo " --rpc-url $RPC_URL \\" -echo " --account " -echo "" -echo "2. Authorize the registrar to create subnames (for claiming):" -echo "" -echo " # If your name is WRAPPED (recommended):" -echo " cast send $NAME_WRAPPER \\" -echo " \"setApprovalForAll(address,bool)\" \\" -echo " $REGISTRAR \\" -echo " true \\" -echo " --rpc-url $RPC_URL \\" -echo " --account " -echo "" -echo " # If your name is UNWRAPPED:" -echo " cast send 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e \\" -echo " \"setOwner(bytes32,address)\" \\" -echo " $PARENT_NODE \\" -echo " $REGISTRAR \\" -echo " --rpc-url $RPC_URL \\" -echo " --account " -echo "" -echo "3. Users can now:" -echo " - Set records (works immediately via wildcard):" -echo " cast send $CONFIG_RESOLVER \"setText(bytes32,string,string)\" \\" -echo " \$(cast call $CONFIG_RESOLVER \"reverseNode(address)\" \$USER_ADDRESS) \\" -echo " \"url\" \"https://example.com\" --rpc-url $RPC_URL --account user" -echo "" -echo " - Claim their subname (optional, for ENS ownership):" -echo " cast send $REGISTRAR \"claim()\" --rpc-url $RPC_URL --account user" -echo "" diff --git a/script/deploy.sh b/script/deploy.sh deleted file mode 100755 index b8e00e8..0000000 --- a/script/deploy.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/bash - -# Set required environment variables -export ETHERSCAN_API_KEY="253URMD24CWBW4CNU19BC1T8YMY145DJ9S" - -# Network configuration - default to Sepolia -NETWORK=${1:-sepolia} - -if [ "$NETWORK" == "sepolia" ]; then - RPC_URL="https://sepolia.gateway.tenderly.co" - CHAIN_ID=11155111 - ENS_REGISTRY="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" - NAME_WRAPPER="0x0635513f179D50A207757E05759CbD106d7dFcE8" - EXPLORER_URL="https://sepolia.etherscan.io" - NETWORK_NAME="Sepolia" -elif [ "$NETWORK" == "mainnet" ]; then - RPC_URL="https://eth.llamarpc.com" - CHAIN_ID=1 - ENS_REGISTRY="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" - NAME_WRAPPER="0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401" - EXPLORER_URL="https://etherscan.io" - NETWORK_NAME="Ethereum Mainnet" -else - echo "Error: Unsupported network. Use 'sepolia' or 'mainnet'" - exit 1 -fi - -# Check if deployer account exists -if [ ! -f ~/.foundry/keystores/deployer ]; then - echo "Error: Foundry account 'deployer' not found." - echo "Keystore file should be at: ~/.foundry/keystores/deployer" - exit 1 -fi - -echo "==========================================" -echo "Deploying ConfigResolver to $NETWORK_NAME" -echo "==========================================" -echo "RPC URL: $RPC_URL" -echo "Chain ID: $CHAIN_ID" -echo "ENS Registry: $ENS_REGISTRY" -echo "NameWrapper: $NAME_WRAPPER" -echo "Deployer account: deployer (keystore)" -echo "" - -# Deploy the contract -echo "Deploying contract..." -DEPLOY_OUTPUT=$(forge script script/DeployConfigResolver.s.sol:DeployConfigResolver \ - --rpc-url $RPC_URL \ - --account deployer \ - --broadcast \ - --verify \ - --etherscan-api-key $ETHERSCAN_API_KEY \ - -vvvv 2>&1) - -# Extract the deployed contract address from the output -CONTRACT_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -o 'ConfigResolver deployed at: 0x[a-fA-F0-9]\{40\}' | sed 's/ConfigResolver deployed at: //' || \ - echo "$DEPLOY_OUTPUT" | grep -o 'Deployed to: 0x[a-fA-F0-9]\{40\}' | sed 's/Deployed to: //' || \ - echo "$DEPLOY_OUTPUT" | grep -A 5 "ConfigResolver" | grep -o '0x[a-fA-F0-9]\{40\}' | head -1) - -if [ -z "$CONTRACT_ADDRESS" ]; then - # Try to get it from broadcast logs - LATEST_BROADCAST=$(find broadcast/DeployConfigResolver.s.sol -type d -name "$CHAIN_ID" 2>/dev/null | sort -r | head -1) - if [ -n "$LATEST_BROADCAST" ]; then - LATEST_RUN=$(find "$LATEST_BROADCAST" -name "run-latest.json" 2>/dev/null) - if [ -n "$LATEST_RUN" ]; then - CONTRACT_ADDRESS=$(jq -r '.transactions[] | select(.contractName == "ConfigResolver") | .contractAddress' "$LATEST_RUN" 2>/dev/null | head -1) - fi - fi -fi - -if [ -z "$CONTRACT_ADDRESS" ]; then - echo "Error: Could not extract contract address from deployment output" - echo "Deployment output:" - echo "$DEPLOY_OUTPUT" - exit 1 -fi - -echo "" -echo "==========================================" -echo "Deployment successful!" -echo "Contract address: $CONTRACT_ADDRESS" -echo "==========================================" -echo "" - -# Note: Verification is handled automatically by the --verify flag during deployment -# Both Etherscan and Sourcify will be notified -echo "==========================================" -echo "Verification" -echo "==========================================" -echo "Etherscan verification was attempted during deployment via --verify flag" -echo "Sourcify will automatically pick up the verification from Etherscan" -echo "" -echo "Contract address: $CONTRACT_ADDRESS" -echo "Etherscan: $EXPLORER_URL/address/$CONTRACT_ADDRESS" -echo "Sourcify: https://sourcify.dev/#/lookup/$CONTRACT_ADDRESS" -echo "" - diff --git a/src/AddressSubnameRegistrar.sol b/src/AddressSubnameRegistrar.sol index 29e5669..54aff2b 100644 --- a/src/AddressSubnameRegistrar.sol +++ b/src/AddressSubnameRegistrar.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity >=0.8.17 <0.9.0; +pragma solidity ^0.8.25; import "@ensdomains/ens-contracts/registry/ENS.sol"; import {INameWrapper} from "@ensdomains/ens-contracts/wrapper/INameWrapper.sol"; @@ -87,11 +87,13 @@ contract AddressSubnameRegistrar { /// @notice Get the label (hex address) for a given address /// @param addr The address - /// @return The lowercase hex string (40 characters, no 0x prefix) + /// @return The lowercase hex string (42 characters, with 0x prefix) function getLabel(address addr) public pure returns (string memory) { - bytes memory ret = new bytes(40); + bytes memory ret = new bytes(42); + ret[0] = "0"; + ret[1] = "x"; uint160 addrVal = uint160(addr); - for (uint256 i = 40; i > 0;) { + for (uint256 i = 42; i > 2;) { unchecked { i--; ret[i] = bytes1(uint8(lookup[addrVal & 0xf])); @@ -145,10 +147,14 @@ contract AddressSubnameRegistrar { ens.setSubnodeRecord(parentNode, labelHash, owner, defaultResolver, 0); } - /// @dev Compute the keccak256 hash of the lowercase hex representation of an address + /// @dev Compute the keccak256 hash of the lowercase hex representation of an address with 0x prefix function sha3HexAddress(address addr) internal pure returns (bytes32 ret) { assembly { - for { let i := 40 } gt(i, 0) {} { + // Store "0x" prefix at positions 0-1 + mstore8(0, 0x30) // '0' = 0x30 + mstore8(1, 0x78) // 'x' = 0x78 + // Store hex address starting at position 2 + for { let i := 42 } gt(i, 2) {} { i := sub(i, 1) mstore8(i, byte(and(addr, 0xf), lookup)) addr := div(addr, 0x10) @@ -156,7 +162,7 @@ contract AddressSubnameRegistrar { mstore8(i, byte(and(addr, 0xf), lookup)) addr := div(addr, 0x10) } - ret := keccak256(0, 40) + ret := keccak256(0, 42) } } } diff --git a/src/ConfigResolver.sol b/src/ConfigResolver.sol index d1d27fe..6fc1f62 100644 --- a/src/ConfigResolver.sol +++ b/src/ConfigResolver.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity >=0.8.17 <0.9.0; +pragma solidity ^0.8.25; import "@ensdomains/ens-contracts/registry/ENS.sol"; import "@ensdomains/ens-contracts/resolvers/profiles/ABIResolver.sol"; @@ -125,7 +125,7 @@ contract ConfigResolver is return owner == msg.sender || isApprovedForAll(owner, msg.sender) || isApprovedFor(owner, node, msg.sender); } - /// @dev ENSIP-10 wildcard resolution. Resolves subnames like
.parent.eth + /// @dev ENSIP-10 wildcard resolution. Resolves subnames like 0x
.parent.eth /// without requiring them to be claimed in ENS, and also supports standard resolution /// for manually created names. /// @param name The DNS-encoded name to resolve @@ -135,11 +135,16 @@ contract ConfigResolver is // Extract the first label length uint256 labelLen = uint8(name[0]); - // If this is a 40-char hex address label, handle wildcard resolution - if (labelLen == 40) { - // Parse the hex address from the label - bytes memory label = name[1:41]; - (address resolvedAddr, bool valid) = label.hexToAddress(0, 40); + // If this is a 42-char hex address label (0x + 40 hex chars), handle wildcard resolution + if (labelLen == 42) { + // Parse the hex address from the label (skip "0x" prefix) + bytes memory label = name[1:43]; + // Verify "0x" prefix + if (label[0] != 0x30 || label[1] != 0x78) { + // '0' = 0x30, 'x' = 0x78 + revert("Invalid address prefix"); + } + (address resolvedAddr, bool valid) = label.hexToAddress(2, 42); if (!valid) { revert("Invalid hex address"); } diff --git a/src/IL1ConfigResolver.sol b/src/IL1ConfigResolver.sol new file mode 100644 index 0000000..15fc604 --- /dev/null +++ b/src/IL1ConfigResolver.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +/// @title IL1ConfigResolver +/// @notice Interface for L1 resolvers that read ENS records from an L2 ConfigResolver +interface IL1ConfigResolver { + /// @notice Returns the chain ID of the L2 where the ConfigResolver is deployed + /// @return The L2 chain ID + function l2ChainId() external view returns (uint256); + + /// @notice Returns the address of the ConfigResolver on L2 + /// @return The L2 ConfigResolver address + function l2ConfigResolver() external view returns (address); +} diff --git a/src/L1ConfigResolver.sol b/src/L1ConfigResolver.sol new file mode 100644 index 0000000..ce99a45 --- /dev/null +++ b/src/L1ConfigResolver.sol @@ -0,0 +1,349 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { + GatewayFetcher, + GatewayRequest +} from "@unruggable/contracts/GatewayFetcher.sol"; +import {GatewayFetchTarget} from "@unruggable/contracts/GatewayFetchTarget.sol"; +import {IGatewayVerifier} from "@unruggable/contracts/IGatewayVerifier.sol"; +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; + +// ENS Resolver Interfaces +import { + IAddrResolver +} from "@ensdomains/ens-contracts/resolvers/profiles/IAddrResolver.sol"; +import { + IAddressResolver +} from "@ensdomains/ens-contracts/resolvers/profiles/IAddressResolver.sol"; +import { + ITextResolver +} from "@ensdomains/ens-contracts/resolvers/profiles/ITextResolver.sol"; +import { + IContentHashResolver +} from "@ensdomains/ens-contracts/resolvers/profiles/IContentHashResolver.sol"; +import { + IExtendedResolver +} from "@ensdomains/ens-contracts/resolvers/profiles/IExtendedResolver.sol"; +import {IL1ConfigResolver} from "./IL1ConfigResolver.sol"; + +/// @title L1ConfigResolver +/// @notice An L1 resolver that reads ENS records from the ConfigResolver deployed on L2 (Base) +/// @dev Uses CCIP-Read (EIP-3668) via Unruggable Gateways to trustlessly read L2 storage +contract L1ConfigResolver is + GatewayFetchTarget, + IERC165, + IExtendedResolver, + IL1ConfigResolver +{ + using GatewayFetcher for GatewayRequest; + + // ============ Errors ============ + error UnsupportedSelector(bytes4 selector); + + // ============ Constants ============ + + // Storage slot constants for ConfigResolver + // Verified via `forge inspect ConfigResolver storage` + uint256 constant SLOT_RECORD_VERSIONS = 0; + uint256 constant SLOT_VERSIONABLE_ADDRESSES = 2; + uint256 constant SLOT_VERSIONABLE_HASHES = 3; + uint256 constant SLOT_VERSIONABLE_TEXTS = 10; + + // Coin type for Ethereum (SLIP-44) + uint256 constant COIN_TYPE_ETH = 60; + + // ============ Immutables ============ + IGatewayVerifier public immutable verifier; + uint256 public immutable l2ChainId; + address public immutable l2ConfigResolver; + + // ============ Constructor ============ + constructor( + IGatewayVerifier _verifier, + uint256 _l2ChainId, + address _l2ConfigResolver + ) { + verifier = _verifier; + l2ChainId = _l2ChainId; + l2ConfigResolver = _l2ConfigResolver; + } + + // ============ ERC-165 ============ + function supportsInterface( + bytes4 interfaceId + ) external pure override returns (bool) { + return + interfaceId == type(IERC165).interfaceId || + interfaceId == type(IExtendedResolver).interfaceId || + interfaceId == type(IAddrResolver).interfaceId || + interfaceId == type(IAddressResolver).interfaceId || + interfaceId == type(ITextResolver).interfaceId || + interfaceId == type(IContentHashResolver).interfaceId || + interfaceId == type(IL1ConfigResolver).interfaceId; + } + + // ============ ENSIP-10 Extended Resolver ============ + + /// @notice Resolves ENS records by reading from the L2 ConfigResolver + /// @dev The DNS-encoded name parameter is unused for direct resolution + /// @param data The ABI-encoded function call (selector + args) + /// @return The ABI-encoded result + function resolve( + bytes calldata, + bytes calldata data + ) external view override returns (bytes memory) { + bytes4 selector = bytes4(data); + + // Decode the node from calldata + bytes32 node; + if ( + selector == IAddrResolver.addr.selector || + selector == IContentHashResolver.contenthash.selector + ) { + node = abi.decode(data[4:], (bytes32)); + } else if (selector == IAddressResolver.addr.selector) { + (node, ) = abi.decode(data[4:], (bytes32, uint256)); + } else if (selector == ITextResolver.text.selector) { + (node, ) = abi.decode(data[4:], (bytes32, string)); + } else { + revert UnsupportedSelector(selector); + } + + // Build the gateway request + GatewayRequest memory req = _buildRequest(node, data); + + // Execute CCIP-Read fetch + fetch( + verifier, + req, + this.resolveCallback.selector, + data, + new string[](0) + ); + } + + /// @notice Callback that receives verified L2 data + /// @param values The array of values read from L2 + /// @param exitCode The exit code (0 = success) + /// @param data The original calldata passed through + /// @return The ABI-encoded result + function resolveCallback( + bytes[] calldata values, + uint8 exitCode, + bytes calldata data + ) external pure returns (bytes memory) { + // Exit code != 0 means record not found or error + if (exitCode != 0) { + return _emptyResponse(bytes4(data)); + } + + bytes4 selector = bytes4(data); + + if (selector == IAddrResolver.addr.selector) { + // addr(bytes32) returns address + bytes memory addrBytes = values[0]; + if (addrBytes.length == 0) { + return abi.encode(address(0)); + } + return abi.encode(address(bytes20(addrBytes))); + } else if (selector == IAddressResolver.addr.selector) { + // addr(bytes32, uint256) returns bytes + return abi.encode(values[0]); + } else if (selector == ITextResolver.text.selector) { + // text(bytes32, string) returns string + return abi.encode(string(values[0])); + } else if (selector == IContentHashResolver.contenthash.selector) { + // contenthash(bytes32) returns bytes + return abi.encode(values[0]); + } + + return new bytes(0); + } + + // ============ Direct Resolution Methods ============ + + /// @notice Get the ETH address for a node + /// @param node The ENS node hash + /// @return The ETH address + function addr(bytes32 node) external view returns (address) { + GatewayRequest memory req = _buildAddrRequest(node, COIN_TYPE_ETH); + fetch( + verifier, + req, + this.addrCallback.selector, + abi.encode(node), + new string[](0) + ); + } + + /// @notice Callback for addr() + function addrCallback( + bytes[] calldata values, + uint8 exitCode, + bytes calldata + ) external pure returns (address) { + if (exitCode != 0 || values[0].length == 0) { + return address(0); + } + return address(bytes20(values[0])); + } + + /// @notice Get a text record for a node + /// @param node The ENS node hash + /// @param key The text record key + /// @return The text record value + function text( + bytes32 node, + string calldata key + ) external view returns (string memory) { + GatewayRequest memory req = _buildTextRequest(node, key); + fetch(verifier, req, this.textCallback.selector, "", new string[](0)); + } + + /// @notice Callback for text() + function textCallback( + bytes[] calldata values, + uint8 exitCode, + bytes calldata + ) external pure returns (string memory) { + if (exitCode != 0 || values[0].length == 0) { + return ""; + } + return string(values[0]); + } + + /// @notice Get the contenthash for a node + /// @param node The ENS node hash + /// @return The contenthash bytes + function contenthash(bytes32 node) external view returns (bytes memory) { + GatewayRequest memory req = _buildContenthashRequest(node); + fetch( + verifier, + req, + this.contenthashCallback.selector, + "", + new string[](0) + ); + } + + /// @notice Callback for contenthash() + function contenthashCallback( + bytes[] calldata values, + uint8 exitCode, + bytes calldata + ) external pure returns (bytes memory) { + if (exitCode != 0) { + return ""; + } + return values[0]; + } + + // ============ Internal Request Builders ============ + + /// @notice Build a gateway request based on the selector + function _buildRequest( + bytes32 node, + bytes calldata data + ) internal view returns (GatewayRequest memory) { + bytes4 selector = bytes4(data); + + if (selector == IAddrResolver.addr.selector) { + return _buildAddrRequest(node, COIN_TYPE_ETH); + } else if (selector == IAddressResolver.addr.selector) { + (, uint256 coinType) = abi.decode(data[4:], (bytes32, uint256)); + return _buildAddrRequest(node, coinType); + } else if (selector == ITextResolver.text.selector) { + (, string memory key) = abi.decode(data[4:], (bytes32, string)); + return _buildTextRequest(node, key); + } else if (selector == IContentHashResolver.contenthash.selector) { + return _buildContenthashRequest(node); + } + + revert UnsupportedSelector(selector); + } + + /// @notice Build a request to read an address record + /// @dev Reads versionable_addresses[recordVersions[node]][node][coinType] + function _buildAddrRequest( + bytes32 node, + uint256 coinType + ) internal view returns (GatewayRequest memory req) { + req = GatewayFetcher.newRequest(1).setTarget(l2ConfigResolver); + + // Step 1: Read recordVersions[node] and push to stack + // recordVersions is mapping(bytes32 => uint64) at slot 0 + req = req.setSlot(SLOT_RECORD_VERSIONS).push(node).follow().read(); + + // Step 2: Now stack has the version, use it to navigate versionable_addresses + // versionable_addresses[version][node][coinType] + req = req.setSlot(SLOT_VERSIONABLE_ADDRESSES); + // follow() uses top of stack (version) as key + req = req.follow(); + // Now push node and follow + req = req.push(node).follow(); + // Now push coinType and follow + req = req.push(coinType).follow(); + // Read the bytes value (dynamic bytes) + req = req.readBytes().setOutput(0); + } + + /// @notice Build a request to read a text record + /// @dev Reads versionable_texts[recordVersions[node]][node][key] + function _buildTextRequest( + bytes32 node, + string memory key + ) internal view returns (GatewayRequest memory req) { + req = GatewayFetcher.newRequest(1).setTarget(l2ConfigResolver); + + // Step 1: Read recordVersions[node] and push to stack + req = req.setSlot(SLOT_RECORD_VERSIONS).push(node).follow().read(); + + // Step 2: Navigate versionable_texts[version][node][key] + req = req.setSlot(SLOT_VERSIONABLE_TEXTS); + // follow() uses top of stack (version) as key + req = req.follow(); + // Push node and follow + req = req.push(node).follow(); + // Push key (string) and follow + req = req.push(key).follow(); + // Read the string value (dynamic bytes) + req = req.readBytes().setOutput(0); + } + + /// @notice Build a request to read a contenthash + /// @dev Reads versionable_hashes[recordVersions[node]][node] + function _buildContenthashRequest( + bytes32 node + ) internal view returns (GatewayRequest memory req) { + req = GatewayFetcher.newRequest(1).setTarget(l2ConfigResolver); + + // Step 1: Read recordVersions[node] and push to stack + req = req.setSlot(SLOT_RECORD_VERSIONS).push(node).follow().read(); + + // Step 2: Navigate versionable_hashes[version][node] + req = req.setSlot(SLOT_VERSIONABLE_HASHES); + // follow() uses top of stack (version) as key + req = req.follow(); + // Push node and follow + req = req.push(node).follow(); + // Read the bytes value (dynamic bytes) + req = req.readBytes().setOutput(0); + } + + /// @notice Return an empty response for the given selector + function _emptyResponse( + bytes4 selector + ) internal pure returns (bytes memory) { + if (selector == IAddrResolver.addr.selector) { + return abi.encode(address(0)); + } else if (selector == IAddressResolver.addr.selector) { + return abi.encode(new bytes(0)); + } else if (selector == ITextResolver.text.selector) { + return abi.encode(""); + } else if (selector == IContentHashResolver.contenthash.selector) { + return abi.encode(new bytes(0)); + } + return new bytes(0); + } +} diff --git a/test/AddressSubnameRegistrar.t.sol b/test/AddressSubnameRegistrar.t.sol index 184004b..102b7ad 100644 --- a/test/AddressSubnameRegistrar.t.sol +++ b/test/AddressSubnameRegistrar.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; +pragma solidity ^0.8.25; import {Test, console} from "forge-std/Test.sol"; import {AddressSubnameRegistrar} from "../src/AddressSubnameRegistrar.sol"; @@ -63,14 +63,14 @@ contract AddressSubnameRegistrarTest is Test { // Log the label for verification string memory label = registrar.getLabel(alice); console.log("Alice's subname label:", label); - // Should be: 8d25687829d6b85d9e0020b8c89e3ca24de20a89 + // Should be: 0x8d25687829d6b85d9e0020b8c89e3ca24de20a89 } function test_LabelIsNormalizedLowercase() public { // The address 0x8d25687829D6b85d9e0020B8c89e3Ca24dE20a89 - // should produce label: 8d25687829d6b85d9e0020b8c89e3ca24de20a89 + // should produce label: 0x8d25687829d6b85d9e0020b8c89e3ca24de20a89 string memory label = registrar.getLabel(alice); - assertEq(label, "8d25687829d6b85d9e0020b8c89e3ca24de20a89"); + assertEq(label, "0x8d25687829d6b85d9e0020b8c89e3ca24de20a89"); } function test_CannotClaimSameSubnameTwice() public { diff --git a/test/ConfigResolver.t.sol b/test/ConfigResolver.t.sol index 070884d..edd93bf 100644 --- a/test/ConfigResolver.t.sol +++ b/test/ConfigResolver.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; +pragma solidity ^0.8.25; import {Test} from "forge-std/Test.sol"; import {ConfigResolver} from "../src/ConfigResolver.sol"; @@ -279,37 +279,199 @@ contract ConfigResolverTest is Test { } function test_WildcardResolveInvalidHex() public { - // Test with invalid hex characters (40 chars but not valid hex) - // "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" - 40 z's + // Test with invalid hex characters (42 chars with 0x prefix but invalid hex after) + // "0xzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" - 0x + 40 z's bytes memory invalidName = - hex"287a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a04746573740365746800"; + hex"2a30787a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a04746573740365746800"; bytes memory data = abi.encodeWithSelector(IAddrResolver.addr.selector, bytes32(0)); vm.expectRevert("Invalid hex address"); resolver.resolve(invalidName, data); } - // Helper to build DNS-encoded name for address.parent.tld + function test_WildcardResolveChecksummedAddress() public { + // Test that checksummed (mixed case) addresses resolve correctly + // Using a well-known checksummed address format + address testAddr = 0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B; + + // Build DNS name with checksummed address (mixed case) + bytes memory checksummedName = _buildDnsNameWithChecksummedAddress(testAddr, "test", "eth"); + + // Build the addr(bytes32) call data + bytes memory data = abi.encodeWithSelector(IAddrResolver.addr.selector, bytes32(0)); + + // Call resolve - should work with checksummed address + bytes memory result = resolver.resolve(checksummedName, data); + + // Decode and verify + address resolved = abi.decode(result, (address)); + assertEq(resolved, testAddr); + } + + function test_WildcardResolveChecksummedAndLowercaseReturnSameResult() public { + // Verify that both checksummed and lowercase addresses resolve to the same result + address testAddr = 0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B; + + // Set up a text record for this address + bytes32 addrReverseNode = resolver.reverseNode(testAddr); + + // We need to give testAddr ownership of their reverse node + vm.prank(testAddr); + reverseRegistrar.claimForAddr(testAddr, testAddr, address(resolver)); + + vm.prank(testAddr); + resolver.setText(addrReverseNode, "url", "https://vitalik.example.com"); + + // Build DNS names with both formats + bytes memory lowercaseName = _buildDnsName(testAddr, "test", "eth"); + bytes memory checksummedName = _buildDnsNameWithChecksummedAddress(testAddr, "test", "eth"); + + bytes memory textData = abi.encodeWithSelector(ITextResolver.text.selector, bytes32(0), "url"); + + // Both should return the same text record + bytes memory result1 = resolver.resolve(lowercaseName, textData); + bytes memory result2 = resolver.resolve(checksummedName, textData); + + assertEq(abi.decode(result1, (string)), "https://vitalik.example.com"); + assertEq(abi.decode(result2, (string)), "https://vitalik.example.com"); + + // Both should also return the same address + bytes memory addrData = abi.encodeWithSelector(IAddrResolver.addr.selector, bytes32(0)); + + bytes memory addrResult1 = resolver.resolve(lowercaseName, addrData); + bytes memory addrResult2 = resolver.resolve(checksummedName, addrData); + + assertEq(abi.decode(addrResult1, (address)), testAddr); + assertEq(abi.decode(addrResult2, (address)), testAddr); + } + + function test_WildcardResolveUppercaseAddress() public view { + // Test with fully uppercase address (another edge case) + address testAddr = 0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B; + + // Build DNS name with uppercase address + bytes memory uppercaseName = _buildDnsNameWithUppercaseAddress(testAddr, "test", "eth"); + + // Build the addr(bytes32) call data + bytes memory data = abi.encodeWithSelector(IAddrResolver.addr.selector, bytes32(0)); + + // Call resolve - should work with uppercase address + bytes memory result = resolver.resolve(uppercaseName, data); + + // Decode and verify + address resolved = abi.decode(result, (address)); + assertEq(resolved, testAddr); + } + + // Helper to build DNS-encoded name for 0xaddress.parent.tld function _buildDnsName(address addr, string memory parent, string memory tld) private pure returns (bytes memory) { bytes memory hexAddr = _addressToHexBytes(addr); bytes memory parentBytes = bytes(parent); bytes memory tldBytes = bytes(tld); - // Format: \x28<40-char-hex>\x\x\x00 + // Format: \x2a<42-char-hex-with-0x>\x\x\x00 return abi.encodePacked( - uint8(40), hexAddr, uint8(parentBytes.length), parentBytes, uint8(tldBytes.length), tldBytes, uint8(0) + uint8(42), hexAddr, uint8(parentBytes.length), parentBytes, uint8(tldBytes.length), tldBytes, uint8(0) ); } - // Helper to convert address to lowercase hex bytes (40 chars, no 0x) + // Helper to convert address to lowercase hex bytes (42 chars, with 0x prefix) function _addressToHexBytes(address addr) private pure returns (bytes memory) { - bytes memory result = new bytes(40); + bytes memory result = new bytes(42); bytes memory hexChars = "0123456789abcdef"; + result[0] = "0"; + result[1] = "x"; + for (uint256 i = 0; i < 20; i++) { + uint8 b = uint8(uint160(addr) >> (8 * (19 - i))); + result[2 + i * 2] = hexChars[b >> 4]; + result[2 + i * 2 + 1] = hexChars[b & 0x0f]; + } + + return result; + } + + // Helper to build DNS-encoded name with checksummed address + function _buildDnsNameWithChecksummedAddress(address addr, string memory parent, string memory tld) + private + pure + returns (bytes memory) + { + bytes memory hexAddr = _addressToChecksummedHexBytes(addr); + bytes memory parentBytes = bytes(parent); + bytes memory tldBytes = bytes(tld); + + return abi.encodePacked( + uint8(42), hexAddr, uint8(parentBytes.length), parentBytes, uint8(tldBytes.length), tldBytes, uint8(0) + ); + } + + // Helper to build DNS-encoded name with uppercase address + function _buildDnsNameWithUppercaseAddress(address addr, string memory parent, string memory tld) + private + pure + returns (bytes memory) + { + bytes memory hexAddr = _addressToUppercaseHexBytes(addr); + bytes memory parentBytes = bytes(parent); + bytes memory tldBytes = bytes(tld); + + return abi.encodePacked( + uint8(42), hexAddr, uint8(parentBytes.length), parentBytes, uint8(tldBytes.length), tldBytes, uint8(0) + ); + } + + // Helper to convert address to checksummed hex bytes (EIP-55) with 0x prefix + function _addressToChecksummedHexBytes(address addr) private pure returns (bytes memory) { + bytes memory result = new bytes(42); + bytes memory hexCharsLower = "0123456789abcdef"; + + result[0] = "0"; + result[1] = "x"; + + // First, create lowercase hex string (without 0x for hashing) + bytes memory lowercase = new bytes(40); + for (uint256 i = 0; i < 20; i++) { + uint8 b = uint8(uint160(addr) >> (8 * (19 - i))); + lowercase[i * 2] = hexCharsLower[b >> 4]; + lowercase[i * 2 + 1] = hexCharsLower[b & 0x0f]; + } + + // Hash the lowercase address for checksum + bytes32 hash = keccak256(lowercase); + + // Apply checksum (EIP-55) + for (uint256 i = 0; i < 40; i++) { + uint8 hashNibble = uint8(hash[i / 2]); + if (i % 2 == 0) { + hashNibble = hashNibble >> 4; + } else { + hashNibble = hashNibble & 0x0f; + } + + uint8 charCode = uint8(lowercase[i]); + // If it's a letter (a-f) and hash nibble >= 8, uppercase it + if (charCode >= 97 && charCode <= 102 && hashNibble >= 8) { + result[2 + i] = bytes1(charCode - 32); // Convert to uppercase + } else { + result[2 + i] = lowercase[i]; + } + } + + return result; + } + + // Helper to convert address to uppercase hex bytes (42 chars, with 0x prefix) + function _addressToUppercaseHexBytes(address addr) private pure returns (bytes memory) { + bytes memory result = new bytes(42); + bytes memory hexChars = "0123456789ABCDEF"; + + result[0] = "0"; + result[1] = "x"; for (uint256 i = 0; i < 20; i++) { uint8 b = uint8(uint160(addr) >> (8 * (19 - i))); - result[i * 2] = hexChars[b >> 4]; - result[i * 2 + 1] = hexChars[b & 0x0f]; + result[2 + i * 2] = hexChars[b >> 4]; + result[2 + i * 2 + 1] = hexChars[b & 0x0f]; } return result; diff --git a/test/L1ConfigResolver.t.sol b/test/L1ConfigResolver.t.sol new file mode 100644 index 0000000..8bdda5b --- /dev/null +++ b/test/L1ConfigResolver.t.sol @@ -0,0 +1,610 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import {Test, console} from "forge-std/Test.sol"; +import {L1ConfigResolver} from "../src/L1ConfigResolver.sol"; +import {IL1ConfigResolver} from "../src/IL1ConfigResolver.sol"; +import {ConfigResolver} from "../src/ConfigResolver.sol"; +import {ENS} from "@ensdomains/ens-contracts/registry/ENS.sol"; +import {INameWrapper} from "@ensdomains/ens-contracts/wrapper/INameWrapper.sol"; +import {IGatewayVerifier} from "@unruggable/contracts/IGatewayVerifier.sol"; +import { + GatewayRequest, + GatewayOP +} from "@unruggable/contracts/GatewayRequest.sol"; +import {GatewayFetcher} from "@unruggable/contracts/GatewayFetcher.sol"; +import { + GatewayFetchTarget, + OffchainLookup +} from "@unruggable/contracts/GatewayFetchTarget.sol"; + +/// @title MockGatewayVerifier +/// @notice A mock verifier that returns pre-computed values for testing +contract MockGatewayVerifier is IGatewayVerifier { + function getLatestContext() external view returns (bytes memory) { + return abi.encode(block.number); + } + + function gatewayURLs() external pure returns (string[] memory urls) { + urls = new string[](1); + urls[0] = "https://mock.gateway/"; + } + + /// @notice Returns values from the proof (which contains pre-computed values in tests) + function getStorageValues( + bytes memory, + GatewayRequest memory, + bytes memory proof + ) external pure returns (bytes[] memory values, uint8 exitCode) { + (values, exitCode) = abi.decode(proof, (bytes[], uint8)); + } +} + +/// @title L1ConfigResolverTest +/// @notice End-to-end tests for L1ConfigResolver reading from ConfigResolver +contract L1ConfigResolverTest is Test { + using GatewayFetcher for GatewayRequest; + + // Contracts + ConfigResolver public configResolver; + L1ConfigResolver public l1Resolver; + MockGatewayVerifier public mockVerifier; + + // Test data + address public user = address(0x1234567890123456789012345678901234567890); + bytes32 public testNode; + string public constant TEST_TEXT_KEY = "url"; + string public constant TEST_TEXT_VALUE = "https://example.com"; + uint256 public constant COIN_TYPE_ETH = 60; + + // Storage slot constants (must match L1ConfigResolver) + uint256 constant SLOT_RECORD_VERSIONS = 0; + uint256 constant SLOT_VERSIONABLE_ADDRESSES = 2; + uint256 constant SLOT_VERSIONABLE_HASHES = 3; + uint256 constant SLOT_VERSIONABLE_TEXTS = 10; + + function setUp() public { + // Use mainnet addresses for ENS (they're the same on all networks) + address ensRegistry = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e; + address nameWrapper = 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401; + + // Deploy ConfigResolver (L2) with mocked ENS + configResolver = new ConfigResolver( + ENS(ensRegistry), + INameWrapper(nameWrapper) + ); + + // Deploy mock verifier + mockVerifier = new MockGatewayVerifier(); + + // Deploy L1ConfigResolver (using Base chain ID 8453 for testing) + l1Resolver = new L1ConfigResolver( + IGatewayVerifier(address(mockVerifier)), + 8453, + address(configResolver) + ); + + // Set up test node (user's reverse node) + testNode = configResolver.reverseNode(user); + + // Mock ENS to allow user to set records on their reverse node + vm.mockCall( + ensRegistry, + abi.encodeWithSelector(ENS.owner.selector, testNode), + abi.encode(user) + ); + + // Set up test data on ConfigResolver as user + vm.startPrank(user); + configResolver.setText(testNode, TEST_TEXT_KEY, TEST_TEXT_VALUE); + configResolver.setAddr(testNode, user); + configResolver.setContenthash( + testNode, + hex"e3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f" + ); + vm.stopPrank(); + } + + // ============ Helper to call fetchCallback and get result ============ + + function _callFetchCallback( + bytes memory proof, + bytes memory carry + ) internal view returns (bytes memory) { + (bool success, bytes memory result) = address(l1Resolver).staticcall( + abi.encodeWithSelector( + l1Resolver.fetchCallback.selector, + proof, + carry + ) + ); + require(success, "fetchCallback failed"); + return result; + } + + // ============ Storage Slot Verification Tests ============ + + /// @notice Verify that SLOT_RECORD_VERSIONS is correct (slot 0) + function test_StorageSlot_RecordVersions() public view { + bytes32 slot = keccak256(abi.encode(testNode, uint256(0))); + uint256 version = uint256(vm.load(address(configResolver), slot)); + + // After setting records, version should still be 0 (only incremented by clearRecords) + assertEq(version, 0, "recordVersions should be at slot 0"); + } + + /// @notice Verify that SLOT_VERSIONABLE_ADDRESSES is correct (slot 2) + function test_StorageSlot_VersionableAddresses() public view { + // Storage layout: versionable_addresses[version][node][coinType] + // Slot calculation: keccak256(coinType, keccak256(node, keccak256(version, baseSlot))) + uint64 version = 0; + uint256 baseSlot = 2; + + bytes32 slot1 = keccak256(abi.encode(version, baseSlot)); + bytes32 slot2 = keccak256(abi.encode(testNode, slot1)); + bytes32 slot3 = keccak256(abi.encode(COIN_TYPE_ETH, slot2)); + + // Read the stored value - for short bytes (<32), Solidity stores data|length in same slot + bytes32 storedValue = vm.load(address(configResolver), slot3); + + // For 20-byte address, Solidity stores: [20 bytes of data][11 zero bytes][1 byte = 2*20 = 40] + // Extract the length from the lowest byte + uint8 encodedLength = uint8(uint256(storedValue) & 0xff); + // For short bytes, length is stored as 2*len, so actual length = encodedLength/2 + assertEq( + encodedLength, + 40, + "Address bytes length encoding should be 2*20=40" + ); + + // Extract the address from high bytes + address storedAddr = address(uint160(uint256(storedValue) >> 96)); + assertEq(storedAddr, user, "Stored address should match user"); + } + + /// @notice Verify that SLOT_VERSIONABLE_TEXTS is correct (slot 10) + function test_StorageSlot_VersionableTexts() public view { + // Storage layout: versionable_texts[version][node][key] + // For string keys in mappings, Solidity uses: keccak256(abi.encodePacked(key, slot)) + uint64 version = 0; + uint256 baseSlot = 10; + + bytes32 slot1 = keccak256(abi.encode(version, baseSlot)); + bytes32 slot2 = keccak256(abi.encode(testNode, slot1)); + // For string keys, use encodePacked(key, slot) + bytes32 slot3 = keccak256(abi.encodePacked(TEST_TEXT_KEY, slot2)); + + // Read the stored value + bytes32 storedValue = vm.load(address(configResolver), slot3); + + // For short strings (<32 bytes), Solidity stores: [string data][padding][2*length] + // "https://example.com" is 19 bytes, so encoding = 2*19 = 38 + uint8 encodedLength = uint8(uint256(storedValue) & 0xff); + assertEq( + encodedLength, + 38, + "Text record length encoding should be 2*19=38" + ); + } + + /// @notice Verify that SLOT_VERSIONABLE_HASHES is correct (slot 3) + function test_StorageSlot_VersionableHashes() public view { + // Storage layout: versionable_hashes[version][node] + uint64 version = 0; + uint256 baseSlot = 3; + + bytes32 slot1 = keccak256(abi.encode(version, baseSlot)); + bytes32 slot2 = keccak256(abi.encode(testNode, slot1)); + + // Read the stored contenthash length + uint256 storedLength = uint256(vm.load(address(configResolver), slot2)); + // Our test contenthash is 38 bytes, stored as 2*38+1 = 77 + assertEq( + storedLength, + 77, + "Contenthash length encoding should be correct" + ); + } + + // ============ Direct Read Tests (verify ConfigResolver data is set correctly) ============ + + function test_ConfigResolver_DirectRead_Text() public view { + string memory value = configResolver.text(testNode, TEST_TEXT_KEY); + assertEq(value, TEST_TEXT_VALUE, "Text record should be set correctly"); + } + + function test_ConfigResolver_DirectRead_Addr() public view { + address addr = configResolver.addr(testNode); + assertEq(addr, user, "Address record should be set correctly"); + } + + function test_ConfigResolver_DirectRead_Contenthash() public view { + bytes memory hash = configResolver.contenthash(testNode); + assertEq( + hash, + hex"e3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f", + "Contenthash should be set correctly" + ); + } + + // ============ CCIP-Read Flow Tests ============ + + /// @notice Test the full CCIP-Read flow for text() resolution + function test_CCIPRead_Text() public view { + // Simulate gateway response by reading directly from ConfigResolver + string memory expectedValue = configResolver.text( + testNode, + TEST_TEXT_KEY + ); + + // Prepare mock response + bytes[] memory values = new bytes[](1); + values[0] = bytes(expectedValue); + bytes memory proof = abi.encode(values, uint8(0)); + + // Build the carry data (Session struct) + GatewayRequest memory req = _buildTextRequest(testNode, TEST_TEXT_KEY); + bytes memory carry = abi.encode( + GatewayFetchTarget.Session({ + verifier: IGatewayVerifier(address(mockVerifier)), + context: mockVerifier.getLatestContext(), + req: req, + callback: L1ConfigResolver.textCallback.selector, + carry: "" + }) + ); + + // Call fetchCallback + bytes memory resultBytes = _callFetchCallback(proof, carry); + string memory result = abi.decode(resultBytes, (string)); + + assertEq( + result, + TEST_TEXT_VALUE, + "CCIP-Read text() should return correct value" + ); + } + + /// @notice Test the full CCIP-Read flow for addr() resolution + function test_CCIPRead_Addr() public view { + // Simulate gateway response + bytes memory expectedValue = abi.encodePacked(user); + + bytes[] memory values = new bytes[](1); + values[0] = expectedValue; + bytes memory proof = abi.encode(values, uint8(0)); + + // Build carry data + GatewayRequest memory req = _buildAddrRequest(testNode, COIN_TYPE_ETH); + bytes memory carry = abi.encode( + GatewayFetchTarget.Session({ + verifier: IGatewayVerifier(address(mockVerifier)), + context: mockVerifier.getLatestContext(), + req: req, + callback: L1ConfigResolver.addrCallback.selector, + carry: abi.encode(testNode) + }) + ); + + // Call fetchCallback + bytes memory resultBytes = _callFetchCallback(proof, carry); + address result = abi.decode(resultBytes, (address)); + + assertEq( + result, + user, + "CCIP-Read addr() should return correct address" + ); + } + + /// @notice Test the full CCIP-Read flow for contenthash() resolution + function test_CCIPRead_Contenthash() public view { + // Simulate gateway response + bytes + memory expectedValue = hex"e3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f"; + + bytes[] memory values = new bytes[](1); + values[0] = expectedValue; + bytes memory proof = abi.encode(values, uint8(0)); + + // Build carry data + GatewayRequest memory req = _buildContenthashRequest(testNode); + bytes memory carry = abi.encode( + GatewayFetchTarget.Session({ + verifier: IGatewayVerifier(address(mockVerifier)), + context: mockVerifier.getLatestContext(), + req: req, + callback: L1ConfigResolver.contenthashCallback.selector, + carry: "" + }) + ); + + // Call fetchCallback + bytes memory resultBytes = _callFetchCallback(proof, carry); + bytes memory result = abi.decode(resultBytes, (bytes)); + + assertEq( + result, + expectedValue, + "CCIP-Read contenthash() should return correct value" + ); + } + + /// @notice Test resolve() with text selector + function test_CCIPRead_Resolve_Text() public view { + // Build the resolve calldata + bytes memory innerCalldata = abi.encodeWithSelector( + bytes4(0x59d1d43c), + testNode, + TEST_TEXT_KEY + ); + + // Simulate gateway response + string memory expectedValue = configResolver.text( + testNode, + TEST_TEXT_KEY + ); + bytes[] memory values = new bytes[](1); + values[0] = bytes(expectedValue); + bytes memory proof = abi.encode(values, uint8(0)); + + // Build carry data + GatewayRequest memory req = _buildTextRequest(testNode, TEST_TEXT_KEY); + bytes memory carry = abi.encode( + GatewayFetchTarget.Session({ + verifier: IGatewayVerifier(address(mockVerifier)), + context: mockVerifier.getLatestContext(), + req: req, + callback: L1ConfigResolver.resolveCallback.selector, + carry: innerCalldata + }) + ); + + // Call fetchCallback + bytes memory resultBytes = _callFetchCallback(proof, carry); + string memory decodedResult = abi.decode( + abi.decode(resultBytes, (bytes)), + (string) + ); + + assertEq( + decodedResult, + TEST_TEXT_VALUE, + "resolve() with text selector should return correct value" + ); + } + + /// @notice Test resolve() with addr selector + function test_CCIPRead_Resolve_Addr() public view { + // Build the resolve calldata for addr(bytes32) + bytes memory innerCalldata = abi.encodeWithSelector( + bytes4(0x3b3b57de), + testNode + ); + + // Simulate gateway response + bytes[] memory values = new bytes[](1); + values[0] = abi.encodePacked(user); + bytes memory proof = abi.encode(values, uint8(0)); + + // Build carry data + GatewayRequest memory req = _buildAddrRequest(testNode, COIN_TYPE_ETH); + bytes memory carry = abi.encode( + GatewayFetchTarget.Session({ + verifier: IGatewayVerifier(address(mockVerifier)), + context: mockVerifier.getLatestContext(), + req: req, + callback: L1ConfigResolver.resolveCallback.selector, + carry: innerCalldata + }) + ); + + // Call fetchCallback + bytes memory resultBytes = _callFetchCallback(proof, carry); + address decodedResult = abi.decode( + abi.decode(resultBytes, (bytes)), + (address) + ); + + assertEq( + decodedResult, + user, + "resolve() with addr selector should return correct address" + ); + } + + // ============ Empty/Missing Record Tests ============ + + function test_CCIPRead_EmptyText() public view { + bytes32 emptyNode = keccak256("nonexistent"); + + bytes[] memory values = new bytes[](1); + values[0] = ""; + bytes memory proof = abi.encode(values, uint8(0)); + + GatewayRequest memory req = _buildTextRequest(emptyNode, "nonexistent"); + bytes memory carry = abi.encode( + GatewayFetchTarget.Session({ + verifier: IGatewayVerifier(address(mockVerifier)), + context: mockVerifier.getLatestContext(), + req: req, + callback: L1ConfigResolver.textCallback.selector, + carry: "" + }) + ); + + bytes memory resultBytes = _callFetchCallback(proof, carry); + string memory result = abi.decode(resultBytes, (string)); + assertEq(result, "", "Empty text record should return empty string"); + } + + function test_CCIPRead_EmptyAddr() public view { + bytes[] memory values = new bytes[](1); + values[0] = ""; + bytes memory proof = abi.encode(values, uint8(0)); + + GatewayRequest memory req = _buildAddrRequest(testNode, COIN_TYPE_ETH); + bytes memory carry = abi.encode( + GatewayFetchTarget.Session({ + verifier: IGatewayVerifier(address(mockVerifier)), + context: mockVerifier.getLatestContext(), + req: req, + callback: L1ConfigResolver.addrCallback.selector, + carry: "" + }) + ); + + bytes memory resultBytes = _callFetchCallback(proof, carry); + address result = abi.decode(resultBytes, (address)); + assertEq( + result, + address(0), + "Empty address record should return zero address" + ); + } + + /// @notice Test exit code handling + function test_CCIPRead_ExitCode_NonZero() public view { + bytes[] memory values = new bytes[](1); + values[0] = ""; + // Non-zero exit code indicates error/not found + bytes memory proof = abi.encode(values, uint8(1)); + + GatewayRequest memory req = _buildTextRequest(testNode, TEST_TEXT_KEY); + bytes memory carry = abi.encode( + GatewayFetchTarget.Session({ + verifier: IGatewayVerifier(address(mockVerifier)), + context: mockVerifier.getLatestContext(), + req: req, + callback: L1ConfigResolver.textCallback.selector, + carry: "" + }) + ); + + bytes memory resultBytes = _callFetchCallback(proof, carry); + string memory result = abi.decode(resultBytes, (string)); + assertEq( + result, + "", + "Non-zero exit code should return empty string for text" + ); + } + + // ============ Interface Support Tests ============ + + function test_SupportsInterface_ERC165() public view { + assertTrue( + l1Resolver.supportsInterface(0x01ffc9a7), + "Should support ERC-165" + ); + } + + function test_SupportsInterface_ExtendedResolver() public view { + assertTrue( + l1Resolver.supportsInterface(0x9061b923), + "Should support IExtendedResolver" + ); + } + + function test_SupportsInterface_Addr() public view { + assertTrue( + l1Resolver.supportsInterface(0x3b3b57de), + "Should support addr(bytes32)" + ); + } + + function test_SupportsInterface_AddrMulti() public view { + assertTrue( + l1Resolver.supportsInterface(0xf1cb7e06), + "Should support addr(bytes32,uint256)" + ); + } + + function test_SupportsInterface_Text() public view { + assertTrue( + l1Resolver.supportsInterface(0x59d1d43c), + "Should support text(bytes32,string)" + ); + } + + function test_SupportsInterface_Contenthash() public view { + assertTrue( + l1Resolver.supportsInterface(0xbc1c58d1), + "Should support contenthash(bytes32)" + ); + } + + // ============ Immutable Getters Tests ============ + + function test_Verifier() public view { + assertEq( + address(l1Resolver.verifier()), + address(mockVerifier), + "Verifier should be set correctly" + ); + } + + function test_L2ConfigResolver() public view { + assertEq( + l1Resolver.l2ConfigResolver(), + address(configResolver), + "L2 ConfigResolver should be set correctly" + ); + } + + function test_L2ChainId() public view { + assertEq( + l1Resolver.l2ChainId(), + 8453, + "L2 Chain ID should be set correctly" + ); + } + + function test_SupportsInterface_IL1ConfigResolver() public view { + // IL1ConfigResolver interface ID + bytes4 interfaceId = type(IL1ConfigResolver).interfaceId; + assertTrue( + l1Resolver.supportsInterface(interfaceId), + "Should support IL1ConfigResolver" + ); + } + + // ============ Helper Functions ============ + + function _buildTextRequest( + bytes32 node, + string memory key + ) internal view returns (GatewayRequest memory req) { + req = GatewayFetcher.newRequest(1).setTarget(address(configResolver)); + req = req.setSlot(SLOT_RECORD_VERSIONS).push(node).follow().read(); + req = req.setSlot(SLOT_VERSIONABLE_TEXTS); + req = req.follow(); + req = req.push(node).follow(); + req = req.push(key).follow(); + req = req.readBytes().setOutput(0); + } + + function _buildAddrRequest( + bytes32 node, + uint256 coinType + ) internal view returns (GatewayRequest memory req) { + req = GatewayFetcher.newRequest(1).setTarget(address(configResolver)); + req = req.setSlot(SLOT_RECORD_VERSIONS).push(node).follow().read(); + req = req.setSlot(SLOT_VERSIONABLE_ADDRESSES); + req = req.follow(); + req = req.push(node).follow(); + req = req.push(coinType).follow(); + req = req.readBytes().setOutput(0); + } + + function _buildContenthashRequest( + bytes32 node + ) internal view returns (GatewayRequest memory req) { + req = GatewayFetcher.newRequest(1).setTarget(address(configResolver)); + req = req.setSlot(SLOT_RECORD_VERSIONS).push(node).follow().read(); + req = req.setSlot(SLOT_VERSIONABLE_HASHES); + req = req.follow(); + req = req.push(node).follow(); + req = req.readBytes().setOutput(0); + } +}