Skip to content

Commit ebc2a73

Browse files
maurelianalcueca
andauthored
feat(ctb): Add the nonce and txHash into the ScheduledTransactions struct (#18097)
* feat(ctb): Add the nonce and txHash into the ScheduledTransactions struct * chore(ctb): bump the semver on SaferSafes * feat(ctb): txHash at start of struct * semver-lock * fix ITimelockGuard to match --------- Co-authored-by: Alberto Cuesta Cañada <[email protected]>
1 parent c7ca9f4 commit ebc2a73

File tree

6 files changed

+45
-7
lines changed

6 files changed

+45
-7
lines changed

packages/contracts-bedrock/interfaces/safe/ITimelockGuard.sol

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ interface ITimelockGuard {
1212
Cancelled,
1313
Executed
1414
}
15+
1516
struct ScheduledTransaction {
17+
bytes32 txHash;
1618
uint256 executionTime;
1719
TransactionState state;
1820
ExecTransactionParams params;
21+
uint256 nonce;
1922
}
2023

2124
struct ExecTransactionParams {

packages/contracts-bedrock/snapshots/abi/SaferSafes.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,11 @@
305305
"outputs": [
306306
{
307307
"components": [
308+
{
309+
"internalType": "bytes32",
310+
"name": "txHash",
311+
"type": "bytes32"
312+
},
308313
{
309314
"internalType": "uint256",
310315
"name": "executionTime",
@@ -366,6 +371,11 @@
366371
"internalType": "struct TimelockGuard.ExecTransactionParams",
367372
"name": "params",
368373
"type": "tuple"
374+
},
375+
{
376+
"internalType": "uint256",
377+
"name": "nonce",
378+
"type": "uint256"
369379
}
370380
],
371381
"internalType": "struct TimelockGuard.ScheduledTransaction[]",
@@ -475,6 +485,11 @@
475485
"outputs": [
476486
{
477487
"components": [
488+
{
489+
"internalType": "bytes32",
490+
"name": "txHash",
491+
"type": "bytes32"
492+
},
478493
{
479494
"internalType": "uint256",
480495
"name": "executionTime",
@@ -536,6 +551,11 @@
536551
"internalType": "struct TimelockGuard.ExecTransactionParams",
537552
"name": "params",
538553
"type": "tuple"
554+
},
555+
{
556+
"internalType": "uint256",
557+
"name": "nonce",
558+
"type": "uint256"
539559
}
540560
],
541561
"internalType": "struct TimelockGuard.ScheduledTransaction",

packages/contracts-bedrock/snapshots/semver-lock.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@
208208
"sourceCodeHash": "0x7fc4789b082bc8ecd29c4c75a06058f0ff0b72f1c1028a42db6f1c35269c8865"
209209
},
210210
"src/safe/SaferSafes.sol:SaferSafes": {
211-
"initCodeHash": "0x2bee3bc687583bae2cb88edcf25ebe277b8d34b30bf9faac55ae6ec80080b8b9",
212-
"sourceCodeHash": "0xed36bffcde1bf806a9bd9b599296f4818a6c123f5277d2f3e68635cb3f22973d"
211+
"initCodeHash": "0xb4e7885e5f181e9223ecdbc4cfc8b5887fd2c22359e4c8bb4dee53f7dd193876",
212+
"sourceCodeHash": "0x31f453780466a9d3e498a7981f66c92c3d0b76e1ee80c19e374d9692bcfbd931"
213213
},
214214
"src/universal/OptimismMintableERC20.sol:OptimismMintableERC20": {
215215
"initCodeHash": "0x3c85eed0d017dca8eda6396aa842ddc12492587b061e8c756a8d32c4610a9658",

packages/contracts-bedrock/src/safe/SaferSafes.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import { ISemver } from "interfaces/universal/ISemver.sol";
2626
/// compatibility restrictions in the LivenessModule2 and TimelockGuard contracts.
2727
contract SaferSafes is LivenessModule2, TimelockGuard, ISemver {
2828
/// @notice Semantic version.
29-
/// @custom:semver 1.8.0
30-
string public constant version = "1.8.0";
29+
/// @custom:semver 1.9.0
30+
string public constant version = "1.9.0";
3131

3232
/// @notice Error for when the liveness response period is insufficient.
3333
error SaferSafes_InsufficientLivenessResponsePeriod();

packages/contracts-bedrock/src/safe/TimelockGuard.sol

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,17 @@ abstract contract TimelockGuard is BaseGuard {
8888
}
8989

9090
/// @notice Scheduled transaction
91+
/// @custom:field txHash The hash of the transaction.
9192
/// @custom:field executionTime The timestamp when execution becomes valid.
9293
/// @custom:field state The state of the transaction.
9394
/// @custom:field params The parameters of the transaction.
95+
/// @custom:field nonce The nonce of the transaction.
9496
struct ScheduledTransaction {
97+
bytes32 txHash;
9598
uint256 executionTime;
9699
TransactionState state;
97100
ExecTransactionParams params;
101+
uint256 nonce;
98102
}
99103

100104
/// @notice Parameters for the Safe's execTransaction function
@@ -564,8 +568,13 @@ abstract contract TimelockGuard is BaseGuard {
564568
uint256 executionTime = block.timestamp + _currentSafeState(_safe).timelockDelay;
565569

566570
// Schedule the transaction and add it to the pending transactions set
567-
_currentSafeState(_safe).scheduledTransactions[txHash] =
568-
ScheduledTransaction({ executionTime: executionTime, state: TransactionState.Pending, params: _params });
571+
_currentSafeState(_safe).scheduledTransactions[txHash] = ScheduledTransaction({
572+
txHash: txHash,
573+
executionTime: executionTime,
574+
state: TransactionState.Pending,
575+
params: _params,
576+
nonce: _nonce
577+
});
569578
_currentSafeState(_safe).pendingTxHashes.add(txHash);
570579

571580
emit TransactionScheduled(_safe, txHash, executionTime);

packages/contracts-bedrock/test/safe/TimelockGuard.t.sol

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,9 +505,11 @@ contract TimelockGuard_ScheduledTransaction_Test is TimelockGuard_TestInit {
505505

506506
TimelockGuard.ScheduledTransaction memory scheduledTransaction =
507507
timelockGuard.scheduledTransaction(safe, dummyTx.hash);
508+
assertEq(scheduledTransaction.txHash, dummyTx.hash);
508509
assertEq(scheduledTransaction.executionTime, INIT_TIME + TIMELOCK_DELAY);
509510
assert(scheduledTransaction.state == TimelockGuard.TransactionState.Pending);
510511
assertEq(keccak256(abi.encode(scheduledTransaction.params)), keccak256(abi.encode(dummyTx.params)));
512+
assertEq(scheduledTransaction.nonce, dummyTx.nonce);
511513
}
512514
}
513515

@@ -525,9 +527,13 @@ contract TimelockGuard_PendingTransactions_Test is TimelockGuard_TestInit {
525527
dummyTx.scheduleTransaction(timelockGuard);
526528

527529
TimelockGuard.ScheduledTransaction[] memory pendingTransactions = timelockGuard.pendingTransactions(safe);
530+
// verify the pending transaction is the one we scheduled
528531
assertEq(pendingTransactions.length, 1);
529-
// ensure the hash of the transaction params are the same
532+
assertEq(pendingTransactions[0].txHash, dummyTx.hash);
533+
assertEq(pendingTransactions[0].executionTime, INIT_TIME + TIMELOCK_DELAY);
534+
assert(pendingTransactions[0].state == TimelockGuard.TransactionState.Pending);
530535
assertEq(pendingTransactions[0].params.to, dummyTx.params.to);
536+
assertEq(pendingTransactions[0].nonce, dummyTx.nonce);
531537
assertEq(keccak256(abi.encode(pendingTransactions[0].params)), keccak256(abi.encode(dummyTx.params)));
532538
}
533539

0 commit comments

Comments
 (0)