Skip to content

Commit

Permalink
Merge pull request #132 from ensdomains/fix-zero-address-for-eth
Browse files Browse the repository at this point in the history
Fix: Empty address for ETH fails
  • Loading branch information
LeonmanRolls authored Apr 17, 2023
2 parents 24b800e + 747261c commit c71ee42
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 2 deletions.
17 changes: 17 additions & 0 deletions packages/ensjs/src/functions/setRecord.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { formatsByName } from '@ensdomains/address-encoder'
import { decodeFirst } from 'cbor'
import { BigNumber } from 'ethers'
import { arrayify, toUtf8String } from 'ethers/lib/utils'
Expand Down Expand Up @@ -145,6 +146,22 @@ describe('setRecord', () => {
// record as hex
expect(resultEmptyAddr).toBe('0x')
})

Object.keys(formatsByName).forEach((coinName) => {
it(`should allow an empty address record for ${coinName}`, async () => {
const tx = await ensInstance.setRecord('test123.eth', {
type: 'addr',
record: {
key: coinName,
value: '',
},
addressOrIndex: 1,
})
expect(tx).toBeTruthy()
await tx.wait()
})
})

it('should allow a contenthash record set', async () => {
const tx = await ensInstance.setRecord('test123.eth', {
type: 'contentHash',
Expand Down
116 changes: 116 additions & 0 deletions packages/ensjs/src/functions/setRecords.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,120 @@ describe('setRecords', () => {
expect(contentType.toNumber()).toBe(1)
expect(toUtf8String(resultABI)).toBe(JSON.stringify(dummyABI))
})

describe('record types', () => {
it('should be able to set and delete a cointype for a wrapped name', async () => {
const tx = await ensInstance.setRecords('wrapped.eth', {
records: {
coinTypes: [
{
key: 'ETH',
value: '0x42D63ae25990889E35F215bC95884039Ba354115',
},
],
},
addressOrIndex: 1,
})
expect(tx).toBeTruthy()
await tx.wait()

const universalResolver =
await ensInstance.contracts!.getUniversalResolver()!
const publicResolver = await ensInstance.contracts!.getPublicResolver()!

const encodedAddr = await universalResolver['resolve(bytes,bytes)'](
hexEncodeName('wrapped.eth'),
publicResolver.interface.encodeFunctionData('addr(bytes32,uint256)', [
namehash('wrapped.eth'),
'60',
]),
)
const [resultAddr] = publicResolver.interface.decodeFunctionResult(
'addr(bytes32,uint256)',
encodedAddr[0],
)
expect(resultAddr).toBe(
'0x42D63ae25990889E35F215bC95884039Ba354115'.toLowerCase(),
)

const tx2 = await ensInstance.setRecords('wrapped.eth', {
records: {
coinTypes: [
{
key: 'ETH',
value: '',
},
],
},
addressOrIndex: 1,
})
expect(tx2).toBeTruthy()
await tx2.wait()

const encodedAddr2 = await universalResolver['resolve(bytes,bytes)'](
hexEncodeName('wrapped.eth'),
publicResolver.interface.encodeFunctionData('addr(bytes32,uint256)', [
namehash('wrapped.eth'),
'60',
]),
)
const [resultAddr2] = publicResolver.interface.decodeFunctionResult(
'addr(bytes32,uint256)',
encodedAddr2[0],
)
expect(resultAddr2).toBe(
'0x0000000000000000000000000000000000000000'.toLowerCase(),
)
})

it('should be able to set and delete a contenthash for a wrapped name', async () => {
const tx = await ensInstance.setRecords('wrapped.eth', {
records: {
contentHash: 'ipfs://QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4',
},
addressOrIndex: 1,
})
expect(tx).toBeTruthy()
await tx.wait()

const universalResolver =
await ensInstance.contracts!.getUniversalResolver()!
const publicResolver = await ensInstance.contracts!.getPublicResolver()!

const encodedData = await universalResolver['resolve(bytes,bytes)'](
hexEncodeName('wrapped.eth'),
publicResolver.interface.encodeFunctionData('contenthash', [
namehash('wrapped.eth'),
]),
)
const [resultData] = publicResolver.interface.decodeFunctionResult(
'contenthash',
encodedData[0],
)
expect(resultData).toBe(
'0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f'.toLowerCase(),
)

const tx2 = await ensInstance.setRecords('wrapped.eth', {
records: {
contentHash: '',
},
addressOrIndex: 1,
})
expect(tx2).toBeTruthy()
await tx2.wait()

const encodedAddr2 = await universalResolver['resolve(bytes,bytes)'](
hexEncodeName('wrapped.eth'),
publicResolver.interface.encodeFunctionData('contenthash', [
namehash('wrapped.eth'),
]),
)
const [resultAddr2] = publicResolver.interface.decodeFunctionResult(
'contenthash',
encodedAddr2[0],
)
expect(resultAddr2).toBe('0x'.toLowerCase())
})
})
})
8 changes: 6 additions & 2 deletions packages/ensjs/src/utils/recordHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ export const generateSetAddr = (
coinTypeInstance = formatsByName[coinType.toUpperCase()]
}
const inputCoinType = coinTypeInstance.coinType
const encodedAddress =
address !== '' ? coinTypeInstance.decoder(address) : '0x'
let encodedAddress = address !== '' ? coinTypeInstance.decoder(address) : '0x'
if (inputCoinType === 60 && encodedAddress === '0x')
encodedAddress = coinTypeInstance.decoder(
'0x0000000000000000000000000000000000000000',
)

return resolver?.interface.encodeFunctionData(
'setAddr(bytes32,uint256,bytes)',
[namehash, inputCoinType, encodedAddress],
Expand Down

0 comments on commit c71ee42

Please sign in to comment.