Skip to content

fix: enforce strict minimum bid increment in EnglishAuction#60

Open
Rav1Chauhan wants to merge 1 commit intoStabilityNexus:mainfrom
Rav1Chauhan:fix/enforce-min-bid-increment
Open

fix: enforce strict minimum bid increment in EnglishAuction#60
Rav1Chauhan wants to merge 1 commit intoStabilityNexus:mainfrom
Rav1Chauhan:fix/enforce-min-bid-increment

Conversation

@Rav1Chauhan
Copy link

@Rav1Chauhan Rav1Chauhan commented Feb 24, 2026

Addressed Issues:

Fixes #50

Screenshots/Recordings:

N/A — Smart contract logic update (no UI changes)

Additional Notes:

This PR strengthens the bidding logic in EnglishAuction by enforcing a strict minimum bid increment.

Problem

Previously, bidders could potentially submit a bid equal to the current highest bid (depending on configuration), which could:

Enable griefing behavior

Cause unnecessary refund churn

Create gas inefficiencies

Allow spam bidding patterns

Solution

Updated the bid() function to enforce:

First bid must be ≥ minimumBid

Subsequent bids must be ≥ highestBid + minBidDelta

Added validation to ensure minBidDelta > 0

This ensures strict ascending bid enforcement and prevents equal-value takeover bids.

Impact

Prevents DOS-like bidding behavior

Eliminates equal-bid replacement

Improves economic fairness

Reduces unnecessary refund operations

Testing

Contracts compile successfully with Hardhat

No new warnings or errors generated

Checklist

  • [ x] My PR addresses a single issue, fixes a single bug or makes a single improvement.
  • [ x] 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.
  • [ x] My changes generate no new warnings or errors.
  • [ x] I have joined the Stability Nexus's Discord server and I will share a link to this PR with the project maintainers there.
  • [ x] I have read the Contribution Guidelines.
  • [x ] Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.

AI Usage Disclosure

Check one of the checkboxes below:

  • This PR does not contain AI-generated code at all.
  • [ x] This PR contains AI-generated code. I have tested the code locally and I am responsible for it.

I have used the following AI models and tools: TODO

⚠️ AI Notice - Important!

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.

Summary by CodeRabbit

  • Bug Fixes
    • Refined bid validation logic with explicit branching for initial and subsequent bids in auctions
    • Enforced minimum bid delta validation to ensure adequate bid increments between consecutive bids
    • Strengthened auction bid acceptance rules with additional validation guards

@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

Walkthrough

The bid function in EnglishAuction.sol has been restructured to enforce minimum bid increments through explicit branching, preventing equal-value bids by requiring either minimumBid for initial bids or highestBid plus minBidDelta for subsequent bids, while validating minBidDelta is non-zero.

Changes

Cohort / File(s) Summary
Bid Validation Logic
contracts/EnglishAuction.sol
Reworked bid function with explicit conditional branches for first bid (must exceed minimumBid) versus subsequent bids (must exceed highestBid + minBidDelta). Added guard ensuring minBidDelta > 0. Token transfer, refunds, state updates, deadline extension, and event emission behavior preserved.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

Solidity Lang

Poem

🐰 A hop and a bound, as bids now are found,
With minBidDelta guarding the ground,
No more griefing hops allowed here,
Each bid must leap higher, crystal clear!
The auction hops onward, fair and true,
Thanks to this update, tried and new! 🌕

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: enforcing a strict minimum bid increment in the EnglishAuction contract.
Linked Issues check ✅ Passed The PR implements all coding requirements from issue #50: enforces minBidDelta > 0, requires first bids ≥ minimumBid, and subsequent bids ≥ highestBid + minBidDelta to prevent griefing.
Out of Scope Changes check ✅ Passed All changes in EnglishAuction.sol are directly related to implementing the minimum bid increment enforcement specified in issue #50; no unrelated modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@contracts/EnglishAuction.sol`:
- Around line 93-132: Add unit tests targeting the bid(uint256 auctionId,
uint256 bidAmount) flow to cover the new invariants: create an auction fixture
and write tests that (1) submit the first bid < minimumBid and assert it
reverts, then submit first bid ≥ minimumBid and assert success and bidPlaced
emitted; (2) after a successful first bid, attempt a subsequent bid < highestBid
+ minBidDelta and assert revert; (3) attempt a subsequent bid equal to
highestBid (or equal to highestBid + minBidDelta - 1) and assert revert to
verify equal bids are rejected; and (4) set auction.minBidDelta == 0 (or
deploy/create an auction with minBidDelta zero) and assert any bid reverts with
"Invalid minBidDelta". Use the contract function name bid and the AuctionData
fields minimumBid, highestBid, minBidDelta, and the bidPlaced event to locate
assertions; ensure tests also simulate ERC20 transfers (mock
receiveERC20/sendERC20 behavior) and check deadline extension side-effects where
relevant.
- Around line 100-115: Validate auction parameters inside the createAuction
function: add require checks that auction.minimumBid > 0 and auction.minBidDelta
> 0 (or the equivalent constructor/initializer arguments) to prevent creating
auctions with minimumBid == 0 or minBidDelta == 0; keep using auction.highestBid
as the sentinel for first bid but ensure these invariants are enforced at
creation so the bid logic in the bid function (comparisons against
auction.minimumBid, auction.highestBid, and auction.minBidDelta) cannot be
bypassed or create dead auctions.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eea3b08 and e78fcb0.

