Skip to content

Commit

Permalink
feat: Improve XP Gov
Browse files Browse the repository at this point in the history
  • Loading branch information
andresaiello committed Oct 29, 2024
1 parent 39e2ec2 commit 6893ead
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/zevm-app-contracts/contracts/xp-nft/ZetaXPGov.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ contract ZetaXPGov is Governor, GovernorSettings, GovernorCountingSimple, Govern
) internal view override returns (uint256) {
uint256 tokenId = xpNFT.tokenByUserTag(account, tagValidToVote);
uint256 level = xpNFT.getLevel(tokenId);
require(level > 0, "ZetaXPGov: invalid NFT level");

// Assign voting weight based on NFT level
if (level == 1) {
Expand Down
4 changes: 3 additions & 1 deletion packages/zevm-app-contracts/data/addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"withdrawERC20": "0xa349B9367cc54b47CAb8D09A95836AE8b4D1d84E",
"ZetaXP": "0x5c25b6f4D2b7a550a80561d3Bf274C953aC8be7d",
"InstantRewards": "0x10DfEd4ba9b8F6a1c998E829FfC0325D533c80E3",
"ProofOfLiveness": "0x981EB6fD19717Faf293Fba0cBD05C6Ac97b8C808"
"ProofOfLiveness": "0x981EB6fD19717Faf293Fba0cBD05C6Ac97b8C808",
"TimelockController": "0x26F16EB99F195F1f401b0Afcafa2FEbb9427CE09",
"ZetaXPGov": "0x7B01E3060B9aAb92E3b981DB699330bB582a53C0"
},
"zeta_mainnet": {
"disperse": "0x23ce409Ea60c3d75827d04D9db3d52F3af62e44d",
Expand Down
4 changes: 2 additions & 2 deletions packages/zevm-app-contracts/scripts/address.helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { join } from "path";

import addresses from "../data/addresses.json";

export const getZEVMAppAddress = (address: string): string => {
return (addresses["zevm"] as any)["zeta_testnet"][address];
export const getZEVMAppAddress = (address: string, network: string = "zeta_testnet"): string => {
return (addresses["zevm"] as any)[network][address];
};

export const getChainId = (network: ZetaProtocolNetwork): number => {
Expand Down
65 changes: 65 additions & 0 deletions packages/zevm-app-contracts/scripts/xp-nft/deploy-gov.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { isProtocolNetworkName } from "@zetachain/protocol-contracts";
import { ethers, network } from "hardhat";

import { getZEVMAppAddress, saveAddress } from "../address.helpers";
import { verifyContract } from "../explorer.helpers";

const networkName = network.name;

const encodeTag = (tag: string) => ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["string"], [tag]));

const executeVerifyContract = async (name: string, address: string, args: any[]) => {
if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name");

console.log(`${name} deployed to:`, address);
saveAddress(`${name}`, address, networkName);
await verifyContract(address, args);
};

const deployXPGov = async () => {
const [signer] = await ethers.getSigners();

if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name");
const zetaXPAddress = getZEVMAppAddress("ZetaXP", networkName);
console.log("ZetaXP address:", zetaXPAddress);

// Deploy the TimelockController contract
const timelockFactory = await ethers.getContractFactory("TimelockController");
const timelock = await timelockFactory.deploy(3600, [signer.address], [signer.address], signer.address);
await timelock.deployed();

const timelockAddress = timelock.address;
executeVerifyContract("TimelockController", timelockAddress, [
3600,
[signer.address],
[signer.address],
signer.address,
]);

const tag = encodeTag("XP_NFT");

// Deploy the ZetaXPGov contract
const ZetaXPGovFactory = await ethers.getContractFactory("ZetaXPGov");
const zetaGov = await ZetaXPGovFactory.deploy(zetaXPAddress, timelockAddress, 4, tag);
await zetaGov.deployed();

const zetaGovAddress = zetaGov.address;

executeVerifyContract("ZetaXPGov", zetaGovAddress, [zetaXPAddress, timelockAddress, 4, tag]);

// Assign proposer and executor roles to the signer
const proposerRole = await timelock.PROPOSER_ROLE();
const executorRole = await timelock.EXECUTOR_ROLE();
await timelock.grantRole(proposerRole, zetaGovAddress);
await timelock.grantRole(executorRole, zetaGovAddress);
};

const main = async () => {
if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name");
await deployXPGov();
};

main().catch((error) => {
console.error(error);
process.exit(1);
});
38 changes: 38 additions & 0 deletions packages/zevm-app-contracts/scripts/xp-nft/gov-query-proposals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { isProtocolNetworkName } from "@zetachain/protocol-contracts";
import { ethers, network } from "hardhat";

import { getZEVMAppAddress } from "../address.helpers";

const networkName = network.name;

const callGov = async () => {
const govAddress = getZEVMAppAddress("ZetaXPGov", networkName);
console.log("ZetaXPGov address:", govAddress);

const ZetaXPGovFactory = await ethers.getContractFactory("ZetaXPGov");
const zetaGov = await ZetaXPGovFactory.attach(govAddress);

const start = 7426910 - 1;
const end = 7441292 + 1;
for (let i = start; i < end; i += 1000) {
const proposalIds = await zetaGov.queryFilter(zetaGov.filters.ProposalCreated(), i, i + 1000);
if (proposalIds.length > 0) {
for (let j = 0; j < proposalIds.length; j++) {
const proposalId = proposalIds[j].proposalId;
const votes = await zetaGov.proposalVotes(proposalId);
console.log("Proposal ID:", proposalId);
console.log("Votes:", votes);
}
}
}
};

const main = async () => {
if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name");
await callGov();
};

main().catch((error) => {
console.error(error);
process.exit(1);
});
68 changes: 68 additions & 0 deletions packages/zevm-app-contracts/scripts/xp-nft/gov-set-level.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { isProtocolNetworkName } from "@zetachain/protocol-contracts";
import { ethers, network } from "hardhat";

import { getSelLevelSignature } from "../../test/xp-nft/test.helpers";
import { ZetaXP_V2 } from "../../typechain-types";
import { getZEVMAppAddress, saveAddress } from "../address.helpers";

const networkName = network.name;

const user = "0x3a600ECC217387e7Cf9F82fc2F3ffFb43F20FF80";
const encodeTag = (tag: string) => ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["string"], [tag]));

