Votes.test.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. const { ethers } = require('hardhat');
  2. const { expect } = require('chai');
  3. const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
  4. const { sum } = require('../../helpers/math');
  5. const { zip } = require('../../helpers/iterate');
  6. const time = require('../../helpers/time');
  7. const { shouldBehaveLikeVotes } = require('./Votes.behavior');
  8. const MODES = {
  9. blocknumber: '$VotesMock',
  10. timestamp: '$VotesTimestampMock',
  11. };
  12. const AMOUNTS = [ethers.parseEther('10000000'), 10n, 20n];
  13. describe('Votes', function () {
  14. for (const [mode, artifact] of Object.entries(MODES)) {
  15. const fixture = async () => {
  16. const accounts = await ethers.getSigners();
  17. const amounts = Object.fromEntries(
  18. zip(
  19. accounts.slice(0, AMOUNTS.length).map(({ address }) => address),
  20. AMOUNTS,
  21. ),
  22. );
  23. const name = 'My Vote';
  24. const version = '1';
  25. const votes = await ethers.deployContract(artifact, [name, version]);
  26. return { accounts, amounts, votes, name, version };
  27. };
  28. describe(`vote with ${mode}`, function () {
  29. beforeEach(async function () {
  30. Object.assign(this, await loadFixture(fixture));
  31. });
  32. shouldBehaveLikeVotes(AMOUNTS, { mode, fungible: true });
  33. it('starts with zero votes', async function () {
  34. expect(await this.votes.getTotalSupply()).to.equal(0n);
  35. });
  36. describe('performs voting operations', function () {
  37. beforeEach(async function () {
  38. this.txs = [];
  39. for (const [account, amount] of Object.entries(this.amounts)) {
  40. this.txs.push(await this.votes.$_mint(account, amount));
  41. }
  42. });
  43. it('reverts if block number >= current block', async function () {
  44. const lastTxTimepoint = await time.clockFromReceipt[mode](this.txs.at(-1));
  45. const clock = await this.votes.clock();
  46. await expect(this.votes.getPastTotalSupply(lastTxTimepoint))
  47. .to.be.revertedWithCustomError(this.votes, 'ERC5805FutureLookup')
  48. .withArgs(lastTxTimepoint, clock);
  49. });
  50. it('delegates', async function () {
  51. expect(await this.votes.getVotes(this.accounts[0])).to.equal(0n);
  52. expect(await this.votes.getVotes(this.accounts[1])).to.equal(0n);
  53. expect(await this.votes.delegates(this.accounts[0])).to.equal(ethers.ZeroAddress);
  54. expect(await this.votes.delegates(this.accounts[1])).to.equal(ethers.ZeroAddress);
  55. await this.votes.delegate(this.accounts[0], ethers.Typed.address(this.accounts[0]));
  56. expect(await this.votes.getVotes(this.accounts[0])).to.equal(this.amounts[this.accounts[0].address]);
  57. expect(await this.votes.getVotes(this.accounts[1])).to.equal(0n);
  58. expect(await this.votes.delegates(this.accounts[0])).to.equal(this.accounts[0]);
  59. expect(await this.votes.delegates(this.accounts[1])).to.equal(ethers.ZeroAddress);
  60. await this.votes.delegate(this.accounts[1], ethers.Typed.address(this.accounts[0]));
  61. expect(await this.votes.getVotes(this.accounts[0])).to.equal(
  62. this.amounts[this.accounts[0].address] + this.amounts[this.accounts[1].address],
  63. );
  64. expect(await this.votes.getVotes(this.accounts[1])).to.equal(0n);
  65. expect(await this.votes.delegates(this.accounts[0])).to.equal(this.accounts[0]);
  66. expect(await this.votes.delegates(this.accounts[1])).to.equal(this.accounts[0]);
  67. });
  68. it('cross delegates', async function () {
  69. await this.votes.delegate(this.accounts[0], ethers.Typed.address(this.accounts[1]));
  70. await this.votes.delegate(this.accounts[1], ethers.Typed.address(this.accounts[0]));
  71. expect(await this.votes.getVotes(this.accounts[0])).to.equal(this.amounts[this.accounts[1].address]);
  72. expect(await this.votes.getVotes(this.accounts[1])).to.equal(this.amounts[this.accounts[0].address]);
  73. });
  74. it('returns total amount of votes', async function () {
  75. const totalSupply = sum(...Object.values(this.amounts));
  76. expect(await this.votes.getTotalSupply()).to.equal(totalSupply);
  77. });
  78. });
  79. });
  80. }
  81. });