Skip to content

Withdrawal Vulnerability across multiple contracts#64

Open
aniket866 wants to merge 2 commits into
StabilityNexus:mainfrom
aniket866:fix-multiple-withdrawn
Open

Withdrawal Vulnerability across multiple contracts#64
aniket866 wants to merge 2 commits into
StabilityNexus:mainfrom
aniket866:fix-multiple-withdrawn

Conversation

@aniket866

@aniket866 aniket866 commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Addressed Issues:

Fix: Withdrawal Vulnerability

Fix: Prevent Multiple Withdrawals

Problem

SafeERC20.safeTransfer with amount 0 does not revert, so repeated calls to withdraw() would silently succeed and emit false Withdrawn events.

Fix

Added require(withdrawAmount > 0, 'No funds to withdraw') in withdraw() across all three auction contracts. For VickreyAuction, the guard also checks commitFeeToTransfer since both ERC20 and ETH commit fees can be withdrawn independently.

AI Usage Disclosure:

We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact. AI slop is strongly discouraged and may lead to banning and blocking. Do not spam our repos with AI slop.

Check one of the checkboxes below:

  • This PR does not contain AI-generated code at all.
  • This PR contains AI-generated code. I have read the AI Usage Policy and this PR complies with this policy. I have tested the code locally and I am responsible for it.

I have used the following AI models and tools: TODO

Checklist

  • My PR addresses a single issue, fixes a single bug or makes a single improvement.
  • My code follows the project's code style and conventions
  • If applicable, I have made corresponding changes or additions to the documentation
  • If applicable, I have made corresponding changes or additions to tests
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contribution Guidelines
  • Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.
  • I have filled this PR template completely and carefully, and I understand that my PR may be closed without review otherwise.

@DengreSarthak

Summary by CodeRabbit

  • Bug Fixes

    • Enforced single-use withdrawals so auctioneers cannot withdraw twice.
    • Withdrawals now require non-zero payable amounts; attempts with no funds revert.
    • Vickrey withdrawals account for accumulated commit fees when present; withdrawals fail only if both available funds and commit fees are zero.
    • One auction type now requires waiting until after its deadline to withdraw.
  • Tests

    • Added withdraw-security suites covering idempotency, deadline enforcement, time advancement, and reentrancy scenarios.

@coderabbitai

coderabbitai Bot commented Mar 19, 2026

Copy link
Copy Markdown

Walkthrough

Adds deadline and non-zero preconditions to withdrawals across auction contracts, caches Vickrey commit-fee before state changes, and updates tests to assert withdrawal idempotency and require advancing time past deadlines.

Changes

Cohort / File(s) Summary
AllPayAuction Withdraw
contracts/AllPayAuction.sol
withdraw(uint256) now requires auction deadline passed via onlyAfterDeadline(auctions[auctionId].deadline) and rejects zero withdrawals (require(withdrawAmount > 0, 'No funds to withdraw')).
EnglishAuction Withdraw
contracts/EnglishAuction.sol
withdraw(uint256) now rejects zero withdrawals with require(withdrawAmount > 0, 'No funds to withdraw') (no signature changes).
VickreyAuction Withdraw
contracts/VickreyAuction.sol
Caches auction.accumulatedCommitFee into a local commitFeeToTransfer before state updates, and changes precondition to `require(withdrawAmount > 0
Withdrawal Security Tests
test/AllPayAuction.test.ts, test/EnglishAuction.test.ts, test/VickreyAuction.test.ts
Updated tests to fast-forward time and mine a block before withdrawing where needed; added Withdraw Security suites asserting first withdraw(0) succeeds and a second immediate withdraw(0) reverts with No funds to withdraw. Minor test comment added in malicious ERC20 reentrancy test.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels

Solidity Lang, Typescript Lang

Suggested reviewers

  • kaneki003
  • ceilican

Poem

🐰 I hopped to audit the tender pot,
Deadlines checked, and zeroes not.
One pull, then closed—no second try,
A tidy hop, a satisfied sigh. 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Withdrawal Vulnerability across multiple contracts' is vague and overly broad. It refers to the general type of vulnerability without clearly specifying the primary fix: preventing multiple withdrawals or enforcing deadline checks. Consider a more specific title that captures the main fix, such as 'Prevent multiple withdrawals via isWithdrawn flag' or 'Add withdraw guards and deadline enforcement'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can customize the tone of the review comments and chat replies.

Configure the tone_instructions setting to customize the tone of the review comments and chat replies. For example, you can set the tone to Act like a strict teacher, Act like a pirate and more.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
contracts/VickreyAuction.sol (1)

111-111: 🧹 Nitpick | 🔵 Trivial

Consider clarifying the error message for exact fee requirement.

The check msg.value == auction.commitFee correctly enforces exact payment (as recommended to prevent locked funds), but the error message "Insufficient commit fee" is slightly misleading when users send too much ETH. A clearer message would be "Commit fee must match exactly".

Suggested improvement
-        require(msg.value == auction.commitFee, 'Insufficient commit fee'); // require exact fee
+        require(msg.value == auction.commitFee, 'Commit fee must match exactly');

Based on learnings: "In Vickrey auction contracts, accepting arbitrary ETH amounts in commitBid while only refunding a fixed amount creates a vulnerability where attackers can lock funds forever by sending excess ETH and never revealing their bids. Always enforce exact payment amounts or track individual fees paid per bidder."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/VickreyAuction.sol` at line 111, The require in commitBid currently
reads require(msg.value == auction.commitFee, 'Insufficient commit fee'); —
change the error string to explicitly state the exact-match requirement (e.g.,
"Commit fee must match exactly") so callers who send too much ETH aren’t misled;
update the require in commitBid that compares msg.value to auction.commitFee to
use the clearer message referencing the exact fee requirement.
contracts/AllPayAuction.sol (1)

