Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[H-01] Denial of Service (DoS) Attack on ClaimContract's Fill Function #48

Open
softstackio opened this issue Sep 9, 2024 · 0 comments

Comments

@softstackio
Copy link

Description:
The ClaimContract contains a critical vulnerability in its fill function that allows a malicious actor to permanently prevent the contract from being initialized. This vulnerability stems from an incorrect balance check that can be exploited by sending a small amount of Ether to the contract before the fill function is called.
The fill function contains the following check:

if (address(this).balance != msg.value) revert
FillErrorBalanceDoubleFill();

This check is intended to ensure that the contract is being filled for the first time. However, it fails to account for the possibility of the contract receiving Ether through other means.

Impact:

  1. Denial of Service: An attacker can permanently prevent the contract from being initialized by sending a small amount of Ether (e.g., 1 wei) to the contract address. This will cause the balance check to always fail, making it impossible to call the fill function successfully.
  2. Contract Rendered Unusable: Once this attack is executed, the entire contract becomes unusable, as the fill function is crucial for initializing the contract with the necessary balances.

Proof of Concept:

  1. Deploy the ClaimContract.
  2. Attacker sends 1 wei to the contract address.
  3. Any attempt to call fill will now fail due to the balance check.

Recommendation:
Replace the current balance check with a mechanism that doesn't rely on the contract's balance. Some options include:

  1. Use a boolean flag to track if the contract has been filled:
bool private filled;
function fill(bytes20[] memory _accounts, uint256[] memory _balances)
external payable {
   if (filled) revert FillErrorBalanceDoubleFill();
   filled = true;
   // Rest of the function...
}
  1. Check the total balance of recorded accounts instead of the contract's balance:
uint256 public totalRecordedBalance;
function fill(bytes20[] memory _accounts, uint256[] memory _balances)
external payable {
   if (totalRecordedBalance > 0) revert FillErrorBalanceDoubleFill();
   // Rest of the function...
   totalRecordedBalance = msg.value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant