This issue arises from the contract’s full pause capability, which disables both the withdraw
and repay
functions. Once the pause is active, users cannot retrieve their deposits or repay their debts, effectively locking their assets. Although pausing the contract is intended as a safeguard during emergencies, relying on a single authority to resume operations poses a centralization concern. In many well-established DeFi protocols, pause mechanisms are implemented in a way that still allows users to withdraw or repay during critical moments, preventing indefinite blockage of funds and mitigating the risk of governance abuse.
This risk is rooted in the contract’s design, where critical user actions (such as withdraw
and repay
) are restricted by the whenNotPaused
modifier. Once the contract is paused, these operations become unavailable, effectively trapping user assets and preventing repayment of outstanding debts. Because only the contract owner can unpause the system, users rely solely on that owner’s discretion to regain access to their funds. This creates a centralization problem: an indefinite pause can be imposed, blocking all key user actions until the owner decides otherwise. In more robust DeFi protocols, pause mechanisms still permit users to withdraw or repay their positions, ensuring that emergency controls do not escalate into permanent lockdowns.
An indefinite pause jeopardizes user autonomy and control over their assets, as neither withdrawals nor repayments can be executed. This circumstance not only heightens the protocol’s centralization risk but may also escalate financial losses for users, who remain unable to manage or liquidate their positions. Prolonged pauses could undermine trust in the platform, potentially causing reputational harm and driving users away in search of more flexible alternatives.
When the contract is set to the paused
state, both the withdraw
and repay
functions are disabled due to the whenNotPaused
modifier. This prevents users from withdrawing their funds or repaying their debt, leaving their assets blocked as long as the owner maintains the contract paused.
This scenario introduces a centralization risk, because the administrator can indefinitely invoke pause()
and thereby prevent users from retrieving assets or repaying loans, creating total dependency on the administrator’s decisions.
Below is a simplified excerpt highlighting the relevant section. Notice that the repay()
and withdraw()
functions include the whenNotPaused
directive, which prevents their execution while the contract is paused:
( ! ) Both withdraw
and repay
are guarded by whenNotPaused
, so once pause()
is invoked, users cannot perform these operations.
By pausing the contract, users are unable to withdraw liquidity or repay their debt. Although pause()
is meant to protect the protocol during emergencies, it poses a centralization risk by effectively blocking user funds until the contract owner decides to unpause it. Many projects implement partial or granular pauses (e.g., disallowing new deposits but still allowing withdrawals or repayments) so that users can access their funds in an emergency scenario.
Leading DeFi protocols (Aave, Compound, MakerDAO, among others) use pause mechanisms to handle emergencies without permanently blocking user access to funds. For instance, Compound can halt deposits and loans but does not prevent withdrawals or repayments; Aave introduces a per-asset “freeze,” maintaining withdrawals; while MakerDAO relies on a governance delay and an emergency shutdown to ensure fund recovery. These strategies aim to minimize centralization while providing flexible tools to safeguard the protocol in critical situations.
Aave V2 – LendingPool
code featuring whenNotPaused
and pause management (protocol-v2/contracts/protocol/lendingpool/LendingPool.sol at master · aave/protocol-v2 · GitHub) (protocol-v2/contracts/protocol/lendingpool/LendingPool.sol at master · aave/protocol-v2 · GitHub);
Aave V3 – PoolConfigurator
documentation (global and per-reserve pause) (Pool Configurator | Aave Protocol Documentation) and community discussion on freeze vs pause (Temporarily Pausing GHO Integration in Aave - General - Aave).
Compound – Code comments on pause policies (compound-protocol/contracts/ComptrollerStorage.sol at master · compound-finance/compound-protocol · GitHub) and checks in functions (mintAllowed
, borrowAllowed
) (compound-protocol/contracts/Comptroller.sol at master · compound-finance/compound-protocol · GitHub); Audit noting that only admin can unpause (Compound Comprehensive Protocol Audit - OpenZeppelin blog).
MakerDAO – Technical documentation on Emergency Shutdown (Maker Protocol Emergency Shutdown | Maker Protocol Technical Docs) (Maker Protocol Emergency Shutdown | Maker Protocol Technical Docs) and DSPause (GSM) (Pause - Detailed Documentation | Maker Protocol Technical Docs).
Uniswap – Documentation highlighting its immutability and absence of a pause function (The Uniswap Protocol | Uniswap).
The contract owner calls pause()
.
The contract automatically blocks withdraw
and repay
functions because they are protected by whenNotPaused
.
Users cannot withdraw their RTokens or repay their debts.
While the contract remains paused, users have no way to access their funds or mitigate ongoing debt positions, potentially resulting in economic damage if interest continues to accrue or if liquidity is needed urgently.
Manual Code Review was performed to thoroughly examine the contract’s logic and identify potential issues.
Introduce a partial or granular pause mechanism that preserves essential user actions. Specifically, allow users to withdraw or repay during emergency states, preventing indefinite blockage of funds and aligning with best practices in leading DeFi protocols.
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.