@vechain/vebetterdao-contracts
Version:
Open-source repository that houses the smart contracts powering the decentralized VeBetterDAO on the VeChain Thor blockchain.
246 lines (245 loc) • 16.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const hardhat_1 = require("hardhat");
const mocha_1 = require("mocha");
const chai_1 = require("chai");
const fixture_test_1 = require("./fixture.test");
const xnodes_1 = require("../helpers/xnodes");
const common_1 = require("../helpers/common");
(0, mocha_1.describe)("VeBetterPassport (Signaling Logic) - @shard8b", function () {
let veBetterPassport;
let owner;
let otherAccounts;
let appId;
let regularSignaler;
let appAdmin;
let x2EarnApps;
(0, mocha_1.beforeEach)(async function () {
const fixture = await (0, fixture_test_1.setupSignalingFixture)();
veBetterPassport = fixture.veBetterPassport;
owner = fixture.owner;
otherAccounts = fixture.otherAccounts;
appId = fixture.appId;
regularSignaler = fixture.regularSignaler;
appAdmin = fixture.appAdmin;
x2EarnApps = fixture.x2EarnApps;
});
(0, mocha_1.describe)("Signaling By Default Admin", function () {
(0, mocha_1.it)("Admin can update the signaling threshold", async function () {
// Enable score check
await veBetterPassport.connect(owner).toggleCheck(4);
// score check should be enabled
(0, chai_1.expect)(await veBetterPassport.isCheckEnabled(4)).to.be.true;
// Expect score threshold to be 0
(0, chai_1.expect)(await veBetterPassport.thresholdPoPScore()).to.equal(0);
await (0, chai_1.expect)(veBetterPassport.connect(regularSignaler).signalUserWithReason(owner.address, "Some reason"))
.to.emit(veBetterPassport, "UserSignaled")
.withArgs(owner.address, regularSignaler.address, appId, "Some reason");
(0, chai_1.expect)(await veBetterPassport.signaledCounter(owner.address)).to.equal(1);
// User should be a person as their score is 0 and participation score check is enabled with threshold of 0,
// even if they have been signaled (as the signaling threshold is not met yet)
(0, chai_1.expect)(await veBetterPassport.isPerson(owner.address)).to.deep.equal([
true,
"User's participation score is above the threshold",
]);
// Update the signaling threshold to 1
await veBetterPassport.connect(owner).setSignalingThreshold(1);
// Enable signaling check
await veBetterPassport.connect(owner).toggleCheck(3);
// User should be a bot as they have been signaled and signaling threshold is 1
(0, chai_1.expect)(await veBetterPassport.isPerson(owner.address)).to.deep.equal([
false,
"User has been signaled too many times",
]);
});
(0, mocha_1.it)("DEFAULT_ADMIN_ROLE can reset signals of a user", async function () {
// Signal the user
await (0, chai_1.expect)(veBetterPassport.connect(regularSignaler).signalUserWithReason(owner.address, "Some reason"))
.to.emit(veBetterPassport, "UserSignaled")
.withArgs(owner.address, regularSignaler.address, appId, "Some reason");
(0, chai_1.expect)(await veBetterPassport.signaledCounter(owner.address)).to.equal(1);
// Reset the signals
await (0, chai_1.expect)(veBetterPassport
.connect(owner)
.resetUserSignalsWithReason(owner.address, "User demonstrated erroneous signaling"))
.to.emit(veBetterPassport, "UserSignalsReset")
.withArgs(owner.address, "User demonstrated erroneous signaling");
(0, chai_1.expect)(await veBetterPassport.signaledCounter(owner.address)).to.equal(0);
});
(0, mocha_1.it)("Should not be able to reset signals without DEFAULT_ADMIN_ROLE", async function () {
// Signal the user
await (0, chai_1.expect)(veBetterPassport.connect(regularSignaler).signalUserWithReason(owner.address, "Some reason"))
.to.emit(veBetterPassport, "UserSignaled")
.withArgs(owner.address, regularSignaler.address, appId, "Some reason");
(0, chai_1.expect)(await veBetterPassport.signaledCounter(owner.address)).to.equal(1);
// Try to reset with a non-admin account
await (0, chai_1.expect)(veBetterPassport
.connect(regularSignaler)
.resetUserSignalsWithReason(owner.address, "User demonstrated erroneous signaling")).to.be.reverted;
// Counter should remain unchanged
(0, chai_1.expect)(await veBetterPassport.signaledCounter(owner.address)).to.equal(1);
});
(0, mocha_1.it)("ROLE_GRANTER can add and remove app signalers", async function () {
const targetSignaler = otherAccounts[2];
// First verify the account is not a signaler
(0, chai_1.expect)(await veBetterPassport.appOfSignaler(targetSignaler.address)).to.equal(hardhat_1.ethers.ZeroHash);
// Add signaler using admin
await (0, chai_1.expect)(veBetterPassport.connect(owner).assignSignalerToApp(appId, targetSignaler.address))
.to.emit(veBetterPassport, "SignalerAssignedToApp")
.withArgs(targetSignaler.address, appId);
(0, chai_1.expect)(await veBetterPassport.appOfSignaler(targetSignaler.address)).to.equal(appId);
// Remove signaler
await (0, chai_1.expect)(veBetterPassport.connect(owner).removeSignalerFromApp(targetSignaler.address))
.to.emit(veBetterPassport, "SignalerRemovedFromApp")
.withArgs(targetSignaler.address, appId);
(0, chai_1.expect)(await veBetterPassport.appOfSignaler(targetSignaler.address)).to.equal(hardhat_1.ethers.ZeroHash);
});
(0, mocha_1.it)("DEFAULT_ADMIN_ROLE can signal a user without reason", async function () {
const targetUser = otherAccounts[5];
// Admin can signal without providing a reason
await (0, chai_1.expect)(veBetterPassport.connect(owner).signalUser(targetUser.address))
.to.emit(veBetterPassport, "UserSignaled")
.withArgs(targetUser.address, owner.address, hardhat_1.ethers.ZeroHash, "");
(0, chai_1.expect)(await veBetterPassport.signaledCounter(targetUser.address)).to.equal(1);
});
(0, mocha_1.it)("Non-admin users cannot use signalUser (no reason)", async function () {
const targetUser = otherAccounts[7];
// Regular signaler should not be able to use the no-reason function
await (0, chai_1.expect)(veBetterPassport.connect(regularSignaler).signalUser(targetUser.address)).to.be.reverted;
// Verify no signals were recorded
(0, chai_1.expect)(await veBetterPassport.signaledCounter(targetUser.address)).to.equal(0);
});
});
(0, mocha_1.describe)("Signaling By SIGNALER_ROLE", function () {
(0, mocha_1.it)("Admin of App can assign and revoke a signaler", async function () {
const targetSignaler = otherAccounts[2];
// First verify the account is not a signaler
(0, chai_1.expect)(await veBetterPassport.appOfSignaler(targetSignaler.address)).to.equal(hardhat_1.ethers.ZeroHash);
// Assign signaler
await (0, chai_1.expect)(veBetterPassport.connect(appAdmin).assignSignalerToAppByAppAdmin(appId, targetSignaler.address))
.to.emit(veBetterPassport, "SignalerAssignedToApp")
.withArgs(targetSignaler.address, appId);
(0, chai_1.expect)(await veBetterPassport.appOfSignaler(targetSignaler.address)).to.equal(appId);
// Remove signaler
await (0, chai_1.expect)(veBetterPassport.connect(appAdmin).removeSignalerFromAppByAppAdmin(targetSignaler.address))
.to.emit(veBetterPassport, "SignalerRemovedFromApp")
.withArgs(targetSignaler.address, appId);
(0, chai_1.expect)(await veBetterPassport.appOfSignaler(targetSignaler.address)).to.equal(hardhat_1.ethers.ZeroHash);
});
(0, mocha_1.it)("Non-Admin of an app cannot add a signaler", async function () {
const nonAdminAccount = otherAccounts[3];
const targetSignaler = otherAccounts[4];
// Try to assign signaler with non-admin account
await (0, chai_1.expect)(veBetterPassport.connect(nonAdminAccount).assignSignalerToAppByAppAdmin(appId, targetSignaler.address)).to.be.reverted;
});
(0, mocha_1.it)("Signaler can signal a user", async function () {
const targetUser = otherAccounts[3];
// Verify starting state
(0, chai_1.expect)(await veBetterPassport.hasRole(await veBetterPassport.SIGNALER_ROLE(), regularSignaler.address)).to.be.true;
(0, chai_1.expect)(await veBetterPassport.signaledCounter(targetUser.address)).to.equal(0);
await (0, chai_1.expect)(veBetterPassport.connect(regularSignaler).signalUserWithReason(targetUser.address, "Some reason"))
.to.emit(veBetterPassport, "UserSignaled")
.withArgs(targetUser.address, regularSignaler.address, appId, "Some reason");
(0, chai_1.expect)(await veBetterPassport.signaledCounter(targetUser.address)).to.equal(1);
// Remove signaler role
await (0, chai_1.expect)(veBetterPassport.connect(appAdmin).removeSignalerFromAppByAppAdmin(regularSignaler.address))
.to.emit(veBetterPassport, "SignalerRemovedFromApp")
.withArgs(regularSignaler.address, appId);
// Try to signal again - should fail
await (0, chai_1.expect)(veBetterPassport.connect(regularSignaler).signalUserWithReason(targetUser.address, "Some reason")).to
.be.reverted;
});
(0, mocha_1.it)("Passport signals should be updated when an entity's signals get reset", async function () {
// Create a new entity-passport relationship
const entity = otherAccounts[3];
const passport = otherAccounts[4];
// Link entity to passport
await (0, common_1.linkEntityToPassportWithSignature)(veBetterPassport, passport, entity, 100000);
// Make passport a signaler and reset signaler for the app
await (0, chai_1.expect)(veBetterPassport.connect(appAdmin).assignSignalerToAppByAppAdmin(appId, passport.address))
.to.emit(veBetterPassport, "SignalerAssignedToApp")
.withArgs(passport.address, appId);
// Signal the entity
await (0, chai_1.expect)(veBetterPassport.connect(passport).signalUserWithReason(entity.address, "Some reason"))
.to.emit(veBetterPassport, "UserSignaled")
.withArgs(entity.address, passport.address, appId, "Some reason");
// Verify signals for both entity and passport
(0, chai_1.expect)(await veBetterPassport.signaledCounter(entity.address)).to.equal(1);
(0, chai_1.expect)(await veBetterPassport.signaledCounter(passport.address)).to.equal(1);
// Reset signals
await (0, chai_1.expect)(veBetterPassport
.connect(owner)
.resetUserSignalsWithReason(entity.address, "User demonstrated erroneous signaling"))
.to.emit(veBetterPassport, "UserSignalsReset")
.withArgs(entity.address, "User demonstrated erroneous signaling");
// Verify signals are reset for both
(0, chai_1.expect)(await veBetterPassport.signaledCounter(entity.address)).to.equal(0);
(0, chai_1.expect)(await veBetterPassport.signaledCounter(passport.address)).to.equal(0);
});
(0, mocha_1.it)("Passport signals should be updated when an entity's app signals get reset", async function () {
// Create a new entity-passport relationship
const entity = otherAccounts[3];
const passport = otherAccounts[4];
// Link entity to passport
await (0, common_1.linkEntityToPassportWithSignature)(veBetterPassport, passport, entity, 100000);
// Signal the entity
await (0, chai_1.expect)(veBetterPassport.connect(regularSignaler).signalUserWithReason(entity.address, "Some reason"))
.to.emit(veBetterPassport, "UserSignaled")
.withArgs(entity.address, regularSignaler.address, appId, "Some reason");
(0, chai_1.expect)(await veBetterPassport.signaledCounter(entity.address)).to.equal(1);
(0, chai_1.expect)(await veBetterPassport.signaledCounter(passport.address)).to.equal(1);
// Reset signals via app admin
await (0, chai_1.expect)(veBetterPassport
.connect(owner)
.resetUserSignalsWithReason(entity.address, "User demonstrated erroneous signaling"))
.to.emit(veBetterPassport, "UserSignalsReset")
.withArgs(entity.address, "User demonstrated erroneous signaling");
// Verify signals are reset for both
(0, chai_1.expect)(await veBetterPassport.signaledCounter(entity.address)).to.equal(0);
(0, chai_1.expect)(await veBetterPassport.signaledCounter(passport.address)).to.equal(0);
});
});
(0, mocha_1.it)("should be able to reset signals of a user by app admins", async function () {
// Create a new app with otherAccounts[5] as admin
const newAppAdmin = otherAccounts[5];
const targetUser = otherAccounts[6];
await x2EarnApps
.connect(newAppAdmin)
.submitApp(otherAccounts[7].address, newAppAdmin, otherAccounts[7].address, "metadataURI");
const newAppId = hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(otherAccounts[7].address));
await (0, xnodes_1.endorseApp)(newAppId, newAppAdmin);
// Make newAppAdmin both a signaler and reset signaler for the new app
await (0, chai_1.expect)(veBetterPassport.connect(newAppAdmin).assignSignalerToAppByAppAdmin(newAppId, newAppAdmin.address))
.to.emit(veBetterPassport, "SignalerAssignedToApp")
.withArgs(newAppAdmin.address, newAppId);
// Signal user with both signalers
await (0, chai_1.expect)(veBetterPassport.connect(regularSignaler).signalUserWithReason(targetUser.address, "Some reason"))
.to.emit(veBetterPassport, "UserSignaled")
.withArgs(targetUser.address, regularSignaler.address, appId, "Some reason");
await (0, chai_1.expect)(veBetterPassport.connect(newAppAdmin).signalUserWithReason(targetUser.address, "Some reason"))
.to.emit(veBetterPassport, "UserSignaled")
.withArgs(targetUser.address, newAppAdmin.address, newAppId, "Some reason");
(0, chai_1.expect)(await veBetterPassport.signaledCounter(targetUser.address)).to.equal(2);
// Reset signals of user by app admin
await (0, chai_1.expect)(veBetterPassport
.connect(owner)
.resetUserSignalsWithReason(targetUser.address, "User demonstrated erroneous signaling"))
.to.emit(veBetterPassport, "UserSignalsReset")
.withArgs(targetUser.address, "User demonstrated erroneous signaling");
(0, chai_1.expect)(await veBetterPassport.signaledCounter(targetUser.address)).to.equal(0);
});
(0, mocha_1.describe)("Signaling By UPGRADER_ROLE", function () {
(0, mocha_1.it)("Should allow to set signaling threshold", async function () {
await veBetterPassport.connect(owner).setSignalingThreshold(2);
(0, chai_1.expect)(await veBetterPassport.signalingThreshold()).to.equal(2);
await (0, chai_1.expect)(veBetterPassport.connect(owner).grantRole(await veBetterPassport.UPGRADER_ROLE(), otherAccounts[2].address))
.to.emit(veBetterPassport, "RoleGranted")
.withArgs(await veBetterPassport.UPGRADER_ROLE(), otherAccounts[2].address, owner.address);
await veBetterPassport.connect(otherAccounts[2]).setSignalingThreshold(3);
(0, chai_1.expect)(await veBetterPassport.signalingThreshold()).to.equal(3);
});
(0, mocha_1.it)("Should revert if not UPGRADER_ROLE", async function () {
await (0, chai_1.expect)(veBetterPassport.connect(otherAccounts[3]).setSignalingThreshold(4)).to.be.reverted;
});
});
});