diff --git a/script/20231025-upgrade-controller/20231025_UpgradeController.s.sol b/script/20231025-upgrade-controller/20231025_UpgradeController.s.sol new file mode 100644 index 00000000..e04f5ef5 --- /dev/null +++ b/script/20231025-upgrade-controller/20231025_UpgradeController.s.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import { ContractKey } from "foundry-deployment-kit/configs/ContractConfig.sol"; +import { RNSDeploy } from "script/RNSDeploy.s.sol"; + +contract Migration__20231025_UpgradeController is RNSDeploy { + function run() public trySetUp { + _upgradeProxy(ContractKey.RONRegistrarController, EMPTY_ARGS); + } +} diff --git a/src/RONRegistrarController.sol b/src/RONRegistrarController.sol index 00816ab5..8f982469 100644 --- a/src/RONRegistrarController.sol +++ b/src/RONRegistrarController.sol @@ -65,6 +65,11 @@ contract RONRegistrarController is /// @dev Mapping id => owner => flag indicating whether the owner is whitelisted to buy protected name mapping(uint256 id => mapping(address owner => bool)) internal _protectedNamesWhitelisted; + modifier onlyAvailable(string memory name) { + _requireAvailable(name); + _; + } + constructor() payable { _disableInitializers(); } @@ -150,7 +155,7 @@ contract RONRegistrarController is address resolver, bytes[] calldata data, bool reverseRecord - ) public pure returns (bytes32) { + ) public view onlyAvailable(name) returns (bytes32) { if (data.length != 0 && resolver == address(0)) revert ResolverRequiredWhenDataSupplied(); return keccak256(abi.encode(computeId(name), owner, duration, secret, resolver, data, reverseRecord)); } @@ -201,7 +206,7 @@ contract RONRegistrarController is data: data, reverseRecord: reverseRecord }); - _validateCommitment(name, duration, commitHash); + _validateCommitment(duration, commitHash); (uint256 usdPrice, uint256 ronPrice) = _handlePrice(name, duration); _register(name, owner, duration, resolver, data, reverseRecord, usdPrice, ronPrice); @@ -233,7 +238,8 @@ contract RONRegistrarController is address resolver, bytes[] calldata data, bool reverseRecord - ) external payable whenNotPaused nonReentrant { + ) external payable whenNotPaused nonReentrant onlyAvailable(name) { + if (!available(name)) revert NameNotAvailable(name); uint256 id = computeId(name); bool protected = _rnsUnified.getRecord(id).mut.protected; bool whitelisted = _protectedNamesWhitelisted[id][owner]; @@ -358,12 +364,10 @@ contract RONRegistrarController is * * Requirements: * - The duration must larger than or equal to minimum registration duration. - * - The name must be available. * - The passed duration must in a valid range. */ - function _validateCommitment(string memory name, uint64 duration, bytes32 commitment) internal { + function _validateCommitment(uint64 duration, bytes32 commitment) internal { if (duration < _minRegistrationDuration) revert DurationTooShort(duration); - if (!available(name)) revert NameNotAvailable(name); uint256 passedDuration = block.timestamp - _committedAt[commitment]; if (passedDuration < _minCommitmentAge) revert CommitmentTooNew(commitment); @@ -447,4 +451,11 @@ contract RONRegistrarController is _priceOracle = priceOracle; emit DomainPriceUpdated(_msgSender(), priceOracle); } + + /** + * @dev Helper method to check if a domain name is available for register. + */ + function _requireAvailable(string memory name) internal view { + if (!available(name)) revert NameNotAvailable(name); + } } diff --git a/src/interfaces/IRONRegistrarController.sol b/src/interfaces/IRONRegistrarController.sol index 74799ba4..22914bda 100644 --- a/src/interfaces/IRONRegistrarController.sol +++ b/src/interfaces/IRONRegistrarController.sol @@ -136,7 +136,7 @@ interface IRONRegistrarController { address resolver, bytes[] calldata data, bool reverseRecord - ) external pure returns (bytes32); + ) external view returns (bytes32); /** * @dev Commits to a registration using the commitment hash.