📒 Files selected for processing (1)
  • contracts/EnglishAuction.sol

Comment on lines +93 to +132
function bid(uint256 auctionId, uint256 bidAmount)
external
exists(auctionId)
beforeDeadline(auctions[auctionId].deadline)
{
AuctionData storage auction = auctions[auctionId];

// First bid must meet minimumBid
if (auction.highestBid == 0) {
require(
bidAmount >= auction.minimumBid,
"Bid below minimum"
);
} else {
// Enforce strict increment
require(
bidAmount >= auction.highestBid + auction.minBidDelta,
"Bid increment too low"
);
}

require(auction.minBidDelta > 0, "Invalid minBidDelta");

receiveERC20(auction.biddingToken, msg.sender, bidAmount);

uint256 refund = auction.highestBid;
address previousWinner = auction.winner;

auction.winner = msg.sender;
auction.highestBid = bidAmount;
auction.availableFunds = bidAmount;

if (refund != 0) {
sendERC20(auction.biddingToken, previousWinner, refund);
}

auction.deadline += auction.deadlineExtension;

emit bidPlaced(auctionId, msg.sender, bidAmount);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add tests for the new bidding invariants (first‑bid minimum, strict increment, and invalid minBidDelta).

This change alters core auction correctness and griefing protection but the PR adds no tests. Please add unit tests covering: (1) first bid ≥ minimumBid, (2) subsequent bid ≥ highestBid + minBidDelta, (3) equal bids revert, and (4) minBidDelta == 0 reverts.

As per coding guidelines: "Verify that any modification to contract logic includes corresponding updates to automated tests."

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

In `@contracts/EnglishAuction.sol` around lines 93 - 132, Add unit tests targeting
the bid(uint256 auctionId, uint256 bidAmount) flow to cover the new invariants:
create an auction fixture and write tests that (1) submit the first bid <
minimumBid and assert it reverts, then submit first bid ≥ minimumBid and assert
success and bidPlaced emitted; (2) after a successful first bid, attempt a
subsequent bid < highestBid + minBidDelta and assert revert; (3) attempt a
subsequent bid equal to highestBid (or equal to highestBid + minBidDelta - 1)
and assert revert to verify equal bids are rejected; and (4) set
auction.minBidDelta == 0 (or deploy/create an auction with minBidDelta zero) and
assert any bid reverts with "Invalid minBidDelta". Use the contract function
name bid and the AuctionData fields minimumBid, highestBid, minBidDelta, and the
bidPlaced event to locate assertions; ensure tests also simulate ERC20 transfers
(mock receiveERC20/sendERC20 behavior) and check deadline extension side-effects
where relevant.

Comment on lines +100 to +115
// First bid must meet minimumBid
if (auction.highestBid == 0) {
require(
bidAmount >= auction.minimumBid,
"Bid below minimum"
);
} else {
// Enforce strict increment
require(
bidAmount >= auction.highestBid + auction.minBidDelta,
"Bid increment too low"
);
}

require(auction.minBidDelta > 0, "Invalid minBidDelta");

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate minimumBid and minBidDelta at auction creation to avoid zero‑bid loopholes and dead auctions.

With the current sentinel (highestBid == 0), a zero bid (possible if minimumBid == 0) keeps highestBid at 0, so later bids never reach the increment path. Also, minBidDelta == 0 lets auctions be created that can never accept bids. Validate both parameters in createAuction so these invalid states can’t be instantiated.

✅ Suggested fix
 function createAuction(
@@
 ) external nonEmptyString(name) nonZeroAddress(auctionedToken) nonZeroAddress(biddingToken) {
     require(duration > 0, 'Duration must be greater than zero seconds');
+    require(minimumBid > 0, "Minimum bid must be > 0");
+    require(minBidDelta > 0, "Invalid minBidDelta");
     receiveFunds(auctionType == AuctionType.NFT, auctionedToken, msg.sender, auctionedTokenIdOrAmount);

As per coding guidelines: "Review for common smart contract vulnerabilities, including but not limited to: Improper input validation."

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

In `@contracts/EnglishAuction.sol` around lines 100 - 115, Validate auction
parameters inside the createAuction function: add require checks that
auction.minimumBid > 0 and auction.minBidDelta > 0 (or the equivalent
constructor/initializer arguments) to prevent creating auctions with minimumBid
== 0 or minBidDelta == 0; keep using auction.highestBid as the sentinel for
first bid but ensure these invariants are enforced at creation so the bid logic
in the bid function (comparisons against auction.minimumBid, auction.highestBid,
and auction.minBidDelta) cannot be bypassed or create dead auctions.

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.

Auctions accept bids equal to the current highest bid — griefing possible

1 participant