@ -1,4 +1,4 @@
const { BN , expectEvent , expectRevert , time } = require ( '@openzeppelin/test-helpers' ) ;
const { BN , expectEvent , expectRevert } = require ( '@openzeppelin/test-helpers' ) ;
const Enums = require ( '../../helpers/enums' ) ;
const RLP = require ( 'rlp' ) ;
@ -11,24 +11,6 @@ const Timelock = artifacts.require('CompTimelock');
const Governor = artifacts . require ( 'GovernorCompatibilityBravoMock' ) ;
const CallReceiver = artifacts . require ( 'CallReceiverMock' ) ;
async function getReceiptOrRevert ( promise , error = undefined ) {
if ( error ) {
await expectRevert ( promise , error ) ;
return undefined ;
} else {
const { receipt } = await promise ;
return receipt ;
}
}
function tryGet ( obj , path = '' ) {
try {
return path . split ( '.' ) . reduce ( ( o , k ) => o [ k ] , obj ) ;
} catch ( _ ) {
return undefined ;
}
}
function makeContractAddress ( creator , nonce ) {
return web3 . utils . toChecksumAddress ( web3 . utils . sha3 ( RLP . encode ( [ creator , nonce ] ) ) . slice ( 12 ) . substring ( 14 ) ) ;
}
@ -194,6 +176,67 @@ contract('GovernorCompatibilityBravo', function (accounts) {
runGovernorWorkflow ( ) ;
} ) ;
describe ( 'with function selector and arguments' , function ( ) {
beforeEach ( async function ( ) {
this . settings = {
proposal : [
Array ( 4 ) . fill ( this . receiver . address ) ,
Array ( 4 ) . fill ( web3 . utils . toWei ( '0' ) ) ,
[
'' ,
'' ,
'mockFunctionNonPayable()' ,
'mockFunctionWithArgs(uint256,uint256)' ,
] ,
[
this . receiver . contract . methods . mockFunction ( ) . encodeABI ( ) ,
this . receiver . contract . methods . mockFunctionWithArgs ( 17 , 42 ) . encodeABI ( ) ,
'0x' ,
web3 . eth . abi . encodeParameters ( [ 'uint256' , 'uint256' ] , [ 18 , 43 ] ) ,
] ,
'<proposal description>' , // description
] ,
proposer ,
tokenHolder : owner ,
voters : [
{
voter : voter1 ,
weight : web3 . utils . toWei ( '10' ) ,
support : Enums . VoteType . For ,
} ,
] ,
steps : {
queue : { delay : 7 * 86400 } ,
} ,
} ;
} ) ;
runGovernorWorkflow ( ) ;
afterEach ( async function ( ) {
await expectEvent . inTransaction (
this . receipts . execute . transactionHash ,
this . receiver ,
'MockFunctionCalled' ,
) ;
await expectEvent . inTransaction (
this . receipts . execute . transactionHash ,
this . receiver ,
'MockFunctionCalled' ,
) ;
await expectEvent . inTransaction (
this . receipts . execute . transactionHash ,
this . receiver ,
'MockFunctionCalledWithArgs' ,
{ a : '17' , b : '42' } ,
) ;
await expectEvent . inTransaction (
this . receipts . execute . transactionHash ,
this . receiver ,
'MockFunctionCalledWithArgs' ,
{ a : '18' , b : '43' } ,
) ;
} ) ;
} ) ;
describe ( 'proposalThreshold not reached' , function ( ) {
beforeEach ( async function ( ) {
this . settings = {
@ -266,8 +309,8 @@ contract('GovernorCompatibilityBravo', function (accounts) {
proposal : [
[ this . receiver . address ] , // targets
[ web3 . utils . toWei ( '0' ) ] , // values
[ '' ] , // signatures
[ this . receiver . contract . methods . mockFunction ( ) . encodeABI ( ) ] , // calldatas
[ 'mockFunction() ' ] , // signatures
[ '0x' ] , // calldatas
'<proposal description>' , // description
] ,
proposer ,
@ -351,8 +394,8 @@ contract('GovernorCompatibilityBravo', function (accounts) {
proposer ,
targets : this . settings . proposal [ 0 ] ,
// values: this.settings.proposal[1].map(value => new BN(value)),
signatures : this . settings . proposal [ 2 ] ,
calldatas : this . settings . proposal [ 3 ] ,
signatures : this . settings . proposal [ 2 ] . map ( _ => '' ) ,
calldatas : this . settings . shortProposal [ 2 ] ,
startBlock : new BN ( this . receipts . propose . blockNumber ) . add ( this . votingDelay ) ,
endBlock : new BN ( this . receipts . propose . blockNumber ) . add ( this . votingDelay ) . add ( this . votingPeriod ) ,
description : this . settings . proposal [ 4 ] ,
@ -378,98 +421,6 @@ contract('GovernorCompatibilityBravo', function (accounts) {
'MockFunctionCalled' ,
) ;
} ) ;
it ( 'run' , async function ( ) {
// transfer tokens
if ( tryGet ( this . settings , 'voters' ) ) {
for ( const voter of this . settings . voters ) {
if ( voter . weight ) {
await this . token . transfer ( voter . voter , voter . weight , { from : this . settings . tokenHolder } ) ;
}
}
}
// propose
if ( this . mock . propose && tryGet ( this . settings , 'steps.propose.enable' ) !== false ) {
this . receipts . propose = await getReceiptOrRevert (
this . mock . methods [ 'propose(address[],uint256[],string[],bytes[],string)' ] (
... this . settings . proposal ,
{ from : this . settings . proposer } ,
) ,
tryGet ( this . settings , 'steps.propose.error' ) ,
) ;
if ( tryGet ( this . settings , 'steps.propose.error' ) === undefined ) {
this . id = this . receipts . propose . logs . find ( ( { event } ) => event === 'ProposalCreated' ) . args . proposalId ;
this . snapshot = await this . mock . proposalSnapshot ( this . id ) ;
this . deadline = await this . mock . proposalDeadline ( this . id ) ;
}
if ( tryGet ( this . settings , 'steps.propose.delay' ) ) {
await time . increase ( tryGet ( this . settings , 'steps.propose.delay' ) ) ;
}
if (
tryGet ( this . settings , 'steps.propose.error' ) === undefined &&
tryGet ( this . settings , 'steps.propose.noadvance' ) !== true
) {
await time . advanceBlockTo ( this . snapshot ) ;
}
}
// vote
if ( tryGet ( this . settings , 'voters' ) ) {
this . receipts . castVote = [ ] ;
for ( const voter of this . settings . voters ) {
if ( ! voter . signature ) {
this . receipts . castVote . push (
await getReceiptOrRevert (
this . mock . castVote ( this . id , voter . support , { from : voter . voter } ) ,
voter . error ,
) ,
) ;
} else {
const { v , r , s } = await voter . signature ( { proposalId : this . id , support : voter . support } ) ;
this . receipts . castVote . push (
await getReceiptOrRevert (
this . mock . castVoteBySig ( this . id , voter . support , v , r , s ) ,
voter . error ,
) ,
) ;
}
if ( tryGet ( voter , 'delay' ) ) {
await time . increase ( tryGet ( voter , 'delay' ) ) ;
}
}
}
// fast forward
if ( tryGet ( this . settings , 'steps.wait.enable' ) !== false ) {
await time . advanceBlockTo ( this . deadline ) ;
}
// queue
if ( this . mock . queue && tryGet ( this . settings , 'steps.queue.enable' ) !== false ) {
this . receipts . queue = await getReceiptOrRevert (
this . mock . methods [ 'queue(uint256)' ] ( this . id , { from : this . settings . queuer } ) ,
tryGet ( this . settings , 'steps.queue.error' ) ,
) ;
this . eta = await this . mock . proposalEta ( this . id ) ;
if ( tryGet ( this . settings , 'steps.queue.delay' ) ) {
await time . increase ( tryGet ( this . settings , 'steps.queue.delay' ) ) ;
}
}
// execute
if ( this . mock . execute && tryGet ( this . settings , 'steps.execute.enable' ) !== false ) {
this . receipts . execute = await getReceiptOrRevert (
this . mock . methods [ 'execute(uint256)' ] ( this . id , { from : this . settings . executer } ) ,
tryGet ( this . settings , 'steps.execute.error' ) ,
) ;
if ( tryGet ( this . settings , 'steps.execute.delay' ) ) {
await time . increase ( tryGet ( this . settings , 'steps.execute.delay' ) ) ;
}
}
} ) ;
runGovernorWorkflow ( ) ;
} ) ;
} ) ;