Open c4-bot-5 opened 9 months ago
Picodes marked the issue as primary issue
othernet-global (sponsor) disputed
Allowing the confirmationWallet to continually delay the final approval is acceptable.
Doing this by mistake would be a user error, otherwise it's a suitable design
Picodes changed the severity to QA (Quality Assurance)
Lines of code
https://github.com/code-423n4/2024-01-salty/blob/main/src/ManagedWallet.sol#L59-L69
Vulnerability details
Impact
Contract
ManagedWallet.sol
states that:However, there is no check to stop
confirmationWallet
from approving an already approved proposal. This needs to be avoided as an accidental action because re-approving causes theactiveTimelock
to be pushed further into the future i.e. greater than 30 days.The expected order of events by the protocol is:
proposeWallets()
is called bymainWallet
.confirmationWallet
sends at least 0.05 ether and causes thereceive()
function to trigger. This sets theactiveTimelock
toblock.timestamp + TIMELOCK_DURATION
i.e. 30 days into the future.proposedMainWallet
callschangeWallets()
after 30 days and the new wallet addresses are set.Now consider the following flow:
proposeWallets()
is called bymainWallet
.t+0 day
, to confirm the proposal,confirmationWallet
sends at least 0.05 ether and causes thereceive()
function to trigger. This sets theactiveTimelock
toblock.timestamp + TIMELOCK_DURATION
i.e.t+30 days
.t+15 days
,confirmationWallet
inadvertently sends 0.05 ether again which causesactiveTimelock
to move tot+45 days
, unnecessarily delaying the change of wallet addresses.Hence, I recommend that an already approved proposal be not allowed to be approved again.
Note that even if we consider that the protocol wants to give the freedom of pushing
activeTimelock
again & again into the future via multiple-approvals, it is much better to do so in the following manner (already supported by the current implementation):X
days (X is any value less than 30), ifconfirmationWallet
wishes to push this further into the future, then:0 ether
to the contractThis is better because in the current design if an already approved proposal's
activeTimelock
is delayed inadvertently byconfirmationWallet
through re-approval, then there is no way to reset it to the previous value.Proof of Concept
Add the following inside
src/root_tests/ManagedWallet.t.sol
and run withCOVERAGE="yes" NETWORK="sep" forge test -vv --rpc-url https://rpc.sepolia.org/ --mt test_MultipleApprovalsCauseIncrementalDelays
:Tools used
Foundry
Recommended Mitigation Steps
Inside
receive()
make sure we are not approving an already approved proposal by checking the current value ofactiveTimelock
:Assessed type
Timing