Platform: Code4rena
Start Date: 24/07/2023
Pot Size: $100,000 USDC
Total HM: 18
Participants: 73
Period: 7 days
Judge: alcueca
Total Solo HM: 8
Id: 267
League: ETH
Rank: 29/73
Findings: 2
Award: $162.72
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: immeas
Also found by: 0xkazim, ABAIKUNANBAEV, T1MOH, berlin-101, bin2chen, kutugu, markus_ether
119.3545 USDC - $119.35
maybe brick the temporalGovernor
when execute grantGuardiansPause()
, it will set guardianPauseAllowed
to true
, but don't execute _unpause()
grantGuardiansPause code:
function grantGuardiansPause() external { require( msg.sender == address(this), "TemporalGovernor: Only this contract can update grant guardian pause" ); @> guardianPauseAllowed = true; lastPauseTime = 0; emit GuardianPauseGranted(block.timestamp); }
This way there may exist a path when Guardian
is held hostage, can putting the contract into a state where it cannot be updated.
Example:
Suppose there is currently a legitimate pending proposal: VAA_1.calldatas
= grantGuardiansPause()
If Guardian
is being held hostage at this point, then a malicious Guardian
could perform the following steps,putting the contract into a state where it cannot be updated.
Guardian
execute togglePause()
->
change to:
_paused = true
guardianPauseAllowed = false
Guardian
execute fastTrackProposalExecution(VAA_1)
,Since VAA_1
is legal, it will be executed successfully ->
change to:
guardianPauseAllowed = true
Guardian
execute Ownable().renounceOwnership()
->
change to:
owner = address(0)
After three steps, the state of the contract will become:
_paused = true
guardianPauseAllowed = true
owner = address(0)
These three states cause all contract methods to fail to execute
Contains:
permissionlessUnpause()
executeProposal()
fastTrackProposalExecution()
togglePause()
...
Since not disabling renounceOwnership()
is also one of the main reasons.
grantGuardiansPause()
enforce _unpause()
, and disable renounceOwnership()/transferOwnership()
function grantGuardiansPause() external { require( msg.sender == address(this), "TemporalGovernor: Only this contract can update grant guardian pause" ); guardianPauseAllowed = true; lastPauseTime = 0; + if (paused()) { + _unpause(); + } emit GuardianPauseGranted(block.timestamp); }
Context
#0 - c4-pre-sort
2023-08-03T13:29:21Z
0xSorryNotSorry marked the issue as duplicate of #232
#1 - c4-judge
2023-08-12T20:50:39Z
alcueca marked the issue as satisfactory
#2 - c4-judge
2023-08-12T20:50:43Z
alcueca marked the issue as partial-50
43.3709 USDC - $43.37
Missing payable
, making it impossible to execute proposals that need eth
.
When the proposal is executed, it takes the value
with it
The code is as follows.
function _executeProposal(bytes memory VAA, bool overrideDelay) private { ... for (uint256 i = 0; i < targets.length; i++) { address target = targets[i]; uint256 value = values[i]; bytes memory data = calldatas[i]; // Go make our call, and if it is not successful revert with the error bubbling up @> (bool success, bytes memory returnData) = target.call{value: value}( data ); /// revert on failure with error message if any require(success, string(returnData)); emit ExecutedTransaction(target, value, data); } }
However, the current contract does not have a receive()
method, and executeProposal()
and other methods does not have a modifier payable
.
This prevents the contract from receiving any eth
.
proposals that need eth
will never be successfully executed.
executeProposal()/fastTrackProposalExecution()
add payable
- function executeProposal(bytes memory VAA) public whenNotPaused { + function executeProposal(bytes memory VAA) public payable whenNotPaused { _executeProposal(VAA, false); } - function fastTrackProposalExecution(bytes memory VAA) external onlyOwner { + function fastTrackProposalExecution(bytes memory VAA) external payable onlyOwner { _executeProposal(VAA, true); /// override timestamp checks and execute }
Context
#0 - c4-pre-sort
2023-08-03T13:20:52Z
0xSorryNotSorry marked the issue as duplicate of #268
#1 - c4-judge
2023-08-12T20:35:52Z
alcueca marked the issue as satisfactory
#2 - c4-judge
2023-08-12T20:35:56Z
alcueca marked the issue as partial-50