28660 - [SC - Insight] pufETHsrcTimelock_setDelay - L State constant M...
pufETH/src/Timelock::_setDelay() - L256: State constant MINIMUM_DELAY is incorrectly treated as an invalid minimum delay value, as can be seen here where newDelay <= MINIMUM_DELAY is used instead of newDelay < MINIMUM_DELAY.
pufETH/src/Timelock::_setDelay() - L256: State constant MINIMUM_DELAY is incorrectly treated as an invalid minimum delay value, as can be seen here where newDelay <= MINIMUM_DELAY is used instead of newDelay < MINIMUM_DELAY.Submitted on Feb 23rd 2024 at 08:47:31 UTC by @OxSCSamurai for Boost | Puffer Finance
Report ID: #28660
Report type: Smart Contract
Report severity: Insight
Target: https://etherscan.io/address/0x3C28B7c7Ba1A1f55c9Ce66b263B33B204f2126eA#code
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
Summary:
The hardcoded constant value for timelock minimum delay is incorrectly treated as an invalid timelock delay value.
Impact in scope:
Contract fails to deliver promised returns, but doesn't lose value
In this context the promised "return" is related to the hardcoded minimum timelock delay value of
7 days.
Vulnerability Details
Buggy function:
If for any reason it's not clear yet what the bug is, let me clarify for you:
It should be clear enough from the above that the value for MINIMUM_DELAY is a VALID minimum value for the timelock delay period. Therefore the <= in newDelay <= MINIMUM_DELAY should be <, because a newDelay value of 7 days should be 100% valid, but anything LESS than 7 days is INVALID, therefore we should use newDelay < MINIMUM_DELAY instead, so that it translates to all values of newDelay where newDelay >= MINIMUM_DELAY, are all VALID values.
Impact Details
Can never change the timelock delay value to the hardcoded VALID minimum delay period of 7 days as is intended protocol functionality because the buggy function was called during constructor/deployment time, as well as called whenever they want to change the delay again after deployment.
The lowest possible value(in days) for the timelock delay is 8 days, contrary to the "promised" minimum delay of 7 days.
Investors/VCs, regulators, users, protocol DAO/governance, multisigs, external integrating projects and external devs will all expect the timelock's minimum possible delay to be 7 days(as promised by the hardcoded
MINIMUM_DELAYconstant), but this is not the case. Anyone who plans/strategizes or builds according to this expectation, will be disappointed to learn that a delay of 7 days is not possible.it seems there might have been some confusion during protocol tests and test setup and especially during deployment contract setup & testing as to "weird" behaviour when a minimum delay of 7 days was selected, so the response was to modify it to
7 days + 1in order to bypass the "weird"/revert behaviour... when in fact it was simply the bug in the internal_setDelay()function.
Recommendations:
Ensure that the hardcoded value of constant
MINIMUM_DELAYis treated correctly throughout the codebase. Here correctly means that7 daystimelock delay is still a valid value to be used in the protocol and that only anything strictly less than7 daysis invalid.Ensure that during tests setup & testing that assumptions are properly validated. It seems the intention here was to deploy with
7 daysas the initial timelock delay value, but your tests/deployment transactions reverted, due to this bug. The tests/deploy script was then modified to bypass this revert, by using a modified initial timelock delay value of7 days + 1.Correct understanding of minimum & maximum boundaries in terms of valid vs invalid values is crucial, and the implementation of this correct understanding must be consistently applied throughout the codebase.
BUGFIX:
References
https://github.com/PufferFinance/pufETH/blob/3e76d02c7b54323d347c8277327d3877bab591f5/src/Timelock.sol#L255-L262 https://github.com/PufferFinance/pufETH/blob/3e76d02c7b54323d347c8277327d3877bab591f5/src/Timelock.sol#L256
Proof of Concept
TEST1:
https://github.com/PufferFinance/pufETH/blob/3a9f943b3a9133cb2ee9bbf8c39e876c4170ead7/script/DeployPuffETH.s.sol#L95
https://github.com/PufferFinance/pufETH/blob/3a9f943b3a9133cb2ee9bbf8c39e876c4170ead7/script/DeployPuffETH.s.sol#L190
With the bug not yet fixed(newDelay <= MINIMUM_DELAY) and the protocol tests modified to use 7 days instead of (0 or 7 days + 1) as per above code snippets, we get an InvalidDelay error/revert in the test results using forge command ETH_RPC_URL=https://mainnet.infura.io/v3/YOUR_KEY forge test --contracts script/DeployPuffETH.s.sol -vvvvv:
Result: Function reverts & test fails. Timelock delay of
7 daysis not accepted.
TEST2:
Same test as above, but now with the bug fixed(newDelay < MINIMUM_DELAY) and using a valid 7 days for the timelock delay duration:
Result: Function does not revert & test passes. Timelock delay of
7 daysis accepted.
TEST3 (control test):
Same test as above with the bug fixed, but now using an invalid 6 days for the timelock delay duration:
Result: Function reverts & test fails. Timelock delay of
6 daysis not accepted.
One final control test:
TEST4 (control test):
Same test as above with the bug fixed, but now using a valid 8 days for the timelock delay duration:
Result: Function does not revert & test passes. Timelock delay of
8 daysis accepted.
Last updated
Was this helpful?