Skip to content

Commit

Permalink
Create ProposalSalt event for TimelockController (#4001)
Browse files Browse the repository at this point in the history
Co-authored-by: Francisco <frangio.1@gmail.com>
  • Loading branch information
JulissaDantes and frangio committed Jan 27, 2023
1 parent 5e28952 commit bc6de21
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/five-poets-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': patch
---

`TimelockController`: Add the `CallSalt` event to emit on operation schedule.
15 changes: 13 additions & 2 deletions contracts/governance/TimelockController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver
*/
event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);

/**
* @dev Emitted when new proposal is scheduled with non-zero salt.
*/
event CallSalt(bytes32 indexed id, bytes32 salt);

/**
* @dev Emitted when operation `id` is cancelled.
*/
Expand Down Expand Up @@ -206,7 +211,7 @@ contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver
/**
* @dev Schedule an operation containing a single transaction.
*
* Emits a {CallScheduled} event.
* Emits events {CallScheduled} and {CallSalt}.
*
* Requirements:
*
Expand All @@ -223,12 +228,15 @@ contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver
bytes32 id = hashOperation(target, value, data, predecessor, salt);
_schedule(id, delay);
emit CallScheduled(id, 0, target, value, data, predecessor, delay);
if (salt != bytes32(0)) {
emit CallSalt(id, salt);
}
}

/**
* @dev Schedule an operation containing a batch of transactions.
*
* Emits one {CallScheduled} event per transaction in the batch.
* Emits a {CallSalt} event and one {CallScheduled} event per transaction in the batch.
*
* Requirements:
*
Expand All @@ -250,6 +258,9 @@ contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver
for (uint256 i = 0; i < targets.length; ++i) {
emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay);
}
if (salt != bytes32(0)) {
emit CallSalt(id, salt);
}
}

/**
Expand Down
23 changes: 23 additions & 0 deletions test/governance/TimelockController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ contract('TimelockController', function (accounts) {
delay: MINDELAY,
});

expectEvent(receipt, 'CallSalt', {
id: this.operation.id,
salt: this.operation.salt,
});

const block = await web3.eth.getBlock(receipt.receipt.blockHash);

expect(await this.mock.getTimestamp(this.operation.id)).to.be.bignumber.equal(
Expand Down Expand Up @@ -219,6 +224,19 @@ contract('TimelockController', function (accounts) {
'TimelockController: insufficient delay',
);
});

it('schedule operation with salt zero', async function () {
const { receipt } = await this.mock.schedule(
this.operation.target,
this.operation.value,
this.operation.data,
this.operation.predecessor,
ZERO_BYTES32,
MINDELAY,
{ from: proposer },
);
expectEvent.notEmitted(receipt, 'CallSalt');
});
});

describe('execute', function () {
Expand Down Expand Up @@ -364,6 +382,11 @@ contract('TimelockController', function (accounts) {
predecessor: this.operation.predecessor,
delay: MINDELAY,
});

expectEvent(receipt, 'CallSalt', {
id: this.operation.id,
salt: this.operation.salt,
});
}

const block = await web3.eth.getBlock(receipt.receipt.blockHash);
Expand Down
3 changes: 3 additions & 0 deletions test/governance/extensions/GovernorTimelockControl.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ contract('GovernorTimelockControl', function (accounts) {

expectEvent(txQueue, 'ProposalQueued', { proposalId: this.proposal.id });
await expectEvent.inTransaction(txQueue.tx, this.timelock, 'CallScheduled', { id: this.proposal.timelockid });
await expectEvent.inTransaction(txQueue.tx, this.timelock, 'CallSalt', {
id: this.proposal.timelockid,
});

expectEvent(txExecute, 'ProposalExecuted', { proposalId: this.proposal.id });
await expectEvent.inTransaction(txExecute.tx, this.timelock, 'CallExecuted', { id: this.proposal.timelockid });
Expand Down

0 comments on commit bc6de21

Please sign in to comment.