diff --git a/src/lib/LinkedBidsListLib.sol b/src/lib/LinkedBidsListLib.sol index d0ecbc6..950e652 100644 --- a/src/lib/LinkedBidsListLib.sol +++ b/src/lib/LinkedBidsListLib.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; +import {SafeCastLib} from "solmate/utils/SafeCastLib.sol"; + struct Bid { uint8 quantity; uint88 unitPrice; @@ -8,12 +10,19 @@ struct Bid { } struct LinkedBidsList { - mapping(address bidder => Bid bidInfo) bids; + mapping(address => Bid) bids; address highestBidder; uint256 minBidIncrease; } +/// @title A library for managing a linked list of bids. library LinkedBidsListLib { + /// @notice Inserts a new bid into the linked list. + /// @dev The bid list is ordered based on the unit price. + /// @param self The linked list to operate on. + /// @param bidder The address of the bidder. + /// @param quantity The quantity of items the bidder commits to purchase. + /// @param unitPrice The price per unit of the bid. function insert(LinkedBidsList storage self, address bidder, uint8 quantity, uint88 unitPrice) internal { require(quantity > 0, "Quantity > 0"); require(unitPrice > 0, "Price > 0"); @@ -31,13 +40,18 @@ library LinkedBidsListLib { self.bids[leftBidder].nextBidder = bidder; } + /// @notice Removes a specified quantity from a bid in the linked list. + /// @dev If the quantity to remove equals the quantity of the bid, the bid is deleted. + /// @param self The linked list to operate on. + /// @param bidder The address of the bidder whose bid to remove quantity from. + /// @param quantity The quantity to remove from the bid. function remove(LinkedBidsList storage self, address bidder, uint256 quantity) internal { require(self.highestBidder != address(0), "LinkedBidsList is empty"); require(self.bids[bidder].quantity > 0, "Bid does not exist"); - require(self.bids[bidder].quantity >= quantity, "Quantity to high"); + require(self.bids[bidder].quantity >= quantity, "Quantity too high"); if (self.bids[bidder].quantity > quantity) { - self.bids[bidder].quantity -= uint8(quantity); + self.bids[bidder].quantity -= SafeCastLib.safeCastTo8(quantity); } else { if (bidder == self.highestBidder) { // update the highestBidder to point to the nextBidder @@ -53,6 +67,10 @@ library LinkedBidsListLib { } } + /// @notice Calculates the bid to replace rightBid + /// @param self The linked list to operate on. + /// @param rightBidPrice The price of the bid to calculate the increase over. + /// @return The increase required over the right bid price. function calculateMinIncrease(LinkedBidsList storage self, uint256 rightBidPrice) internal view returns (uint256) { return (rightBidPrice * (self.minBidIncrease + 10_000)) / 10_000; } diff --git a/test/LinkedBidsList.t.sol b/test/LinkedBidsList.t.sol index 3e3ad67..740abee 100644 --- a/test/LinkedBidsList.t.sol +++ b/test/LinkedBidsList.t.sol @@ -174,4 +174,10 @@ contract LinkedListTest is Test { assertEq(list.bids[bidder3].unitPrice, 3 ether); assertEq(list.bids[bidder3].nextBidder, bidder1); } + + function test_WhenSameBidder_Insert() public {} + + function test_WhenRightBidderAddress0_Insert() public {} + + function test_RevertsWhen_MinBidIncreaseGreaterThan10000() public {} }