Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
cf43f80
delete-attribute
aniket866 Mar 18, 2026
12a9ab7
Code rabbit follow up
aniket866 Mar 18, 2026
5926ba3
Code rabbit fix
aniket866 Mar 18, 2026
8f60e5d
Code rabbit fix
aniket866 Mar 18, 2026
6a0d7f8
fix: schema by update important field
Nikuunj Mar 20, 2026
0b6ee25
update: error for name and contact
Nikuunj Mar 20, 2026
340f4d9
fix: validate user need to pass phone / email , and name is mandatory
Nikuunj Mar 20, 2026
7c36ca1
update: call the fn
Nikuunj Mar 20, 2026
f229460
Merge branch 'main' into delete-attribute
aniket866 Mar 20, 2026
cb415de
formatting
aniket866 Mar 20, 2026
a926546
Query-functions
aniket866 Mar 20, 2026
6c30f6d
fix: all test and validatefn call fix
Nikuunj Mar 23, 2026
417a1be
fix: fmt
Nikuunj Mar 23, 2026
a192669
Merge pull request #64 from aniket866/Query-Functions
KanishkSogani Mar 23, 2026
98dc951
update: test case for phn and email hashcompatibility
Nikuunj Mar 23, 2026
4cfdb02
Revert "update: test case for phn and email hashcompatibility"
Nikuunj Mar 23, 2026
049f8fc
fix: test_schemaConstants
Nikuunj Mar 23, 2026
c656af9
Merge pull request #62 from Nikuunj/main
KanishkSogani Mar 23, 2026
10608be
Merge branch 'bug' of github.com:Nikuunj/IdentityTokens-EVM-Contracts
Nikuunj Mar 23, 2026
5ea5109
update: validate setattribute and set contract fn
Nikuunj Mar 23, 2026
42ade6b
fix: test case for missing name and contact
Nikuunj Mar 23, 2026
d8590fc
update: identitytoken validate remove if field name , email, ph no
Nikuunj Mar 24, 2026
aa8df60
update: test case for and use single batch test fix
Nikuunj Mar 24, 2026
1f50c7e
remove: validate condition from batch set
Nikuunj Mar 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/IdentityToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,25 @@ contract IdentityToken is ERC721, IIdentityToken {
return tokenId;
}

/**
* @dev Adds validation to ensure required identity fields are present.
* Name is mandatory and at least one contact method (email or phone)
* must be provided.
*/
function _validateRequiredFields(uint256 tokenId) internal view {
bytes memory name = attributes[tokenId][keccak256(abi.encodePacked("name"))];
bytes memory email = attributes[tokenId][keccak256(abi.encodePacked("email"))];
bytes memory phone = attributes[tokenId][keccak256(abi.encodePacked("phone"))];

// Name is mandatory
if (name.length == 0) revert Errors.MissingName();

// At least one contact method required
if (email.length == 0 && phone.length == 0) {
revert Errors.MissingContact();
}
}
Comment on lines +84 to +101
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Gas optimization: Pre-compute constant key hashes.

The function computes keccak256(abi.encodePacked("name")), keccak256(abi.encodePacked("email")), and keccak256(abi.encodePacked("phone")) on every call. Since these are static strings, declare them as constant bytes32 at the contract level (or reuse from Schema.sol if already defined) to save gas.

♻️ Proposed refactor

Add constants at contract level:

bytes32 private constant KEY_NAME = keccak256(abi.encodePacked("name"));
bytes32 private constant KEY_EMAIL = keccak256(abi.encodePacked("email"));
bytes32 private constant KEY_PHONE = keccak256(abi.encodePacked("phone"));

Then refactor the function:

 function _validateRequiredFields(uint256 tokenId) internal view {
-    bytes memory name = attributes[tokenId][keccak256(abi.encodePacked("name"))];
-    bytes memory email = attributes[tokenId][keccak256(abi.encodePacked("email"))];
-    bytes memory phone = attributes[tokenId][keccak256(abi.encodePacked("phone"))];
+    bytes memory name = attributes[tokenId][KEY_NAME];
+    bytes memory email = attributes[tokenId][KEY_EMAIL];
+    bytes memory phone = attributes[tokenId][KEY_PHONE];

     // Name is mandatory
     if (name.length == 0) revert Errors.MissingName();

     // At least one contact method required
     if (email.length == 0 && phone.length == 0) {
         revert Errors.MissingContact();
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/IdentityToken.sol` around lines 79 - 96, Pre-compute and reuse the
keccak256 hashes for the static attribute keys instead of recomputing them in
_validateRequiredFields: declare bytes32 constants (e.g., KEY_NAME, KEY_EMAIL,
KEY_PHONE) at the contract level or import/reuse the equivalents from
Schema.sol, then replace the inline
keccak256(abi.encodePacked("name"/"email"/"phone")) lookups in
_validateRequiredFields with attributes[tokenId][KEY_NAME],
attributes[tokenId][KEY_EMAIL], and attributes[tokenId][KEY_PHONE] to reduce
gas.

Comment on lines +89 to +101
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_validateRequiredFields recomputes keccak256(abi.encodePacked(...)) on every call and copies the stored bytes values into memory. To reduce gas and avoid key-string drift/typos, consider using precomputed key hashes (e.g., extend/use the existing Schema library) and read lengths directly from storage (bytes storage) instead of copying to memory.

Copilot uses AI. Check for mistakes.

/**
* @dev Sets a metadata attribute (e.g., name, social link) for an identity.
*/
Expand All @@ -85,6 +104,8 @@ contract IdentityToken is ERC721, IIdentityToken {
bytes calldata value
) external onlyTokenOwner(tokenId) notCompromised(tokenId) {
_setAttribute(tokenId, key, value);

_validateRequiredFields(tokenId);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ library Errors {
error AlreadyHasIdentity();
error DuplicateEndorsement();
error ArrayLengthMismatch();
error MissingName();
error MissingContact();
}
Loading