Skip to content

Commit

Permalink
Merge branch 'staging' into fix/refactor-wrapped-callback
Browse files Browse the repository at this point in the history
  • Loading branch information
mdtanrikulu committed Oct 28, 2024
2 parents 18b7816 + 5421b56 commit 556d92b
Show file tree
Hide file tree
Showing 9 changed files with 426 additions and 23 deletions.
Binary file modified bun.lockb
Binary file not shown.
10 changes: 5 additions & 5 deletions contracts/resolvers/profiles/ExtendedDNSResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ contract ExtendedDNSResolver is IExtendedDNSResolver, IERC165 {
if (value.length == 0) {
return value;
}
(bytes memory record, bool valid) = value.hexToBytes(2, value.length);
(address record, bool valid) = value.hexToAddress(2, value.length);
if (!valid) revert InvalidAddressFormat(value);
return record;
return abi.encode(record);
}

function _resolveAddr(
Expand All @@ -133,9 +133,9 @@ contract ExtendedDNSResolver is IExtendedDNSResolver, IERC165 {
if (value.length == 0) {
return value;
}
(bytes memory record, bool valid) = value.hexToBytes(2, value.length);
(address record, bool valid) = value.hexToAddress(2, value.length);
if (!valid) revert InvalidAddressFormat(value);
return record;
return abi.encode(record);
}

function _resolveText(
Expand All @@ -147,7 +147,7 @@ contract ExtendedDNSResolver is IExtendedDNSResolver, IERC165 {
context,
bytes.concat("t[", bytes(key), "]=")
);
return value;
return abi.encode(value);
}

uint256 constant STATE_START = 0;
Expand Down
68 changes: 68 additions & 0 deletions contracts/utils/MigrationHelper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;

import {IBaseRegistrar} from "../ethregistrar/IBaseRegistrar.sol";
import {INameWrapper} from "../wrapper/INameWrapper.sol";
import {Controllable} from "../wrapper/Controllable.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

contract MigrationHelper is Ownable, Controllable {
IBaseRegistrar public immutable registrar;
INameWrapper public immutable wrapper;
address public migrationTarget;

error MigrationTargetNotSet();

event MigrationTargetUpdated(address indexed target);

constructor(IBaseRegistrar _registrar, INameWrapper _wrapper) {
registrar = _registrar;
wrapper = _wrapper;
}

function setMigrationTarget(address target) external onlyOwner {
migrationTarget = target;
emit MigrationTargetUpdated(target);
}

function migrateNames(
address nameOwner,
uint256[] memory tokenIds,
bytes memory data
) external onlyController {
if (migrationTarget == address(0)) {
revert MigrationTargetNotSet();
}

for (uint256 i = 0; i < tokenIds.length; i++) {
registrar.safeTransferFrom(
nameOwner,
migrationTarget,
tokenIds[i],
data
);
}
}

function migrateWrappedNames(
address nameOwner,
uint256[] memory tokenIds,
bytes memory data
) external onlyController {
if (migrationTarget == address(0)) {
revert MigrationTargetNotSet();
}

uint256[] memory amounts = new uint256[](tokenIds.length);
for (uint256 i = 0; i < amounts.length; i++) {
amounts[i] = 1;
}
wrapper.safeBatchTransferFrom(
nameOwner,
migrationTarget,
tokenIds,
amounts,
data
);
}
}
26 changes: 26 additions & 0 deletions deploy/utils/10_deploy_migration_helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { DeployFunction } from 'hardhat-deploy/types.js'

const func: DeployFunction = async function (hre) {
const { deployments, viem } = hre
const { deploy } = deployments

const { deployer, owner } = await viem.getNamedClients()

const registrar = await viem.getContract('BaseRegistrarImplementation')
const wrapper = await viem.getContract('NameWrapper')

await viem.deploy('MigrationHelper', [registrar.address, wrapper.address])

if (owner !== undefined && owner.address !== deployer.address) {
const migrationHelper = await viem.getContract('MigrationHelper')
const hash = await migrationHelper.write.transferOwnership([owner.address])
console.log(`Transfer ownership to ${owner.address} (tx: ${hash})...`)
await viem.waitForTransactionSuccess(hash)
}
}

func.id = 'migration-helper'
func.tags = ['utils', 'MigrationHelper']
func.dependencies = ['BaseRegistrarImplementation', 'NameWrapper']

export default func
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ensdomains/ens-contracts",
"version": "1.0.1",
"version": "1.2.2",
"description": "ENS contracts",
"type": "module",
"scripts": {
Expand All @@ -16,7 +16,7 @@
"pub": "npm publish --access public",
"prepare": "husky install",
"wikiCheck": "bun ./scripts/wikiCheck.ts",
"postinstall": "bunx patch-package"
"postinstall": "npx patch-package"
},
"files": [
"build",
Expand Down
1 change: 1 addition & 0 deletions scripts/deploy-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ execSync('bun run hardhat --network localhost deploy', {
env: {
...process.env,
NODE_OPTIONS: '--experimental-loader ts-node/esm/transpile-only',
BATCH_GATEWAY_URLS: '["https://example.com/"]',
},
})

Expand Down
9 changes: 7 additions & 2 deletions test/dnsregistrar/TestOffchainDNSResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { loadFixture } from '@nomicfoundation/hardhat-toolbox-viem/network-helpe
import { expect } from 'chai'
import hre from 'hardhat'
import {
Address,
encodeAbiParameters,
encodeFunctionData,
getAddress,
Expand Down Expand Up @@ -404,7 +405,9 @@ describe('OffchainDNSResolver', () => {
texts: [`ENS1 ${resolver.address} a[60]=${testAddress}`],
calldata,
}),
).resolves.toEqual(testAddress.toLowerCase() as Hex)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('correctly handles extra data in the TXT record when calling a resolver that supports address resolution with valid cointype', async () => {
Expand All @@ -428,7 +431,9 @@ describe('OffchainDNSResolver', () => {
texts: [`ENS1 ${resolver.address} a[${ethCoinType}]=${testAddress}`],
calldata,
}),
).resolves.toEqual(testAddress.toLowerCase() as Hex)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('handles extra data in the TXT record when calling a resolver that supports address resolution with invalid cointype', async () => {
Expand Down
53 changes: 39 additions & 14 deletions test/resolvers/TestExtendedDNSResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Abi,
Address,
bytesToHex,
encodeAbiParameters,
encodeFunctionData,
namehash,
stringToHex,
Expand Down Expand Up @@ -89,7 +90,9 @@ describe('ExtendedDNSResolver', () => {
args: [],
context: `a[60]=${testAddress}`,
}),
).resolves.toEqual(testAddress.toLowerCase() as Address)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('resolves Ethereum addresses using addr(bytes32,uint256)', async () => {
Expand All @@ -106,7 +109,9 @@ describe('ExtendedDNSResolver', () => {
args: [coinType],
context: `a[60]=${testAddress}`,
}),
).resolves.toEqual(testAddress.toLowerCase() as Address)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('ignores records with the wrong cointype', async () => {
Expand Down Expand Up @@ -157,7 +162,9 @@ describe('ExtendedDNSResolver', () => {
args: [],
context: `foo=bar a[60]=${testAddress}`,
}),
).resolves.toEqual(testAddress.toLowerCase() as Address)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('handles multiple spaces between records', async () => {
Expand All @@ -173,7 +180,9 @@ describe('ExtendedDNSResolver', () => {
args: [],
context: `foo=bar a[60]=${testAddress}`,
}),
).resolves.toEqual(testAddress.toLowerCase() as Address)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('handles multiple spaces between quoted records', async () => {
Expand All @@ -189,7 +198,9 @@ describe('ExtendedDNSResolver', () => {
args: [],
context: `foo='bar' a[60]=${testAddress}`,
}),
).resolves.toEqual(testAddress.toLowerCase() as Address)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('handles no spaces between quoted records', async () => {
Expand All @@ -205,7 +216,9 @@ describe('ExtendedDNSResolver', () => {
args: [],
context: `foo='bar'a[60]=${testAddress}`,
}),
).resolves.toEqual(testAddress.toLowerCase() as Address)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('works if the record comes after one for another cointype', async () => {
Expand All @@ -221,7 +234,9 @@ describe('ExtendedDNSResolver', () => {
args: [],
context: `a[0]=0x1234 a[60]=${testAddress}`,
}),
).resolves.toEqual(testAddress.toLowerCase() as Address)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('uses the first matching record it finds', async () => {
Expand All @@ -237,7 +252,9 @@ describe('ExtendedDNSResolver', () => {
args: [],
context: `a[60]=${testAddress} a[60]=0x1234567890123456789012345678901234567890`,
}),
).resolves.toEqual(testAddress.toLowerCase() as Address)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})

it('resolves addresses with coin types', async () => {
Expand All @@ -255,7 +272,9 @@ describe('ExtendedDNSResolver', () => {
args: [optimismCoinType],
context: `a[e${optimismChainId}]=${testAddress}`,
}),
).resolves.toEqual(testAddress.toLowerCase() as Address)
).resolves.toEqual(
encodeAbiParameters([{ type: 'address' }], [testAddress as Address]),
)
})
})

Expand All @@ -272,7 +291,9 @@ describe('ExtendedDNSResolver', () => {
args: ['com.twitter'],
context: 't[com.twitter]=nicksdjohnson',
}),
).resolves.toEqual(stringToHex('nicksdjohnson'))
).resolves.toEqual(
encodeAbiParameters([{ type: 'string' }], ['nicksdjohnson']),
)
})

it('returns 0x for a missing key', async () => {
Expand All @@ -287,7 +308,7 @@ describe('ExtendedDNSResolver', () => {
args: ['com.discord'],
context: 't[com.twitter]=nicksdjohnson',
}),
).resolves.toEqual('0x')
).resolves.toEqual(encodeAbiParameters([{ type: 'string' }], ['']))
})

it('decodes a quoted t record', async () => {
Expand All @@ -302,7 +323,9 @@ describe('ExtendedDNSResolver', () => {
args: ['url'],
context: "t[url]='https://ens.domains/'",
}),
).resolves.toEqual(stringToHex('https://ens.domains/'))
).resolves.toEqual(
encodeAbiParameters([{ type: 'string' }], ['https://ens.domains/']),
)
})

it('handles escaped quotes', async () => {
Expand All @@ -317,7 +340,9 @@ describe('ExtendedDNSResolver', () => {
args: ['note'],
context: "t[note]='I\\'m great'",
}),
).resolves.toEqual(stringToHex("I'm great"))
).resolves.toEqual(
encodeAbiParameters([{ type: 'string' }], ["I'm great"]),
)
})

it('rejects a record with an unterminated quoted string', async () => {
Expand All @@ -332,7 +357,7 @@ describe('ExtendedDNSResolver', () => {
args: ['note'],
context: "t[note]='I\\'m great",
}),
).resolves.toEqual('0x')
).resolves.toEqual(encodeAbiParameters([{ type: 'string' }], ['']))
})
})
})
Loading

0 comments on commit 556d92b

Please sign in to comment.