Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

Denial of Service in `graduateAndUpgrade` Due to Blacklisted USDC Recipient

Summary

This report details a critical Denial of Service (DoS) vulnerability in the graduateAndUpgrade() function of the LevelOne.sol contract. The vulnerability arises if any teacher's address, scheduled to receive a payout, is blacklisted by the USDC token contract. When the graduateAndUpgrade function attempts to transfer USDC to such a blacklisted address using SafeERC20.safeTransfer, the underlying USDC transfer will revert. This revert will propagate, causing the entire graduateAndUpgrade transaction to fail. Consequently, no payouts (to any teacher or the principal) will occur, and the crucial contract upgrade authorization to LevelTwo.sol will also be rolled back, effectively halting the end-of-session process.

Vulnerability Details / Issue Description

  • The graduateAndUpgrade() function in LevelOne.sol iterates through a list of teachers (listOfTeachers) to - distribute USDC payouts from the bursary. The function uses OpenZeppelin's SafeERC20.safeTransfer for these operations.

// Relevant snippet from src/LevelOne.sol
function graduateAndUpgrade(address _levelTwo, bytes memory /* _data */) public onlyPrincipal {
// ... (validations, payout calculations) ...
_authorizeUpgrade(_levelTwo); // Authorizes the proxy to upgrade
for (uint256 n = 0; n < totalTeachers; n++) {
// If listOfTeachers[n] is blacklisted by USDC, this call will revert.
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
// emit Graduated(_levelTwo); // (if added)
}

The USDC token contract, managed by Circle, includes a blacklisting mechanism. If an address is blacklisted, the USDC contract's transfer (and transferFrom) functions will revert any attempted transaction involving that address.

When usdc.safeTransfer(listOfTeachers[n], payPerTeacher) is called for a blacklisted teacher:

  1. The IERC20(usdc).transfer(recipient, amount) call within safeTransfer will revert due to the recipient being blacklisted.

  2. SafeERC20.safeTransfer does not catch this type of revert from the token contract; instead, the revert propagates up the call stack.

  3. As a result, the entire graduateAndUpgrade transaction reverts. All state changes, including the _authorizeUpgrade(_levelTwo) call (which occurs before the loop in the current code) and any successful payouts to prior teachers in the loop, are rolled back.
    This means a single blacklisted teacher address can prevent all other teachers and the principal from receiving their payouts and block the contract upgrade process.

Proof Of Concept / Scenario

  1. Setup:

  • The LevelOne.sol contract is initialized and a session is active.

  • Several teachers are added to listOfTeachers. One of these teachers, say teacher_blacklisted, has their address blacklisted by the USDC token contract.
    The bursary has accumulated sufficient USDC.

  1. Execution:

  • The principal calls graduateAndUpgrade(levelTwoAddress, "").

  • The function proceeds, and _authorizeUpgrade(levelTwoAddress) is executed.

  • The payout loop begins.

  • If teacher_blacklisted is encountered in the loop, the usdc.safeTransfer(teacher_blacklisted, payPerTeacher) call is made.

  1. Outcome:

  • The USDC contract's transfer to teacher_blacklisted reverts.

  • The safeTransfer call reverts.

  • The entire graduateAndUpgrade transaction reverts.

  • No payouts are made to any teacher or the principal.

  • The state change from _authorizeUpgrade is rolled back, so the contract is not authorized for an upgrade to LevelTwo.sol.

  • The end-of-session process is effectively blocked.

Impact

The impact of this vulnerability is High:

  • Denial of Service for Core Functionality: The graduateAndUpgrade function, critical for concluding a session, distributing funds, and enabling contract upgrades, becomes unusable if even one teacher in the payout list is blacklisted by USDC.

  • Funds Locked (Effectively): While the USDC tokens remain in the contract, they cannot be distributed as intended through this function.

  • Blocked Contract Upgrades: The inability to successfully execute graduateAndUpgrade prevents the UUPS upgrade mechanism - from being authorized, halting the planned evolution of the contract to LevelTwo.sol.

  • Operational Disruption: The entire Hawk High session lifecycle is disrupted, affecting all stakeholders (teachers, principal, and indirectly students awaiting system progression).

Tools Used

Manual Code Review

Recommendations

To mitigate this DoS vulnerability, the contract should be modified to handle potential failures in individual token transfers more gracefully, ensuring that a single failed transfer does not halt the entire process.

Implement try/catch for Individual Payouts (Recommended Direct Mitigation): Wrap each usdc.safeTransfer call within the loop in a try/catch block. If a transfer fails (e.g., due to a blacklisted address), the catch block can handle the error, perhaps by emitting an event indicating the failed payout, and then allow the loop to continue to the next teacher.

  • Pros: Allows other teachers and the principal to be paid, and the upgrade can be authorized.

  • Cons: The blacklisted teacher will not receive their payment via this transaction. The contract must have a clear policy or mechanism for handling these unpaid funds (e.g., they remain in the bursary, or a separate administrative function is needed for recovery).

Updates

Lead Judging Commences

yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.