@dydxfoundation/governance
Version:
dYdX governance smart contracts
125 lines (124 loc) • 6.69 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const chai_1 = require("chai");
const ethers_1 = require("ethers");
const lodash_1 = __importDefault(require("lodash"));
const constants_1 = require("../../src/lib/constants");
const hex_1 = require("../../src/lib/hex");
const describe_contract_1 = require("../helpers/describe-contract");
const get_affected_stakers_for_test_1 = require("../helpers/get-affected-stakers-for-test");
const hre_1 = __importDefault(require("../hre"));
let testStakers;
function init() {
testStakers = (0, get_affected_stakers_for_test_1.getAffectedStakersForTest)();
}
(0, describe_contract_1.describeContractHardhatRevertBeforeEach)('SafetyModuleV2 initial storage slots', init, (ctx) => {
it('0–49: AccessControlUpgradeable', async () => {
await expectZeroes(lodash_1.default.range(0, 50));
});
it('50: ReentrancyGuard', async () => {
(0, chai_1.expect)(await read(50)).to.equal(1);
});
it('51–101: VersionedInitializable', async () => {
(0, chai_1.expect)(await read(51)).to.equal(2);
await expectZeroes(lodash_1.default.range(52, 102));
});
it('102–127: SM1Storage', async () => {
// Slot 102 and 103: Epoch parameters.
const expectedEpochParametersStruct = (0, hex_1.concatHex)([
ctx.config.EPOCH_ZERO_START,
ctx.config.EPOCH_LENGTH, // interval
].map((n) => (0, hex_1.asUintHex)(n, 128)));
(0, chai_1.expect)(await read(102)).to.equal(expectedEpochParametersStruct);
(0, chai_1.expect)(await read(103)).to.equal(ctx.config.BLACKOUT_WINDOW);
await expectZeroes(lodash_1.default.range(104, 105));
// Slot 105: Domain separator hash.
(0, chai_1.expect)((await read(105)).eq(0)).to.be.false();
await expectZeroes(lodash_1.default.range(106, 113));
// Slot 113: Rewards per second.
(0, chai_1.expect)(await read(113)).to.equal(ctx.config.SM_REWARDS_PER_SECOND);
// Slot 114: Global index value and timestamp.
const stakedFilter = ctx.safetyModule.filters.Staked();
const stakedLogs = await ctx.safetyModule.queryFilter(stakedFilter);
const lastStakeLog = stakedLogs[stakedLogs.length - 1];
const lastStakeBlock = await lastStakeLog.getBlock();
const lastStakeTimestamp = lastStakeBlock.timestamp;
const expectedIndexAndTimestamp = (0, hex_1.concatHex)([
(0, hex_1.asUintHex)(lastStakeTimestamp, 32),
(0, hex_1.asUintHex)(0, 224), // index
]);
(0, chai_1.expect)(await read(114)).to.equal(expectedIndexAndTimestamp);
await expectZeroes(lodash_1.default.range(115, 119));
// Slot 119: Total active balance (current epoch).
(0, chai_1.expect)(await read(119)).to.equal(1);
await expectZeroes(lodash_1.default.range(120, 124));
// Slot 115: Exchange rate.
(0, chai_1.expect)(await read(124)).to.equal(new bignumber_js_1.default(constants_1.SM_EXCHANGE_RATE_BASE).toString());
await expectZeroes(lodash_1.default.range(125, 200));
});
it('Mappings', async () => {
// Check mappings for just a few of the affected stakers.
const stakersToCheck = testStakers.slice(0, 3);
for (const staker of stakersToCheck) {
const stakedFilter = ctx.safetyModule.filters.Staked(staker);
const stakedLogs = await ctx.safetyModule.queryFilter(stakedFilter);
(0, chai_1.expect)(stakedLogs.length).to.equal(1);
const stakeLog = stakedLogs[0];
const stakeBlock = await stakeLog.getBlock();
const stakeBlockNumber = stakeBlock.number;
// Expect _VOTING_SNAPSHOTS_[staker].blockNumber to be the block number in which the staker
// staked funds.
const votingSnapshotBlockNumberSlot = ethers_1.utils.keccak256((0, hex_1.concatHex)([
(0, hex_1.asUintHex)(0, 256),
ethers_1.utils.keccak256((0, hex_1.concatHex)([
(0, hex_1.asBytes32)(staker),
(0, hex_1.asUintHex)(107, 256),
])),
]));
(0, chai_1.expect)(await read(votingSnapshotBlockNumberSlot)).to.equal(stakeBlockNumber);
// Expect _PROPOSITION_SNAPSHOTS_[staker].blockNumber to be the block number in which the staker
// staked funds.
const propositionSnapshotBlockNumberSlot = ethers_1.utils.keccak256((0, hex_1.concatHex)([
(0, hex_1.asUintHex)(0, 256),
ethers_1.utils.keccak256((0, hex_1.concatHex)([
(0, hex_1.asBytes32)(staker),
(0, hex_1.asUintHex)(110, 256),
])),
]));
(0, chai_1.expect)(await read(propositionSnapshotBlockNumberSlot)).to.equal(stakeBlockNumber);
// Expect _VOTING_SNAPSHOT_COUNTS_[staker] to be set to 1 for each staker.
const votingSnapshotCountSlot = ethers_1.utils.keccak256((0, hex_1.concatHex)([
(0, hex_1.asBytes32)(staker),
(0, hex_1.asUintHex)(108, 256),
]));
(0, chai_1.expect)(await read(votingSnapshotCountSlot)).to.equal(1);
// Expect _PROPOSITION_SNAPSHOT_COUNTS_[staker] to be set to 1 for each staker.
const propositionSnapshotCountSlot = ethers_1.utils.keccak256((0, hex_1.concatHex)([
(0, hex_1.asBytes32)(staker),
(0, hex_1.asUintHex)(111, 256),
]));
(0, chai_1.expect)(await read(propositionSnapshotCountSlot)).to.equal(1);
// Expect _ACTIVE_BALANCES_[staker].currentEpoch to be set to 1 for each staker.
const activeBalanceCurrentEpochSlot = ethers_1.utils.keccak256((0, hex_1.concatHex)([
(0, hex_1.asBytes32)(staker),
(0, hex_1.asUintHex)(118, 256),
]));
(0, chai_1.expect)(await read(activeBalanceCurrentEpochSlot)).to.equal(1);
}
});
async function expectZeroes(range) {
for (const i of range) {
(0, chai_1.expect)(await read(i)).to.equal(0);
}
}
async function readHex(slot) {
return hre_1.default.ethers.provider.getStorageAt(ctx.safetyModule.address, ethers_1.BigNumber.from(slot));
}
async function read(slot) {
return ethers_1.BigNumber.from(await readHex(ethers_1.BigNumber.from(slot)));
}
});