Lack of payable
modifier and msg.value
transfer in Governance.execute
function will prevent governors to execute proposals that require payable function call.
Governance contract implements the core governance functionality for RAAC protocol. veRAACToken holders can create and vote on proposals. Any users can execute already passed and queued proposals via Governance.execute
function.
Governance.execute
function then will call TimelockController.executeBatch
to finalize propsal execution.
The vulnerability originates from the fact that Governance.execute
function lacks of payable
modifier.
It prevents governors execute proposals that require payable function call.
Scenario
alice creates a proposal that requires sending msg.value
to ProposeHandler
contract
voting delay (1 day) passes
alice votes for it
bob also votes for it
voting period (7 days) passes
quorum reached and the proposal voting is passed
proposal is queued to timelock controller
timelock delay (2 days) passes
proposal cannot be executed due to timelockController OutOfFund error
alice tries to send ether to timelockController
but transfer also fails because timelockController doesn't have any payable fallback
How to run POC
Follow the steps in hardhat-foundry integration tutorial
Create a file test/poc.t.sol
and run forge test poc.t.sol -vvvv
Governance cannot execute proposals that require payable function call
Manual Review, Foundry
This can be fixed by either of the following approach:
Make Governance.execute
function payable, and make it delegates msg.value
to TimelockController.executeBatch
, or
Implement a payable fallback function to TimelockController
Workarounds
There are some clever workarounds for this vulnerabilty. i.e. TimelockController can be funded before proposal execution in the following ways:
Protocol owners can use selfdestruct
to force send ether to TimelockController.
Admin can schedule an emergency action to ReturnEth
smart contract. This smart contract will do nothing but refunds all msg.value
to msg.sender
. Since TimelockController.executeEmergencyAction
has payable
modifier, admin can fund eth to TimelockController
in this way.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.