// Helper function to set the level of an NFT
const setLevelToNFT = async (tokenId: number, level: number, zetaXP: ZetaXP_V2, signer: SignerWithAddress) => {
const currentBlock = await ethers.provider.getBlock("latest");
const sigTimestamp = currentBlock.timestamp;
const signatureExpiration = sigTimestamp + 1000;

const currentChainId = (await ethers.provider.getNetwork()).chainId;
const signature = await getSelLevelSignature(
currentChainId,
zetaXP.address,
signer,
signatureExpiration,
sigTimestamp,
tokenId,
level
);

await zetaXP.setLevel({ level, sigTimestamp, signature, signatureExpiration, tokenId });
};

const callGov = async () => {
const [signer] = await ethers.getSigners();

if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name");
const zetaXPAddress = getZEVMAppAddress("ZetaXP", networkName);
console.log("ZetaXP address:", zetaXPAddress);

const XPNFT = await ethers.getContractFactory("ZetaXP_V2");
const xpnft = await XPNFT.attach(zetaXPAddress);

const xpSigner = await xpnft.signerAddress();
console.log("XP Signer:", xpSigner);

const tag = encodeTag("XP_NFT");
console.log("Tag:", tag);
const id = await xpnft.tokenByUserTag(user, tag);
console.log("ID:", id);

const level = await xpnft.getLevel(id);
console.log("Level:", level);

if (level.toNumber() === 0) {
await setLevelToNFT(id, 3, xpnft, signer);
}
};

const main = async () => {
if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name");
await callGov();
};

main().catch((error) => {
console.error(error);
process.exit(1);
});

0 comments on commit 6893ead

Please sign in to comment.