Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create ProposalSalt event for TimelockController #4001

Merged
merged 11 commits into from
Jan 27, 2023
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 `ProposalSalt` event to emit on operation schedule.([#4001](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4001))
JulissaDantes marked this conversation as resolved.
Show resolved Hide resolved
11 changes: 11 additions & 0 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.
frangio marked this conversation as resolved.
Show resolved Hide resolved
*/
event ProposalSalt(bytes32 indexed id, bytes32 salt);
frangio marked this conversation as resolved.
Show resolved Hide resolved

/**
* @dev Emitted when operation `id` is cancelled.
*/
Expand Down Expand Up @@ -223,6 +228,9 @@ 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 ProposalSalt(id, salt);
frangio marked this conversation as resolved.
Show resolved Hide resolved
}
}

/**
Expand Down Expand Up @@ -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 ProposalSalt(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, 'ProposalSalt', {
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, 'ProposalSalt');
});
});

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

expectEvent(receipt, 'ProposalSalt', {
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, 'ProposalSalt', {
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