-
Notifications
You must be signed in to change notification settings - Fork 230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: change the nft metadata #192
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,50 @@ | ||||||
// SPDX-License-Identifier: MIT | ||||||
pragma solidity ^0.8.20; | ||||||
|
||||||
import "./xpNFT.sol"; | ||||||
|
||||||
contract ZetaXP_V2 is ZetaXP { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename the contract to adhere to Solidity naming conventions The contract name Apply this diff to rename the contract: -contract ZetaXP_V2 is ZetaXP {
+contract ZetaXPV2 is ZetaXP { 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Check: Slither
|
||||||
bytes32 private constant SETLEVEL_TYPEHASH = | ||||||
keccak256("SetLevel(uint256 tokenId,uint256 signatureExpiration,uint256 sigTimestamp,uint256 level)"); | ||||||
|
||||||
struct SetLevelData { | ||||||
uint256 tokenId; | ||||||
bytes signature; | ||||||
uint256 signatureExpiration; | ||||||
uint256 sigTimestamp; | ||||||
uint256 level; | ||||||
} | ||||||
|
||||||
mapping(uint256 => uint256) public levelByTokenId; | ||||||
event LevelSet(address indexed sender, uint256 indexed tokenId, uint256 level); | ||||||
|
||||||
function version() public pure override returns (string memory) { | ||||||
return "2.0.0"; | ||||||
} | ||||||
|
||||||
function _verifySetLevelSignature(SetLevelData memory data) private view { | ||||||
bytes32 structHash = keccak256( | ||||||
abi.encode(SETLEVEL_TYPEHASH, data.tokenId, data.signatureExpiration, data.sigTimestamp, data.level) | ||||||
); | ||||||
bytes32 constructedHash = _hashTypedDataV4(structHash); | ||||||
|
||||||
if (!SignatureChecker.isValidSignatureNow(signerAddress, constructedHash, data.signature)) { | ||||||
revert InvalidSigner(); | ||||||
} | ||||||
|
||||||
if (block.timestamp > data.signatureExpiration) revert SignatureExpired(); | ||||||
if (data.sigTimestamp <= lastUpdateTimestampByTokenId[data.tokenId]) revert OutdatedSignature(); | ||||||
} | ||||||
Comment on lines
+25
to
+37
Check notice Code scanning / Slither Block timestamp Low
ZetaXP_V2._verifySetLevelSignature(ZetaXP_V2.SetLevelData) uses timestamp for comparisons
Dangerous comparisons: - block.timestamp > data.signatureExpiration |
||||||
|
||||||
function setLevel(SetLevelData memory data) external { | ||||||
_verifySetLevelSignature(data); | ||||||
|
||||||
levelByTokenId[data.tokenId] = data.level; | ||||||
lastUpdateTimestampByTokenId[data.tokenId] = data.sigTimestamp; | ||||||
emit LevelSet(msg.sender, data.tokenId, data.level); | ||||||
} | ||||||
|
||||||
function getLevel(uint256 tokenId) external view returns (uint256) { | ||||||
return levelByTokenId[tokenId]; | ||||||
} | ||||||
} | ||||||
Comment on lines
+6
to
+50
Check warning Code scanning / Slither Conformance to Solidity naming conventions Warning
Contract ZetaXP_V2 is not in CapWords
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,35 @@ | ||||||||||||||||||||||||
import { isProtocolNetworkName } from "@zetachain/protocol-contracts"; | ||||||||||||||||||||||||
import { ethers, network, upgrades } from "hardhat"; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
import addresses from "../../data/addresses.json"; | ||||||||||||||||||||||||
import { saveAddress } from "../address.helpers"; | ||||||||||||||||||||||||
import { verifyContract } from "../explorer.helpers"; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
const networkName = network.name; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
const upgradeZetaXP = async () => { | ||||||||||||||||||||||||
if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name"); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
//@ts-ignore | ||||||||||||||||||||||||
const nftAddress = addresses["zevm"][networkName].ZetaXP; | ||||||||||||||||||||||||
Comment on lines
+13
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using Suppressing TypeScript errors with Define an appropriate interface for - //@ts-ignore
const nftAddress = addresses["zevm"][networkName].ZetaXP;
+ const nftAddress = (addresses as { [key: string]: any })["zevm"][networkName].ZetaXP; Or, better yet, define a detailed type for interface Addresses {
zevm: {
[networkName: string]: {
ZetaXP: string;
};
};
}
const addressesData = addresses as Addresses;
const nftAddress = addressesData.zevm[networkName].ZetaXP; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate There's a risk of Add a check to ensure const nftAddress = addresses["zevm"][networkName].ZetaXP;
+ if (!nftAddress) {
+ throw new Error(`NFT address not found for network: ${networkName}`);
+ } 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
const ZetaXPFactory = await ethers.getContractFactory("ZetaXP_V2"); | ||||||||||||||||||||||||
const zetaXP = await upgrades.upgradeProxy(nftAddress, ZetaXPFactory); | ||||||||||||||||||||||||
const implementationAddress = await upgrades.erc1967.getImplementationAddress(zetaXP.address); | ||||||||||||||||||||||||
Comment on lines
+16
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling for the upgrade process The upgrade operation may fail due to various reasons (e.g., network issues, incorrect contract code). Implementing error handling will make the script more robust. Wrap the upgrade steps in a try-catch block: + try {
const ZetaXPFactory = await ethers.getContractFactory("ZetaXP_V2");
const zetaXP = await upgrades.upgradeProxy(nftAddress, ZetaXPFactory);
const implementationAddress = await upgrades.erc1967.getImplementationAddress(zetaXP.address);
+ } catch (error) {
+ console.error("Upgrade failed:", error);
+ process.exit(1);
+ } 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
console.log("ZetaXP upgraded in:", zetaXP.address); | ||||||||||||||||||||||||
console.log("ZetaXP implementation deployed to:", implementationAddress); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
saveAddress("ZetaXP", zetaXP.address, networkName); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
await verifyContract(implementationAddress, []); | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle verification failures gracefully If contract verification fails, the script should handle it to prevent silent failures. Consider wrapping the verification in a try-catch block: + try {
await verifyContract(implementationAddress, []);
+ } catch (error) {
+ console.error("Contract verification failed:", error);
+ // Decide whether to exit or continue based on the importance
+ } 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||
}; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
const main = async () => { | ||||||||||||||||||||||||
await upgradeZetaXP(); | ||||||||||||||||||||||||
}; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
main().catch((error) => { | ||||||||||||||||||||||||
console.error(error); | ||||||||||||||||||||||||
process.exit(1); | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
Comment on lines
+32
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance error handling in Currently, any error causes the script to exit without specifying the context. Providing more details aids in troubleshooting. Update the error log to include contextual information: main().catch((error) => {
- console.error(error);
+ console.error("An unexpected error occurred during the upgrade script execution:", error);
process.exit(1);
}); 📝 Committable suggestion
Suggested change
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent version numbering requires attention.
The version number has been changed from "2.0.0" to "1.0.1", which is contrary to conventional semantic versioning practices. This change appears to be a regression in version number, which could lead to confusion in dependency management and contract upgrades.
Consider the following points:
ZetaXPV2
suggests a major version change, which conflicts with the "1.0.1" version number.Proposed solution:
Alternatively, if this is indeed a minor update to version 1: