@vechain/vebetterdao-contracts
Version:
Open-source repository that houses the smart contracts powering the decentralized VeBetterDAO on the VeChain Thor blockchain.
708 lines (707 loc) • 55.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const upgrades_core_1 = require("@openzeppelin/upgrades-core");
const local_1 = require("@repo/config/contracts/envs/local");
const chai_1 = require("chai");
const hardhat_1 = require("hardhat");
const mocha_1 = require("mocha");
const helpers_1 = require("../../scripts/helpers");
const helpers_2 = require("../helpers");
const xnodes_1 = require("../helpers/xnodes");
(0, mocha_1.describe)("Contract upgradeablity @shard15e", () => {
// We prepare the environment for 4 creators
let creator1;
let creator2;
let creator3;
let creator4;
before(async function () {
const { creators } = await (0, helpers_2.getOrDeployContractInstances)({ forceDeploy: true });
creator1 = creators[0];
creator2 = creators[1];
creator3 = creators[2];
creator4 = creators[3];
});
(0, mocha_1.it)("User with UPGRADER_ROLE should be able to upgrade the contract", async function () {
const { x2EarnApps, owner, administrationUtils, endorsementUtils, voteEligibilityUtils, appStorageUtils } = await (0, helpers_2.getOrDeployContractInstances)({
forceDeploy: true,
});
// Deploy the implementation contract
const Contract = await hardhat_1.ethers.getContractFactory("X2EarnApps", {
libraries: {
AdministrationUtils: await administrationUtils.getAddress(),
EndorsementUtils: await endorsementUtils.getAddress(),
VoteEligibilityUtils: await voteEligibilityUtils.getAddress(),
AppStorageUtils: await appStorageUtils.getAddress(),
},
});
const implementation = await Contract.deploy();
await implementation.waitForDeployment();
const currentImplAddress = await (0, upgrades_core_1.getImplementationAddress)(hardhat_1.ethers.provider, await x2EarnApps.getAddress());
const UPGRADER_ROLE = await x2EarnApps.UPGRADER_ROLE();
(0, chai_1.expect)(await x2EarnApps.hasRole(UPGRADER_ROLE, owner.address)).to.eql(true);
await (0, chai_1.expect)(x2EarnApps.connect(owner).upgradeToAndCall(await implementation.getAddress(), "0x")).to.not.be.reverted;
const newImplAddress = await (0, upgrades_core_1.getImplementationAddress)(hardhat_1.ethers.provider, await x2EarnApps.getAddress());
(0, chai_1.expect)(newImplAddress.toUpperCase()).to.not.eql(currentImplAddress.toUpperCase());
(0, chai_1.expect)(newImplAddress.toUpperCase()).to.eql((await implementation.getAddress()).toUpperCase());
});
(0, mocha_1.it)("Only user with UPGRADER_ROLE should be able to upgrade the contract", async function () {
const { x2EarnApps, otherAccount, administrationUtils, endorsementUtils, voteEligibilityUtils, appStorageUtils } = await (0, helpers_2.getOrDeployContractInstances)({
forceDeploy: true,
});
// Deploy the implementation contract
const Contract = await hardhat_1.ethers.getContractFactory("X2EarnApps", {
libraries: {
AdministrationUtils: await administrationUtils.getAddress(),
EndorsementUtils: await endorsementUtils.getAddress(),
VoteEligibilityUtils: await voteEligibilityUtils.getAddress(),
AppStorageUtils: await appStorageUtils.getAddress(),
},
});
const implementation = await Contract.deploy();
await implementation.waitForDeployment();
const currentImplAddress = await (0, upgrades_core_1.getImplementationAddress)(hardhat_1.ethers.provider, await x2EarnApps.getAddress());
const UPGRADER_ROLE = await x2EarnApps.UPGRADER_ROLE();
(0, chai_1.expect)(await x2EarnApps.hasRole(UPGRADER_ROLE, otherAccount.address)).to.eql(false);
await (0, chai_1.expect)(x2EarnApps.connect(otherAccount).upgradeToAndCall(await implementation.getAddress(), "0x")).to.be
.reverted;
const newImplAddress = await (0, upgrades_core_1.getImplementationAddress)(hardhat_1.ethers.provider, await x2EarnApps.getAddress());
(0, chai_1.expect)(newImplAddress.toUpperCase()).to.eql(currentImplAddress.toUpperCase());
(0, chai_1.expect)(newImplAddress.toUpperCase()).to.not.eql((await implementation.getAddress()).toUpperCase());
});
(0, mocha_1.it)("X2Earn Apps Info added pre contract upgrade should should be same after upgrade", async () => {
const config = (0, local_1.createLocalConfig)();
config.EMISSIONS_CYCLE_DURATION = 24;
config.X2EARN_NODE_COOLDOWN_PERIOD = 1;
const { timeLock, owner, otherAccounts, vechainNodesMock, veBetterPassport, administrationUtils, endorsementUtils, voteEligibilityUtils, appStorageUtils, x2EarnRewardsPool, x2EarnCreator, stargateNftMock, administrationUtilsV2, endorsementUtilsV2, voteEligibilityUtilsV2, administrationUtilsV3, endorsementUtilsV3, voteEligibilityUtilsV3, xAllocationVoting, administrationUtilsV4, endorsementUtilsV4, voteEligibilityUtilsV4, administrationUtilsV5, endorsementUtilsV5, voteEligibilityUtilsV5, administrationUtilsV6, endorsementUtilsV6, voteEligibilityUtilsV6, administrationUtilsV7, endorsementUtilsV7, voteEligibilityUtilsV7, } = await (0, helpers_2.getOrDeployContractInstances)({
forceDeploy: true,
});
// Deploy X2EarnApps
const x2EarnAppsV1 = (await (0, helpers_1.deployProxy)("X2EarnAppsV1", [
"ipfs://",
[await timeLock.getAddress(), owner.address],
owner.address,
owner.address,
]));
// Add app 1
await x2EarnAppsV1
.connect(owner)
.addApp(otherAccounts[2].address, otherAccounts[2].address, "My app", "metadataURI");
// Add app 2
await x2EarnAppsV1
.connect(owner)
.addApp(otherAccounts[3].address, otherAccounts[3].address, "My app #2", "metadataURI");
// start round using V1 contract
await (0, helpers_2.startNewAllocationRound)();
// Add app 3 during first round
await x2EarnAppsV1
.connect(owner)
.addApp(otherAccounts[4].address, otherAccounts[4].address, "My app #3", "metadataURI");
const appsV1 = await x2EarnAppsV1.apps();
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
// Upgrade X2EarnAppsV1 to X2EarnApps
const x2EarnAppsV2 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV1", "X2EarnAppsV2", await x2EarnAppsV1.getAddress(), [
config.XAPP_GRACE_PERIOD,
await vechainNodesMock.getAddress(),
await veBetterPassport.getAddress(),
await x2EarnCreator.getAddress(),
], {
version: 2,
libraries: {
AdministrationUtilsV2: await administrationUtilsV2.getAddress(),
EndorsementUtilsV2: await endorsementUtilsV2.getAddress(),
VoteEligibilityUtilsV2: await voteEligibilityUtilsV2.getAddress(),
},
}));
// start new round
await (0, helpers_2.startNewAllocationRound)();
const appsV2 = await x2EarnAppsV2.apps();
(0, chai_1.expect)(appsV1).to.eql(appsV2);
// Upgrade X2EarnAppsV2 to X2EarnApps
const x2EarnAppsV3 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV2", "X2EarnAppsV3", await x2EarnAppsV2.getAddress(), [config.X2EARN_NODE_COOLDOWN_PERIOD, await xAllocationVoting.getAddress()], {
version: 3,
libraries: {
AdministrationUtilsV3: await administrationUtilsV3.getAddress(),
EndorsementUtilsV3: await endorsementUtilsV3.getAddress(),
VoteEligibilityUtilsV3: await voteEligibilityUtilsV3.getAddress(),
},
}));
// start new round
await (0, helpers_2.startNewAllocationRound)();
const appsV3 = await x2EarnAppsV3.apps();
(0, chai_1.expect)(appsV2).to.eql(appsV3);
const cooldownPeriod = await x2EarnAppsV3.cooldownPeriod();
(0, chai_1.expect)(cooldownPeriod).to.eql(1n);
// Upgrade X2EarnAppsV2 to X2EarnApps
const x2EarnAppsV4 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV3", "X2EarnAppsV4", await x2EarnAppsV3.getAddress(), [await x2EarnRewardsPool.getAddress()], {
version: 4,
libraries: {
AdministrationUtilsV4: await administrationUtilsV4.getAddress(),
EndorsementUtilsV4: await endorsementUtilsV4.getAddress(),
VoteEligibilityUtilsV4: await voteEligibilityUtilsV4.getAddress(),
},
}));
// start new round
await (0, helpers_2.startNewAllocationRound)();
const appsV4 = await x2EarnAppsV4.apps();
(0, chai_1.expect)(appsV3).to.eql(appsV4);
// Upgrade X2EarnAppsV4 to X2EarnAppsV5
const x2EarnAppsV5 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV4", "X2EarnAppsV5", await x2EarnAppsV4.getAddress(), [], {
version: 5,
libraries: {
AdministrationUtilsV5: await administrationUtilsV5.getAddress(),
EndorsementUtilsV5: await endorsementUtilsV5.getAddress(),
VoteEligibilityUtilsV5: await voteEligibilityUtilsV5.getAddress(),
},
}));
// start new round
await (0, helpers_2.startNewAllocationRound)();
const appsV5 = await x2EarnAppsV5.apps();
(0, chai_1.expect)(appsV4).to.eql(appsV5);
// Upgrade X2EarnAppsV5 to X2EarnAppsV6
const x2EarnAppsV6 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV5", "X2EarnAppsV6", await x2EarnAppsV5.getAddress(), [], {
version: 6,
libraries: {
AdministrationUtilsV6: await administrationUtilsV6.getAddress(),
EndorsementUtilsV6: await endorsementUtilsV6.getAddress(),
VoteEligibilityUtilsV6: await voteEligibilityUtilsV6.getAddress(),
},
}));
// start new round
await (0, helpers_2.startNewAllocationRound)();
const appsV6 = await x2EarnAppsV6.apps();
(0, chai_1.expect)(appsV5).to.eql(appsV6);
// Upgrade X2EarnAppsV6 to X2EarnAppsV7
const x2EarnAppsV7 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV6", "X2EarnAppsV7", await x2EarnAppsV6.getAddress(), [await stargateNftMock.getAddress()], {
version: 7,
libraries: {
AdministrationUtilsV7: await administrationUtilsV7.getAddress(),
EndorsementUtilsV7: await endorsementUtilsV7.getAddress(),
VoteEligibilityUtilsV7: await voteEligibilityUtilsV7.getAddress(),
},
}));
// start new round
await (0, helpers_2.startNewAllocationRound)();
const appsV7 = await x2EarnAppsV7.apps();
(0, chai_1.expect)(appsV6).to.eql(appsV7);
// Upgrade X2EarnAppsV7 to X2EarnApps (V8 - latest)
const x2EarnAppsV8 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV7", "X2EarnApps", await x2EarnAppsV7.getAddress(), [], {
version: 8,
libraries: {
AdministrationUtils: await administrationUtils.getAddress(),
EndorsementUtils: await endorsementUtils.getAddress(),
VoteEligibilityUtils: await voteEligibilityUtils.getAddress(),
AppStorageUtils: await appStorageUtils.getAddress(),
},
}));
// start new round
await (0, helpers_2.startNewAllocationRound)();
const appsV8 = await x2EarnAppsV8.apps();
(0, chai_1.expect)(appsV7).to.eql(appsV8);
});
(0, mocha_1.it)("X2Earn Apps added pre contract upgrade should need endorsement after upgrade and should be in grace period", async () => {
const config = (0, local_1.createLocalConfig)();
config.EMISSIONS_CYCLE_DURATION = 24;
const { xAllocationVoting, x2EarnRewardsPool, xAllocationPool, timeLock, x2EarnCreator, owner, nodeManagement, otherAccounts, veBetterPassport, administrationUtilsV2, endorsementUtilsV2, voteEligibilityUtilsV2, } = await (0, helpers_2.getOrDeployContractInstances)({
forceDeploy: true,
});
// Deploy X2EarnApps
const x2EarnAppsV1 = (await (0, helpers_1.deployProxy)("X2EarnAppsV1", [
"ipfs://",
[await timeLock.getAddress(), owner.address],
owner.address,
owner.address,
]));
await x2EarnRewardsPool.setX2EarnApps(await x2EarnAppsV1.getAddress());
await xAllocationPool.setX2EarnAppsAddress(await x2EarnAppsV1.getAddress());
await xAllocationVoting.setX2EarnAppsAddress(await x2EarnAppsV1.getAddress());
const app1Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app"));
const app2Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app #2"));
const app3Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app #3"));
// Create two MjolnirX node holder with an endorsement score of 100
await (0, xnodes_1.createLegacyNodeHolder)(7, otherAccounts[1]); // Node strength level 7 corresponds (MjolnirX) to an endorsement score of 100
await (0, xnodes_1.createLegacyNodeHolder)(7, otherAccounts[2]); // Node strength level 7 corresponds (MjolnirX) to an endorsement score of 100
// Add apps -> should be eligble for next round
await x2EarnAppsV1
.connect(owner)
.addApp(otherAccounts[2].address, otherAccounts[2].address, "My app", "metadataURI");
await x2EarnAppsV1
.connect(owner)
.addApp(otherAccounts[3].address, otherAccounts[3].address, "My app #2", "metadataURI");
// start round using V1 contract
const round1 = await (0, helpers_2.startNewAllocationRound)();
// Add app -> should be eligble for next round
await x2EarnAppsV1
.connect(owner)
.addApp(otherAccounts[4].address, otherAccounts[4].address, "My app #3", "metadataURI");
// check eligibilty
(0, chai_1.expect)(await x2EarnAppsV1.isEligibleNow(app1Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV1.isEligibleNow(app2Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV1.isEligibleNow(app3Id)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app1Id, round1)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app2Id, round1)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app3Id, round1)).to.eql(false);
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
// Upgrade X2EarnAppsV1 to X2EarnApps
const x2EarnAppsV2 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV1", "X2EarnAppsV2", await x2EarnAppsV1.getAddress(), [
config.XAPP_GRACE_PERIOD,
await nodeManagement.getAddress(),
await veBetterPassport.getAddress(),
await x2EarnCreator.getAddress(),
], {
version: 2,
libraries: {
AdministrationUtilsV2: await administrationUtilsV2.getAddress(),
EndorsementUtilsV2: await endorsementUtilsV2.getAddress(),
VoteEligibilityUtilsV2: await voteEligibilityUtilsV2.getAddress(),
},
}));
await veBetterPassport
.connect(owner)
.grantRole(await veBetterPassport.ACTION_SCORE_MANAGER_ROLE(), await x2EarnAppsV2.getAddress());
// start new round
const round2 = await (0, helpers_2.startNewAllocationRound)();
// check eligibilty
(0, chai_1.expect)(await x2EarnAppsV2.isEligibleNow(app1Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isEligibleNow(app2Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isEligibleNow(app3Id)).to.eql(true);
// All apps should be eligible now
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app1Id, round2)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app2Id, round2)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app3Id, round2)).to.eql(true);
// Need to check the status of the apps so that they SC will reconise apps are unendrosed
await x2EarnAppsV2.checkEndorsement(app1Id);
await x2EarnAppsV2.checkEndorsement(app2Id);
await x2EarnAppsV2.checkEndorsement(app3Id);
// All apps should be seeking endorsement
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app2Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app3Id)).to.eql(true);
// 2 out of the three apps get endorsed
await x2EarnAppsV2.connect(otherAccounts[1]).endorseApp(app1Id, 1); // Node holder endorsement score is 100
await x2EarnAppsV2.connect(otherAccounts[2]).endorseApp(app2Id, 2); // Node holder endorsement score is 100
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
// Need to check the status of the apps so that they SC will reconise apps are unendrosed ans track grace period
await x2EarnAppsV2.checkEndorsement(app1Id);
await x2EarnAppsV2.checkEndorsement(app2Id);
await x2EarnAppsV2.checkEndorsement(app3Id);
// start new round
const round3 = await (0, helpers_2.startNewAllocationRound)();
// All apps should be eligible now
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app1Id, round3)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app2Id, round3)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app3Id, round3)).to.eql(true);
// Only 1 app should be seeking endorsement
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app2Id)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app3Id)).to.eql(true);
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
// Need to check the status of the apps so that they SC will reconise apps are unendrosed and track grace period
await x2EarnAppsV2.checkEndorsement(app1Id);
await x2EarnAppsV2.checkEndorsement(app2Id);
await x2EarnAppsV2.checkEndorsement(app3Id);
// start new round -> app3Id has had two rounds unendorsed so it is no longer in grace period and not eligeble for voting
const round4 = await (0, helpers_2.startNewAllocationRound)();
// All apps should be eligible now
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app1Id, round4)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app2Id, round4)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app3Id, round4)).to.eql(false);
// Only 1 app should be seeking endorsement
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app2Id)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app3Id)).to.eql(true);
});
(0, mocha_1.it)("Vechain nodes that starting endorsing XApps priod to upgrade or not subject to cooldown period but will be after they perform an action.", async () => {
const config = (0, local_1.createLocalConfig)();
config.EMISSIONS_CYCLE_DURATION = 24;
config.X2EARN_NODE_COOLDOWN_PERIOD = 1;
const { xAllocationVoting, x2EarnRewardsPool, xAllocationPool, timeLock, x2EarnCreator, owner, nodeManagement, otherAccounts, veBetterPassport, administrationUtilsV2, endorsementUtilsV2, voteEligibilityUtilsV2, administrationUtilsV3, endorsementUtilsV3, voteEligibilityUtilsV3, administrationUtilsV4, endorsementUtilsV4, voteEligibilityUtilsV4, administrationUtilsV5, endorsementUtilsV5, voteEligibilityUtilsV5, administrationUtils, endorsementUtils, voteEligibilityUtils, appStorageUtils, } = await (0, helpers_2.getOrDeployContractInstances)({
forceDeploy: true,
});
// Deploy X2EarnApps
const x2EarnAppsV1 = (await (0, helpers_1.deployProxy)("X2EarnAppsV1", [
"ipfs://",
[await timeLock.getAddress(), owner.address],
owner.address,
owner.address,
]));
await x2EarnRewardsPool.setX2EarnApps(await x2EarnAppsV1.getAddress());
await xAllocationPool.setX2EarnAppsAddress(await x2EarnAppsV1.getAddress());
await xAllocationVoting.setX2EarnAppsAddress(await x2EarnAppsV1.getAddress());
const app1Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app"));
const app2Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app #2"));
const app3Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app #3"));
// Create two MjolnirX node holder with an endorsement score of 100
const nodeId1 = await (0, xnodes_1.createLegacyNodeHolder)(7, otherAccounts[1]); // Node strength level 7 corresponds (MjolnirX) to an endorsement score of 100
const nodeId2 = await (0, xnodes_1.createLegacyNodeHolder)(7, otherAccounts[2]); // Node strength level 7 corresponds (MjolnirX) to an endorsement score of 100
// Add apps -> should be eligble for next round
await x2EarnAppsV1
.connect(owner)
.addApp(otherAccounts[2].address, otherAccounts[2].address, "My app", "metadataURI");
await x2EarnAppsV1
.connect(owner)
.addApp(otherAccounts[3].address, otherAccounts[3].address, "My app #2", "metadataURI");
// start round using V1 contract
const round1 = await (0, helpers_2.startNewAllocationRound)();
// Add app -> should be eligble for next round
await x2EarnAppsV1
.connect(owner)
.addApp(otherAccounts[4].address, otherAccounts[4].address, "My app #3", "metadataURI");
// check eligibilty
(0, chai_1.expect)(await x2EarnAppsV1.isEligibleNow(app1Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV1.isEligibleNow(app2Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV1.isEligibleNow(app3Id)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app1Id, round1)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app2Id, round1)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app3Id, round1)).to.eql(false);
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
// Upgrade X2EarnAppsV1 to X2EarnApps
const x2EarnAppsV2 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV1", "X2EarnAppsV2", await x2EarnAppsV1.getAddress(), [
config.XAPP_GRACE_PERIOD,
await nodeManagement.getAddress(),
await veBetterPassport.getAddress(),
await x2EarnCreator.getAddress(),
], {
version: 2,
libraries: {
AdministrationUtilsV2: await administrationUtilsV2.getAddress(),
EndorsementUtilsV2: await endorsementUtilsV2.getAddress(),
VoteEligibilityUtilsV2: await voteEligibilityUtilsV2.getAddress(),
},
}));
await veBetterPassport
.connect(owner)
.grantRole(await veBetterPassport.ACTION_SCORE_MANAGER_ROLE(), await x2EarnAppsV2.getAddress());
// start new round
const round2 = await (0, helpers_2.startNewAllocationRound)();
// check eligibilty
(0, chai_1.expect)(await x2EarnAppsV2.isEligibleNow(app1Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isEligibleNow(app2Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isEligibleNow(app3Id)).to.eql(true);
// All apps should be eligible now
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app1Id, round2)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app2Id, round2)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app3Id, round2)).to.eql(true);
// Need to check the status of the apps so that they SC will reconise apps are unendrosed
await x2EarnAppsV2.checkEndorsement(app1Id);
await x2EarnAppsV2.checkEndorsement(app2Id);
await x2EarnAppsV2.checkEndorsement(app3Id);
// All apps should be seeking endorsement
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app2Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app3Id)).to.eql(true);
// 2 out of the three apps get endorsed
await x2EarnAppsV2.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
await x2EarnAppsV2.connect(otherAccounts[2]).endorseApp(app2Id, nodeId2); // Node holder endorsement score is 100
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
// Need to check the status of the apps so that they SC will reconise apps are unendrosed ans track grace period
await x2EarnAppsV2.checkEndorsement(app1Id);
await x2EarnAppsV2.checkEndorsement(app2Id);
await x2EarnAppsV2.checkEndorsement(app3Id);
// start new round
const round3 = await (0, helpers_2.startNewAllocationRound)();
// All apps should be eligible now
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app1Id, round3)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app2Id, round3)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app3Id, round3)).to.eql(true);
// Only 1 app should be seeking endorsement
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app2Id)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app3Id)).to.eql(true);
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
// Need to check the status of the apps so that they SC will reconise apps are unendrosed and track grace period
await x2EarnAppsV2.checkEndorsement(app1Id);
await x2EarnAppsV2.checkEndorsement(app2Id);
await x2EarnAppsV2.checkEndorsement(app3Id);
// start new round -> app3Id has had two rounds unendorsed so it is no longer in grace period and not eligeble for voting
const round4 = await (0, helpers_2.startNewAllocationRound)();
// All apps should be eligible now
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app1Id, round4)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app2Id, round4)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app3Id, round4)).to.eql(false);
// Only 1 app should be seeking endorsement
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app2Id)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app3Id)).to.eql(true);
// Prior to upgrade node holder can endorse apps without being subject to cooldown period
await x2EarnAppsV2.connect(otherAccounts[1]).unendorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(true);
await x2EarnAppsV2.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(false);
await x2EarnAppsV2.connect(otherAccounts[1]).unendorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(true);
await x2EarnAppsV2.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
(0, chai_1.expect)(await x2EarnAppsV2.isAppUnendorsed(app1Id)).to.eql(false);
// Create new node holders with an endorsement score of 100
const nodeId3 = await (0, xnodes_1.createLegacyNodeHolder)(7, otherAccounts[5]); // Node strength level 7 corresponds (MjolnirX) to an endorsement score of 100
const nodeId4 = await (0, xnodes_1.createLegacyNodeHolder)(7, otherAccounts[6]); // Node strength level 7 corresponds (MjolnirX) to an endorsement score of 100
// app3Id just gets endorsed
await x2EarnAppsV2.connect(otherAccounts[6]).endorseApp(app3Id, nodeId4);
// Upgrade X2EarnAppsV3 to X2EarnAppsV2
const x2EarnAppsV3 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV2", "X2EarnAppsV3", await x2EarnAppsV2.getAddress(), [config.X2EARN_NODE_COOLDOWN_PERIOD, await xAllocationVoting.getAddress()], {
version: 3,
libraries: {
AdministrationUtilsV3: await administrationUtilsV3.getAddress(),
EndorsementUtilsV3: await endorsementUtilsV3.getAddress(),
VoteEligibilityUtilsV3: await voteEligibilityUtilsV3.getAddress(),
},
}));
// New node holders should not be subject to cooldown period even if they endorse an app prior to upgrade
(0, chai_1.expect)(await x2EarnAppsV3.checkCooldown(nodeId3)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV3.checkCooldown(nodeId4)).to.eql(false);
// Node holders that endorsed an app prior to upgrade should not be subject to cooldown period
(0, chai_1.expect)(await x2EarnAppsV3.checkCooldown(nodeId1)).to.eql(false);
// If a node holder that endorsed an app prior to upgrade performs an action they should be subject to cooldown period
await x2EarnAppsV3.connect(otherAccounts[1]).unendorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
await x2EarnAppsV3.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
(0, chai_1.expect)(await x2EarnAppsV3.checkCooldown(nodeId1)).to.eql(true);
// Should revert if user in cooldown period tries to endorse an app
await (0, helpers_2.catchRevert)(x2EarnAppsV3.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1));
await x2EarnAppsV3
.connect(creator1)
.submitApp(otherAccounts[4].address, otherAccounts[4].address, "My app 4", "metadataURI");
const app4Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app 4"));
// New node holders should be subject to cooldown period
await (0, helpers_2.catchRevert)(x2EarnAppsV3.connect(otherAccounts[6]).endorseApp(app4Id, nodeId4));
// Fast forward time to next round
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
await (0, helpers_2.startNewAllocationRound)();
// New node holders should not be subject to cooldown period
(0, chai_1.expect)(await x2EarnAppsV3.checkCooldown(nodeId1)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV3.checkCooldown(nodeId2)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV3.checkCooldown(nodeId3)).to.eql(false);
// Upgrade X2EarnAppsV3 to X2EarnApps
const x2EarnAppsV4 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV3", "X2EarnAppsV4", await x2EarnAppsV3.getAddress(), [await x2EarnRewardsPool.getAddress()], {
version: 4,
libraries: {
AdministrationUtilsV4: await administrationUtilsV4.getAddress(),
EndorsementUtilsV4: await endorsementUtilsV4.getAddress(),
VoteEligibilityUtilsV4: await voteEligibilityUtilsV4.getAddress(),
},
}));
// New node holders should not be subject to cooldown period even if they endorse an app prior to upgrade
(0, chai_1.expect)(await x2EarnAppsV4.checkCooldown(nodeId1)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV4.checkCooldown(nodeId2)).to.eql(false);
// Node holders that endorsed an app prior to upgrade should not be subject to cooldown period
(0, chai_1.expect)(await x2EarnAppsV4.checkCooldown(nodeId1)).to.eql(false);
// If a node holder that endorsed an app prior to upgrade performs an action they should be subject to cooldown period
await x2EarnAppsV4.connect(otherAccounts[1]).unendorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
await x2EarnAppsV4.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
(0, chai_1.expect)(await x2EarnAppsV4.checkCooldown(nodeId1)).to.eql(true);
// Should revert if user in cooldown period tries to endorse an app
await (0, helpers_2.catchRevert)(x2EarnAppsV4.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1));
await x2EarnAppsV4
.connect(creator2)
.submitApp(otherAccounts[4].address, otherAccounts[4].address, "My app 5", "metadataURI");
const app5Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app 5"));
// New node holders should be subject to cooldown period
await (0, helpers_2.catchRevert)(x2EarnAppsV4.connect(otherAccounts[6]).endorseApp(app5Id, nodeId4));
// Fast forward time to next round
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
await (0, helpers_2.startNewAllocationRound)();
// New node holders should not be subject to cooldown period
(0, chai_1.expect)(await x2EarnAppsV4.checkCooldown(nodeId1)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV4.checkCooldown(nodeId2)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV4.checkCooldown(nodeId3)).to.eql(false);
// Upgrade X2EarnAppsV4 to X2EarnAppsV5
const x2EarnAppsV5 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV4", "X2EarnAppsV5", await x2EarnAppsV4.getAddress(), [], {
version: 5,
libraries: {
AdministrationUtilsV5: await administrationUtilsV5.getAddress(),
EndorsementUtilsV5: await endorsementUtilsV5.getAddress(),
VoteEligibilityUtilsV5: await voteEligibilityUtilsV5.getAddress(),
},
}));
// New node holders should not be subject to cooldown period
(0, chai_1.expect)(await x2EarnAppsV5.checkCooldown(nodeId1)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV5.checkCooldown(nodeId2)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV5.checkCooldown(nodeId3)).to.eql(false);
// If a node holder that endorsed an app prior to upgrade performs an action they should be subject to cooldown period
await x2EarnAppsV5.connect(otherAccounts[1]).unendorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
await x2EarnAppsV5.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1); // Node holder endorsement score is 100
(0, chai_1.expect)(await x2EarnAppsV5.checkCooldown(nodeId1)).to.eql(true);
// Should revert if user in cooldown period tries to endorse an app
await (0, helpers_2.catchRevert)(x2EarnAppsV5.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1));
// Should revert if user in cooldown period tries to unendorse an app
await (0, helpers_2.catchRevert)(x2EarnAppsV5.connect(otherAccounts[1]).unendorseApp(app1Id, nodeId1));
// Should revert if user in cooldown period tries to endorse an app
await (0, helpers_2.catchRevert)(x2EarnAppsV5.connect(otherAccounts[1]).endorseApp(app1Id, nodeId1));
// Should revert if user in cooldown period tries to unendorse an app
await (0, helpers_2.catchRevert)(x2EarnAppsV5.connect(otherAccounts[1]).unendorseApp(app1Id, nodeId1));
await x2EarnAppsV5
.connect(creator3)
.submitApp(otherAccounts[4].address, otherAccounts[4].address, "My app 6", "metadataURI");
const app6Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app 6"));
// New node holders should be subject to cooldown period
await (0, helpers_2.catchRevert)(x2EarnAppsV5.connect(otherAccounts[6]).endorseApp(app6Id, nodeId4));
// Fast forward time to next round
// wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
await (0, helpers_2.startNewAllocationRound)();
// New node holders should not be subject to cooldown period
(0, chai_1.expect)(await x2EarnAppsV5.checkCooldown(nodeId1)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV5.checkCooldown(nodeId2)).to.eql(false);
(0, chai_1.expect)(await x2EarnAppsV5.checkCooldown(nodeId3)).to.eql(false);
});
(0, mocha_1.it)("Should not have state conflict after upgrading to V6", async () => {
const config = (0, local_1.createLocalConfig)();
config.EMISSIONS_CYCLE_DURATION = 24;
config.X2EARN_NODE_COOLDOWN_PERIOD = 1;
const { xAllocationVoting, x2EarnRewardsPool, xAllocationPool, timeLock, owner, otherAccounts, veBetterPassport, endorsementUtils, administrationUtils, voteEligibilityUtils, appStorageUtils, nodeManagement, x2EarnCreator, administrationUtilsV2, endorsementUtilsV2, voteEligibilityUtilsV2, administrationUtilsV3, endorsementUtilsV3, voteEligibilityUtilsV3, administrationUtilsV4, endorsementUtilsV4, voteEligibilityUtilsV4, administrationUtilsV5, endorsementUtilsV5, voteEligibilityUtilsV5, administrationUtilsV6, endorsementUtilsV6, voteEligibilityUtilsV6, } = await (0, helpers_2.getOrDeployContractInstances)({ forceDeploy: true });
const x2EarnAppsV2 = (await (0, helpers_1.deployAndUpgrade)(["X2EarnAppsV1", "X2EarnAppsV2"], [
["ipfs://", [await timeLock.getAddress(), owner.address], owner.address, owner.address],
[
config.XAPP_GRACE_PERIOD,
await nodeManagement.getAddress(),
await veBetterPassport.getAddress(),
await x2EarnCreator.getAddress(),
],
], {
versions: [undefined, 2],
libraries: [
undefined,
{
AdministrationUtilsV2: await administrationUtilsV2.getAddress(),
EndorsementUtilsV2: await endorsementUtilsV2.getAddress(),
VoteEligibilityUtilsV2: await voteEligibilityUtilsV2.getAddress(),
},
],
}));
// Grant Roles
// Grant minter and burner role to X2Earn contract
await x2EarnCreator.connect(owner).grantRole(await x2EarnCreator.MINTER_ROLE(), await x2EarnAppsV2.getAddress());
await x2EarnCreator.connect(owner).grantRole(await x2EarnCreator.BURNER_ROLE(), await x2EarnAppsV2.getAddress());
// Grant the ACTION_SCORE_MANAGER_ROLE to X2Earn contract
await veBetterPassport
.grantRole(await veBetterPassport.ACTION_SCORE_MANAGER_ROLE(), await x2EarnAppsV2.getAddress())
.then(async (tx) => await tx.wait());
await x2EarnRewardsPool.setX2EarnApps(await x2EarnAppsV2.getAddress());
await xAllocationPool.setX2EarnAppsAddress(await x2EarnAppsV2.getAddress());
await xAllocationVoting.setX2EarnAppsAddress(await x2EarnAppsV2.getAddress());
const app1Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app"));
const app2Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app #2"));
const app3Id = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes("My app #3"));
// Create two MjolnirX node holders with an endorsement score of 100
await (0, xnodes_1.createLegacyNodeHolder)(7, otherAccounts[1]); // Node strength level 7 corresponds (MjolnirX) to an endorsement score of 100
await (0, xnodes_1.createLegacyNodeHolder)(7, otherAccounts[2]); // Node strength level 7 corresponds (MjolnirX) to an endorsement score of 100
// Add apps -> should be eligible for the next round
await x2EarnAppsV2
.connect(owner)
.submitApp(otherAccounts[2].address, otherAccounts[2].address, "My app", "metadataURI");
await x2EarnAppsV2
.connect(owner)
.submitApp(otherAccounts[3].address, otherAccounts[3].address, "My app #2", "metadataURI");
await x2EarnAppsV2.connect(otherAccounts[1]).endorseApp(app1Id, 1);
await x2EarnAppsV2.connect(otherAccounts[2]).endorseApp(app2Id, 2);
// Start round using V1 contract
const round1 = await (0, helpers_2.startNewAllocationRound)();
// Add app -> should be eligible for the next round
await x2EarnAppsV2
.connect(owner)
.submitApp(otherAccounts[4].address, otherAccounts[4].address, "My app #3", "metadataURI");
await (0, xnodes_1.createLegacyNodeHolder)(7, otherAccounts[4]); // Node strength level 7 corresponds (MjolnirX) to an endorsement score of 100
await x2EarnAppsV2.connect(otherAccounts[4]).endorseApp(app3Id, 3);
// Check eligibility
(0, chai_1.expect)(await x2EarnAppsV2.isEligibleNow(app1Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isEligibleNow(app2Id)).to.eql(true);
(0, chai_1.expect)(await x2EarnAppsV2.isEligibleNow(app3Id)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app1Id, round1)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app2Id, round1)).to.eql(true);
(0, chai_1.expect)(await xAllocationVoting.isEligibleForVote(app3Id, round1)).to.eql(false);
// Wait for round to end
await (0, helpers_2.waitForCurrentRoundToEnd)();
const initialSlotVoteEligibility = BigInt("0xb5b8d618af1ffb8d5bcc4bd23f445ba34ed08d7a16d1e1b5411cfbe7913e5900");
const initialSlotSettings = BigInt("0x83b9a7e51f394efa93107c3888716138908bbbe611dfc86afa3639a826441100");
const initialSlotAppsStorage = BigInt("0xb6909058bd527140b8d55a44344c5e42f1f148f1b3b16df7641882df8dd72900");
const initialSlotAdministration = BigInt("0x5830f0e95c01712d916c34d9e2fa42e9f749b325b67bce7382d70bb99c623500");
const initialEndorsementSlot = BigInt("0xc1a7bcdc0c77e8c77ade4541d1777901ab96ca598d164d89afa5c8dfbfc44300");
const storageSlots = await (0, helpers_2.getStorageSlots)(x2EarnAppsV2.getAddress(), initialSlotVoteEligibility, initialSlotSettings, initialSlotAppsStorage, initialSlotAdministration, initialEndorsementSlot);
config.X2EARN_NODE_COOLDOWN_PERIOD = 24;
// Upgrade X2EarnAppsV2 to X2EarnAppsV3
const x2EarnAppsV3 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV2", "X2EarnAppsV3", await x2EarnAppsV2.getAddress(), [config.X2EARN_NODE_COOLDOWN_PERIOD, await xAllocationVoting.getAddress()], {
version: 3,
libraries: {
AdministrationUtilsV3: await administrationUtilsV3.getAddress(),
EndorsementUtilsV3: await endorsementUtilsV3.getAddress(),
VoteEligibilityUtilsV3: await voteEligibilityUtilsV3.getAddress(),
},
}));
const storageSlotsAfterV3 = await (0, helpers_2.getStorageSlots)(x2EarnAppsV3.getAddress(), initialSlotVoteEligibility, initialSlotSettings, initialSlotAppsStorage, initialSlotAdministration, initialEndorsementSlot);
(0, chai_1.expect)(await x2EarnAppsV3.version()).to.equal("3");
(0, chai_1.expect)(storageSlotsAfterV3[storageSlotsAfterV3.length - 2]).to.equal(BigInt(config.X2EARN_NODE_COOLDOWN_PERIOD));
for (let i = 0; i < storageSlots.length; i++) {
(0, chai_1.expect)(storageSlots[i]).to.equal(storageSlotsAfterV3[i]);
}
const storageSlotsAdministrationAfterV3 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotAdministration);
const storageSlotsVoteEligibilityAfterV3 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotVoteEligibility);
const storageSlotsSettingsAfterV3 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotSettings);
const storageSlotsAppsStorageAfterV3 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotAppsStorage);
const storageSlotsEndorsementSlotAfterV3 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialEndorsementSlot);
// x2EarnAppsV4
const x2EarnAppsV4 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV3", "X2EarnAppsV4", await x2EarnAppsV3.getAddress(), [await x2EarnRewardsPool.getAddress()], {
version: 4,
libraries: {
AdministrationUtilsV4: await administrationUtilsV4.getAddress(),
EndorsementUtilsV4: await endorsementUtilsV4.getAddress(),
VoteEligibilityUtilsV4: await voteEligibilityUtilsV4.getAddress(),
},
}));
const storageSlotsAdministrationAfterV4 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotAdministration);
const storageSlotsVoteEligibilityAfterV4 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotVoteEligibility);
const storageSlotsSettingsAfterV4 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotSettings);
const storageSlotsAppsStorageAfterV4 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotAppsStorage);
const storageSlotsEndorsementSlotAfterV4 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialEndorsementSlot);
(0, chai_1.expect)(await x2EarnAppsV4.version()).to.equal("4");
// Check that the storage slots are the same for the administration module
for (let i = 0; i < storageSlotsAdministrationAfterV3.length; i++) {
(0, chai_1.expect)(storageSlotsAdministrationAfterV3[i]).to.equal(storageSlotsAdministrationAfterV4[i]);
}
// Check that the storage slots are the same for the vote eligibility module
for (let i = 0; i < storageSlotsVoteEligibilityAfterV3.length; i++) {
(0, chai_1.expect)(storageSlotsVoteEligibilityAfterV3[i]).to.equal(storageSlotsVoteEligibilityAfterV4[i]);
}
// Check that the storage slots are the same for the settings module
for (let i = 0; i < storageSlotsSettingsAfterV3.length; i++) {
(0, chai_1.expect)(storageSlotsSettingsAfterV3[i]).to.equal(storageSlotsSettingsAfterV4[i]);
}
// Check that the storage slots are the same for the apps storage module
for (let i = 0; i < storageSlotsAppsStorageAfterV3.length; i++) {
(0, chai_1.expect)(storageSlotsAppsStorageAfterV3[i]).to.equal(storageSlotsAppsStorageAfterV4[i]);
}
// Check that the storage slots are the same for the endorsement slot
for (let i = 0; i < storageSlotsEndorsementSlotAfterV3.length; i++) {
(0, chai_1.expect)(storageSlotsEndorsementSlotAfterV3[i]).to.equal(storageSlotsEndorsementSlotAfterV4[i]);
}
// The first slot is the x2earnCreator contract address
const addressFromSlot = hardhat_1.ethers.getAddress("0x" + storageSlotsAdministrationAfterV4[0].slice(26));
const expectedAddress = hardhat_1.ethers.getAddress(await x2EarnCreator.getAddress());
(0, chai_1.expect)(addressFromSlot).to.equal(expectedAddress);
// The second slot is the x2earnRewardsPool contract address
const addressFromSlot2 = hardhat_1.ethers.getAddress("0x" + storageSlotsAdministrationAfterV4[1].slice(26));
const expectedAddress2 = hardhat_1.ethers.getAddress(await x2EarnRewardsPool.getAddress());
(0, chai_1.expect)(addressFromSlot2).to.equal(expectedAddress2);
// Upgrade to V5
const x2EarnAppsV5 = (await (0, helpers_1.upgradeProxy)("X2EarnAppsV4", "X2EarnAppsV5", await x2EarnAppsV4.getAddress(), [], {
version: 5,
libraries: {
AdministrationUtilsV5: await administrationUtilsV5.getAddress(),
EndorsementUtilsV5: await endorsementUtilsV5.getAddress(),
VoteEligibilityUtilsV5: await voteEligibilityUtilsV5.getAddress(),
},
}));
const storageSlotsAdministrationAfterV5 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotAdministration);
const storageSlotsVoteEligibilityAfterV5 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotVoteEligibility);
const storageSlotsSettingsAfterV5 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotSettings);
const storageSlotsAppsStorageAfterV5 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialSlotAppsStorage);
const storageSlotsEndorsementSlotAfterV5 = await (0, helpers_2.getStorageSlots)(await x2EarnAppsV2.getAddress(), initialEndorsementSlot);
// check that the version is good
(0, chai_1.expect)(await x2EarnAppsV5.version()).to.eql("5");
// Check that the storage slots are the same for the administration module