From e8b14b097db7626c3c70dcad43899995a2d9cd9d Mon Sep 17 00:00:00 2001 From: Volodymyr Lykhonis Date: Mon, 13 Nov 2023 06:42:45 -0500 Subject: [PATCH] Add page name verification on chain --- src/page/PageName.sol | 11 +++++++++-- test/page/PageName.t.sol | 30 +++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/page/PageName.sol b/src/page/PageName.sol index 5c3dbac..e8ebdd4 100644 --- a/src/page/PageName.sol +++ b/src/page/PageName.sol @@ -142,11 +142,18 @@ contract PageName is LSP8EnumerableInitAbstract, ReentrancyGuardUpgradeable, Pau emit ReleasedName(tokenOwner, tokenId); } - function _isValidName(string memory name) private view returns (bool) { - uint256 length = bytes(name).length; + function _isValidName(string memory name) public view returns (bool) { + bytes memory chars = bytes(name); + uint256 length = chars.length; if (length < minimumLength || length > 32) { return false; } + for (uint256 i = 0; i < length; i++) { + bytes1 char = chars[i]; + if (!(char >= 0x61 && char <= 0x7a) && !(char >= 0x30 && char <= 0x39) && char != 0x2d && char != 0x5f) { + return false; + } + } return true; } diff --git a/test/page/PageName.t.sol b/test/page/PageName.t.sol index 0577a07..fd5d82b 100644 --- a/test/page/PageName.t.sol +++ b/test/page/PageName.t.sol @@ -146,13 +146,18 @@ contract PageNameTest is Test { assertEq(withdraw, beneficiary.balance); } - function testFuzz_Reserve(uint8 minimumLength, string calldata reservationName) public { - vm.assume(bytes(reservationName).length >= minimumLength); - vm.assume(bytes(reservationName).length <= 32); + function testFuzz_Reserve(uint8 minimumLength) public { + vm.assume(minimumLength <= 32); vm.prank(owner); name.setMinimumLength(minimumLength); + bytes memory buffer = new bytes(minimumLength); + for (uint256 i = 0; i < minimumLength; i++) { + buffer[i] = bytes1(uint8(0x61 + uint256(blockhash(block.number + i)) % (0x7a - 0x61))); + } + string memory reservationName = string(buffer); + (UniversalProfile profile,) = deployProfile(); bytes32 hash = keccak256( abi.encodePacked(address(name), block.chainid, address(profile), reservationName, uint256(0 ether)) @@ -212,6 +217,25 @@ contract PageNameTest is Test { name.reserve(address(profile), reservationName, v, r, s); } + function testFuzz_Revert_ReserveIfContainsInvalidCharacters(bytes1 char) public { + vm.assume( + ((char >= 0 && char < 0x30) || (char > 0x39 && char < 0x61) || char > 0x7a) && char != 0x2d && char != 0x5f + ); // not a-z0-9-_ + + string memory reservationName = string(abi.encodePacked("test", char)); + + (UniversalProfile profile,) = deployProfile(); + bytes32 hash = keccak256( + abi.encodePacked(address(name), block.chainid, address(profile), reservationName, uint256(0 ether)) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(controllerKey, hash); + vm.prank(address(profile)); + vm.expectRevert( + abi.encodeWithSelector(PageName.IncorrectReservationName.selector, address(profile), reservationName) + ); + name.reserve(address(profile), reservationName, v, r, s); + } + function test_Revert_ReserveWhenExceedProfileLimit() public { (UniversalProfile profile,) = deployProfile(); vm.prank(owner);