141-141: 🧹 Nitpick | 🔵 Trivial

Remove or clarify the dangling TODO comment.

This bare // TODO lacks context. Either complete the intended task, add a description of what needs to be done, or remove it if no longer applicable.

Suggested fix
-// TODO
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/AllPayAuction.sol` at line 141, There is a bare "// TODO" comment
inside the AllPayAuction contract that provides no context; either remove that
dangling comment or replace it with a meaningful note describing the exact work
to be done (e.g., intended behavior, edge-case to handle, or a reference to an
issue/PR) so future readers know the intent; locate the lonely TODO in the
AllPayAuction contract and either delete it or expand it into a specific
actionable comment referencing the affected function or state (e.g.,
constructor, placeBid, settleAuction) and the required change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@contracts/AllPayAuction.sol`:
- Line 141: There is a bare "// TODO" comment inside the AllPayAuction contract
that provides no context; either remove that dangling comment or replace it with
a meaningful note describing the exact work to be done (e.g., intended behavior,
edge-case to handle, or a reference to an issue/PR) so future readers know the
intent; locate the lonely TODO in the AllPayAuction contract and either delete
it or expand it into a specific actionable comment referencing the affected
function or state (e.g., constructor, placeBid, settleAuction) and the required
change.

In `@contracts/VickreyAuction.sol`:
- Line 111: The require in commitBid currently reads require(msg.value ==
auction.commitFee, 'Insufficient commit fee'); — change the error string to
explicitly state the exact-match requirement (e.g., "Commit fee must match
exactly") so callers who send too much ETH aren’t misled; update the require in
commitBid that compares msg.value to auction.commitFee to use the clearer
message referencing the exact fee requirement.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9fa15d45-cef8-4f08-87ed-8ee3bec0d107

📥 Commits

Reviewing files that changed from the base of the PR and between 886ea71 and c80fea5.

📒 Files selected for processing (6)
  • contracts/AllPayAuction.sol
  • contracts/EnglishAuction.sol
  • contracts/VickreyAuction.sol
  • test/AllPayAuction.test.ts
  • test/EnglishAuction.test.ts
  • test/VickreyAuction.test.ts

@DengreSarthak DengreSarthak self-assigned this Mar 20, 2026
Comment thread contracts/AllPayAuction.sol Outdated
Comment thread contracts/EnglishAuction.sol

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
contracts/AllPayAuction.sol (1)

137-137: 🧹 Nitpick | 🔵 Trivial

Remove orphaned TODO comment.

There's an incomplete // TODO comment at the end of the file with no description. Either add the intended task description or remove it.

🧹 Suggested fix
-
-// TODO
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/AllPayAuction.sol` at line 137, The file contains an orphaned "//
TODO" comment at the end of the AllPayAuction contract; remove the stray comment
or replace it with a concrete task description relevant to the AllPayAuction
contract (e.g., document known limitation or TODO for a specific function like
placeBid or settleAuction) so no ambiguous TODO remains—locate the trailing
comment after the AllPayAuction contract closing brace and delete it or replace
it with a clear, actionable comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@contracts/AllPayAuction.sol`:
- Line 137: The file contains an orphaned "// TODO" comment at the end of the
AllPayAuction contract; remove the stray comment or replace it with a concrete
task description relevant to the AllPayAuction contract (e.g., document known
limitation or TODO for a specific function like placeBid or settleAuction) so no
ambiguous TODO remains—locate the trailing comment after the AllPayAuction
contract closing brace and delete it or replace it with a clear, actionable
comment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3fa0c6a8-ebc6-47fc-81db-5901da5246f7

📥 Commits

Reviewing files that changed from the base of the PR and between c80fea5 and 6794136.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • contracts/AllPayAuction.sol
  • contracts/EnglishAuction.sol
  • contracts/VickreyAuction.sol
  • test/AllPayAuction.test.ts
  • test/EnglishAuction.test.ts
  • test/VickreyAuction.test.ts

@aniket866 aniket866 changed the title Multiple Withdrawal Vulnerability across multiple contracts Withdrawal Vulnerability across multiple contracts Mar 20, 2026
@aniket866 aniket866 requested a review from DengreSarthak March 20, 2026 18:14
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

Successfully merging this pull request may close these issues.

2 participants