@@ -135,37 +135,18 @@ contract Auction is IAuction, Ownable2Step, Pausable, EIP712 {
135135 }
136136
137137 /// @inheritdoc IAuction
138- function cancel (bytes32 castHash , AuthData memory auth ) external whenNotPaused {
139- // Auction must be active or ended (not settled or cancelled)
140- AuctionState state = auctionState (castHash);
141- if (state != AuctionState.Active && state != AuctionState.Ended) revert AuctionNotCancellable ();
142-
143- // Verify authorization
144- if (block .timestamp > auth.deadline) revert DeadlineExpired ();
145- if (usedNonces[auth.nonce]) revert NonceAlreadyUsed ();
146-
147- // Validate signature
148- bytes32 digest = hashCancelAuthorization (castHash, auth.nonce, auth.deadline);
149- address signer = ECDSA.recover (digest, auth.signature);
150- if (! authorizers[signer]) revert Unauthorized ();
151-
152- // Mark nonce as used
153- usedNonces[auth.nonce] = true ;
154-
155- // Load refund info
156- AuctionData storage auctionData = auctions[castHash];
157- address refundAddress = auctionData.highestBidder;
158- uint96 refundBidderFid = auctionData.highestBidderFid;
159- uint256 refundAmount = auctionData.highestBid;
160-
161- // Mark as cancelled
162- auctionData.state = AuctionState.Cancelled;
138+ function batchCancel (bytes32 [] calldata castHashes , AuthData[] calldata authDatas ) external whenNotPaused {
139+ uint256 length = castHashes.length ;
140+ if (length != authDatas.length ) revert InvalidAuctionParams ();
163141
164- // Refund the highest bidder
165- usdc.transfer (refundAddress, refundAmount);
166- emit BidRefunded (castHash, refundAddress, refundAmount);
142+ for (uint256 i = 0 ; i < length; ++ i) {
143+ _cancel (castHashes[i], authDatas[i]);
144+ }
145+ }
167146
168- emit AuctionCancelled (castHash, refundAddress, refundBidderFid, signer);
147+ /// @inheritdoc IAuction
148+ function cancel (bytes32 castHash , AuthData memory auth ) external whenNotPaused {
149+ _cancel (castHash, auth);
169150 }
170151
171152 /// @inheritdoc IAuction
@@ -260,25 +241,20 @@ contract Auction is IAuction, Ownable2Step, Pausable, EIP712 {
260241 /// @inheritdoc IAuction
261242 function auctionState (bytes32 castHash ) public view returns (AuctionState) {
262243 AuctionData storage auctionData = auctions[castHash];
244+ AuctionState state = auctionData.state;
263245
264- if (auctionData.endTime == 0 ) {
265- return AuctionState.None;
266- }
267-
268- // If auction is in terminal state, return that state
269- if (
270- auctionData.state == AuctionState.Settled || auctionData.state == AuctionState.Cancelled
271- || auctionData.state == AuctionState.Recovered
272- ) {
273- return auctionData.state;
246+ if (block .timestamp > auctionData.endTime && state == AuctionState.Active) {
247+ return AuctionState.Ended;
274248 }
275249
276- // Otherwise, check if auction is active or ended based on time
277- if (block .timestamp < auctionData.endTime) {
278- return AuctionState.Active;
279- }
250+ return state;
251+ }
280252
281- return AuctionState.Ended;
253+ /// @inheritdoc IAuction
254+ function getAuction (bytes32 castHash ) external view returns (AuctionData memory ) {
255+ AuctionData memory auction = auctions[castHash];
256+ auction.state = auctionState (castHash);
257+ return auction;
282258 }
283259
284260 /// @inheritdoc IAuction
@@ -484,6 +460,39 @@ contract Auction is IAuction, Ownable2Step, Pausable, EIP712 {
484460 emit AuctionSettled (castHash, auctionData.highestBidder, auctionData.highestBidderFid, auctionData.highestBid);
485461 }
486462
463+ function _cancel (bytes32 castHash , AuthData memory auth ) internal {
464+ // Auction must be active or ended (not settled or cancelled)
465+ AuctionState state = auctionState (castHash);
466+ if (state != AuctionState.Active && state != AuctionState.Ended) revert AuctionNotCancellable ();
467+
468+ // Verify authorization
469+ if (block .timestamp > auth.deadline) revert DeadlineExpired ();
470+ if (usedNonces[auth.nonce]) revert NonceAlreadyUsed ();
471+
472+ // Validate signature
473+ bytes32 digest = hashCancelAuthorization (castHash, auth.nonce, auth.deadline);
474+ address signer = ECDSA.recover (digest, auth.signature);
475+ if (! authorizers[signer]) revert Unauthorized ();
476+
477+ // Mark nonce as used
478+ usedNonces[auth.nonce] = true ;
479+
480+ // Load refund info
481+ AuctionData storage auctionData = auctions[castHash];
482+ address refundAddress = auctionData.highestBidder;
483+ uint96 refundBidderFid = auctionData.highestBidderFid;
484+ uint256 refundAmount = auctionData.highestBid;
485+
486+ // Mark as cancelled
487+ auctionData.state = AuctionState.Cancelled;
488+
489+ // Refund the highest bidder
490+ usdc.transfer (refundAddress, refundAmount);
491+ emit BidRefunded (castHash, refundAddress, refundAmount);
492+
493+ emit AuctionCancelled (castHash, refundAddress, refundBidderFid, signer);
494+ }
495+
487496 function _permitAndTransfer (uint256 amount , PermitData memory permit ) internal {
488497 IERC20Permit (address (usdc)).permit (
489498 msg .sender , address (this ), amount, permit.deadline, permit.v, permit.r, permit.s
0 commit comments