GovernorWorkflow.behavior.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. const { expectRevert, time } = require('@openzeppelin/test-helpers');
  2. async function getReceiptOrRevert (promise, error = undefined) {
  3. if (error) {
  4. await expectRevert(promise, error);
  5. return undefined;
  6. } else {
  7. const { receipt } = await promise;
  8. return receipt;
  9. }
  10. }
  11. function tryGet (obj, path = '') {
  12. try {
  13. return path.split('.').reduce((o, k) => o[k], obj);
  14. } catch (_) {
  15. return undefined;
  16. }
  17. }
  18. function runGovernorWorkflow () {
  19. beforeEach(async function () {
  20. this.receipts = {};
  21. this.descriptionHash = web3.utils.keccak256(this.settings.proposal.slice(-1).find(Boolean));
  22. this.id = await this.mock.hashProposal(...this.settings.proposal.slice(0, -1), this.descriptionHash);
  23. });
  24. it('run', async function () {
  25. // transfer tokens
  26. if (tryGet(this.settings, 'voters')) {
  27. for (const voter of this.settings.voters) {
  28. if (voter.weight) {
  29. await this.token.transfer(voter.voter, voter.weight, { from: this.settings.tokenHolder });
  30. } else if (voter.nfts) {
  31. for (const nft of voter.nfts) {
  32. await this.token.transferFrom(this.settings.tokenHolder, voter.voter, nft,
  33. { from: this.settings.tokenHolder });
  34. }
  35. }
  36. }
  37. }
  38. // propose
  39. if (this.mock.propose && tryGet(this.settings, 'steps.propose.enable') !== false) {
  40. this.receipts.propose = await getReceiptOrRevert(
  41. this.mock.methods['propose(address[],uint256[],bytes[],string)'](
  42. ...this.settings.proposal,
  43. { from: this.settings.proposer },
  44. ),
  45. tryGet(this.settings, 'steps.propose.error'),
  46. );
  47. if (tryGet(this.settings, 'steps.propose.error') === undefined) {
  48. this.deadline = await this.mock.proposalDeadline(this.id);
  49. this.snapshot = await this.mock.proposalSnapshot(this.id);
  50. }
  51. if (tryGet(this.settings, 'steps.propose.delay')) {
  52. await time.increase(tryGet(this.settings, 'steps.propose.delay'));
  53. }
  54. if (
  55. tryGet(this.settings, 'steps.propose.error') === undefined &&
  56. tryGet(this.settings, 'steps.propose.noadvance') !== true
  57. ) {
  58. await time.advanceBlockTo(this.snapshot.addn(1));
  59. }
  60. }
  61. // vote
  62. if (tryGet(this.settings, 'voters')) {
  63. this.receipts.castVote = [];
  64. for (const voter of this.settings.voters.filter(({ support }) => !!support)) {
  65. if (!voter.signature) {
  66. this.receipts.castVote.push(
  67. await getReceiptOrRevert(
  68. voter.reason
  69. ? this.mock.castVoteWithReason(this.id, voter.support, voter.reason, { from: voter.voter })
  70. : this.mock.castVote(this.id, voter.support, { from: voter.voter }),
  71. voter.error,
  72. ),
  73. );
  74. } else {
  75. const { v, r, s } = await voter.signature({ proposalId: this.id, support: voter.support });
  76. this.receipts.castVote.push(
  77. await getReceiptOrRevert(
  78. this.mock.castVoteBySig(this.id, voter.support, v, r, s),
  79. voter.error,
  80. ),
  81. );
  82. }
  83. if (tryGet(voter, 'delay')) {
  84. await time.increase(tryGet(voter, 'delay'));
  85. }
  86. }
  87. }
  88. // fast forward
  89. if (tryGet(this.settings, 'steps.wait.enable') !== false) {
  90. await time.advanceBlockTo(this.deadline.addn(1));
  91. }
  92. // queue
  93. if (this.mock.queue && tryGet(this.settings, 'steps.queue.enable') !== false) {
  94. this.receipts.queue = await getReceiptOrRevert(
  95. this.mock.methods['queue(address[],uint256[],bytes[],bytes32)'](
  96. ...this.settings.proposal.slice(0, -1),
  97. this.descriptionHash,
  98. { from: this.settings.queuer },
  99. ),
  100. tryGet(this.settings, 'steps.queue.error'),
  101. );
  102. this.eta = await this.mock.proposalEta(this.id);
  103. if (tryGet(this.settings, 'steps.queue.delay')) {
  104. await time.increase(tryGet(this.settings, 'steps.queue.delay'));
  105. }
  106. }
  107. // execute
  108. if (this.mock.execute && tryGet(this.settings, 'steps.execute.enable') !== false) {
  109. this.receipts.execute = await getReceiptOrRevert(
  110. this.mock.methods['execute(address[],uint256[],bytes[],bytes32)'](
  111. ...this.settings.proposal.slice(0, -1),
  112. this.descriptionHash,
  113. { from: this.settings.executer },
  114. ),
  115. tryGet(this.settings, 'steps.execute.error'),
  116. );
  117. if (tryGet(this.settings, 'steps.execute.delay')) {
  118. await time.increase(tryGet(this.settings, 'steps.execute.delay'));
  119. }
  120. }
  121. });
  122. }
  123. module.exports = {
  124. runGovernorWorkflow,
  125. };