Platform: Code4rena
Start Date: 03/08/2023
Pot Size: $90,500 USDC
Total HM: 6
Participants: 36
Period: 7 days
Judge: 0xean
Total Solo HM: 1
Id: 273
League: ETH
Rank: 10/36
Findings: 1
Award: $1,379.86
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: ktg
Also found by: 0xTheC0der, KingNFT, MiloTruck
1379.8624 USDC - $1,379.86
The SecurityCouncilNomineeElectionGovernorTiming.electionToTimestamp(uint256 electionIndex) method basically adds 6 months * electionIndex
to the firstNominationStartDate
and returns the resulting timetamp.
The issue is that firstNominationStartDate.day
is just passed trough without changes, see L89.
As a consquence, depending on the firstNominationStartDate
, unsupported/invalid dates. which exceed the "days in month" (examples: 2030-09-31, 2030-02-29). are generated before the timestamp creation which leads to undefined behaviour in DateTimeLib.dateTimeToTimestamp(...), see also DateTimeLib.isSupportedDateTime(...).
The SecurityCouncilNomineeElectionGovernor.createElection() method is directly affected by the above issue since the creation of a new election might fail or be available too early due to relying on a timestamp whose creation was subject to undefined behaviour.
Keep in mind, that although there might be no problem, i.e. valid timestamps, with most invalid dates using the current library version, it is still undefined behaviour and one has to pay extra attention in case of using another version of the DateTimeLib
.
The following PoC implicitly modifies the existing testCreateElection
case to demonstrate the unsupported/invalid date issue.
Just apply the diff below and run the tests with forge test -vv --match-contract SecurityCouncilNomineeElectionGovernorTest
.
diff --git a/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol b/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol index c8fd056..8b5ff35 100644 --- a/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol +++ b/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol @@ -83,6 +83,16 @@ abstract contract SecurityCouncilNomineeElectionGovernorTiming is // add one to make month 1 indexed month += 1; + // PoC: add check as suggested by DateTimeLib + require(DateTimeLib.isSupportedDateTime({ + year: year, + month: month, + day: firstNominationStartDate.day, + hour: firstNominationStartDate.hour, + minute: 0, + second: 0 + }), "PoC: Unsupported election DateTime"); + return DateTimeLib.dateTimeToTimestamp({ year: year, month: month, diff --git a/test/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.t.sol b/test/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.t.sol index 9f60ba5..5dc99e0 100644 --- a/test/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.t.sol +++ b/test/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.t.sol @@ -17,7 +17,8 @@ contract SecurityCouncilNomineeElectionGovernorTest is Test { SecurityCouncilNomineeElectionGovernor.InitParams initParams = SecurityCouncilNomineeElectionGovernor.InitParams({ - firstNominationStartDate: Date({year: 2030, month: 1, day: 1, hour: 0}), + firstNominationStartDate: Date({year: 2030, month: 3, day: 31, hour: 0}), + // other: firstNominationStartDate: Date({year: 2029, month: 8, day: 29, hour: 0}), nomineeVettingDuration: 1 days, nomineeVetter: address(0x11), securityCouncilManager: ISecurityCouncilManager(address(0x22)),
VS Code, Foundry
Use the DateTimeLib.addMonths(...) method to safely add months to a given DateTime or timestamp.
Math
#0 - c4-pre-sort
2023-08-13T18:01:35Z
0xSorryNotSorry marked the issue as duplicate of #182
#1 - c4-judge
2023-08-18T23:53:10Z
0xean marked the issue as satisfactory