Skip to content

Commit b25e528

Browse files
authored
Merge pull request #50 from wildcat-finance/delete-pending-batch-on-closure
Delete pending batch on closure - resolves #48
2 parents 126da71 + 5cf6624 commit b25e528

File tree

5 files changed

+61
-36
lines changed

5 files changed

+61
-36
lines changed

src/market/WildcatMarket.sol

+20
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,26 @@ contract WildcatMarket is
254254
availableLiquidity -= normalizedAmountPaid;
255255
_withdrawalData.batches[expiry] = batch;
256256
}
257+
258+
// Remove the pending batch to ensure new withdrawals are not
259+
// added to it after the market is closed.
260+
state.pendingWithdrawalExpiry = 0;
261+
emit_WithdrawalBatchExpired(
262+
expiry,
263+
batch.scaledTotalAmount,
264+
batch.scaledAmountBurned,
265+
batch.normalizedAmountPaid
266+
);
267+
emit_WithdrawalBatchClosed(expiry);
268+
269+
// If the batch expiry is at the time of the market's closure, create
270+
// a new empty batch that expires in one second to ensure new batches
271+
// aren't created after the market is closed with the same expiry.
272+
if (expiry == block.timestamp) {
273+
uint32 newExpiry = expiry + 1;
274+
emit_WithdrawalBatchCreated(newExpiry);
275+
state.pendingWithdrawalExpiry = newExpiry;
276+
}
257277
}
258278

259279
uint256 numBatches = _withdrawalData.unpaidBatches.length();

src/market/WildcatMarketWithdrawals.sol

+1-4
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,7 @@ contract WildcatMarketWithdrawals is WildcatMarketBase {
235235
uint baseCalldataSize
236236
) internal returns (uint256) {
237237
WithdrawalBatch memory batch = _withdrawalData.batches[expiry];
238-
// If the market is closed, allow withdrawal prior to expiry.
239-
if (expiry >= block.timestamp && !state.isClosed) {
240-
revert_WithdrawalBatchNotExpired();
241-
}
238+
if (expiry == state.pendingWithdrawalExpiry) revert_WithdrawalBatchNotExpired();
242239

243240
AccountWithdrawalStatus storage status = _withdrawalData.accountStatuses[expiry][
244241
accountAddress

test/helpers/ExpectedStateTracker.sol

+31-9
Original file line numberDiff line numberDiff line change
@@ -322,20 +322,21 @@ contract ExpectedStateTracker is Test, IMarketEventsAndErrors {
322322
address accountAddress,
323323
uint256 normalizedAmount
324324
) internal returns (uint32 expiry, uint104 scaledAmount) {
325-
return _trackQueueWithdrawal(
326-
state,
327-
accountAddress,
328-
normalizedAmount,
329-
registerExpectationsStandin,
330-
0
331-
);
325+
return
326+
_trackQueueWithdrawal(
327+
state,
328+
accountAddress,
329+
normalizedAmount,
330+
registerExpectationsStandin,
331+
0
332+
);
332333
}
333334

334335
function _trackQueueWithdrawal(
335336
MarketState memory state,
336337
address accountAddress,
337338
uint256 normalizedAmount,
338-
function (uint, bool) internal registerHookExpectations,
339+
function(uint, bool) internal registerHookExpectations,
339340
uint registerHookExpectationsInput
340341
) internal returns (uint32 expiry, uint104 scaledAmount) {
341342
scaledAmount = state.scaleAmount(normalizedAmount).toUint104();
@@ -476,6 +477,27 @@ contract ExpectedStateTracker is Test, IMarketEventsAndErrors {
476477
availableLiquidity -= normalizedAmountPaid;
477478
_withdrawalData.batches[expiry] = batch;
478479
}
480+
state.pendingWithdrawalExpiry = 0;
481+
if (expectEvents) {
482+
vm.expectEmit(address(market));
483+
emit WithdrawalBatchExpired(
484+
expiry,
485+
batch.scaledTotalAmount,
486+
batch.scaledAmountBurned,
487+
batch.normalizedAmountPaid
488+
);
489+
vm.expectEmit(address(market));
490+
emit WithdrawalBatchClosed(expiry);
491+
}
492+
493+
if (expiry == block.timestamp) {
494+
uint32 newExpiry = expiry + 1;
495+
if (expectEvents) {
496+
vm.expectEmit(address(market));
497+
emit WithdrawalBatchCreated(newExpiry);
498+
}
499+
state.pendingWithdrawalExpiry = newExpiry;
500+
}
479501
}
480502

481503
uint256 numBatches = _withdrawalData.unpaidBatches.length();
@@ -605,7 +627,7 @@ contract ExpectedStateTracker is Test, IMarketEventsAndErrors {
605627
return 0;
606628
}
607629
uint104 scaledAmountBurned = uint104(MathUtils.min(scaledAvailableLiquidity, scaledAmountOwed));
608-
normalizedAmountPaid = MathUtils.mulDiv(scaledAmountBurned, state.scaleFactor, RAY).toUint128();
630+
normalizedAmountPaid = MathUtils.mulDiv(scaledAmountBurned, state.scaleFactor, RAY).toUint128();
609631

610632
batch.scaledAmountBurned += scaledAmountBurned;
611633
batch.normalizedAmountPaid += normalizedAmountPaid;

test/market/WildcatMarket.t.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ contract WildcatMarketTest is BaseMarketTest {
284284
state.isClosed = true;
285285
state.reserveRatioBips = 10000;
286286
state.timeDelinquent = 0;
287+
state.pendingWithdrawalExpiry = 0;
287288
updateState(state);
288289
market.closeMarket();
289290
assertEq(market.getUnpaidBatchExpiries().length, 0);
@@ -401,7 +402,6 @@ contract WildcatMarketTest is BaseMarketTest {
401402
safeStopPrank();
402403
}
403404

404-
405405
function test_deposit_DepositBelowMinimum() external {
406406
parameters.minimumDeposit = 101;
407407
setUpContracts(false);

test/market/WildcatMarketWithdrawals.t.sol

+8-22
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ contract WithdrawalsTest is BaseMarketTest {
161161
_requestWithdrawal(alice, withdrawalAmount);
162162
}
163163

164-
165164
/* -------------------------------------------------------------------------- */
166165
/* queueFullWithdrawal() */
167166
/* -------------------------------------------------------------------------- */
@@ -200,16 +199,8 @@ contract WithdrawalsTest is BaseMarketTest {
200199
uint256 userBalance1,
201200
uint256 userBalance2
202201
) external asAccount(alice) {
203-
userBalance1 = bound(
204-
userBalance1,
205-
2,
206-
DefaultMaximumSupply / 2
207-
);
208-
userBalance2 = bound(
209-
userBalance2,
210-
2,
211-
DefaultMaximumSupply - userBalance1
212-
);
202+
userBalance1 = bound(userBalance1, 2, DefaultMaximumSupply / 2);
203+
userBalance2 = bound(userBalance2, 2, DefaultMaximumSupply - userBalance1);
213204
_deposit(alice, userBalance1);
214205
_deposit(bob, userBalance2);
215206
_requestFullWithdrawal(alice);
@@ -226,9 +217,7 @@ contract WithdrawalsTest is BaseMarketTest {
226217
);
227218
}
228219

229-
function test_queueFullWithdrawal_BurnAll(
230-
uint128 userBalance
231-
) external asAccount(alice) {
220+
function test_queueFullWithdrawal_BurnAll(uint128 userBalance) external asAccount(alice) {
232221
userBalance = uint128(bound(userBalance, 2, DefaultMaximumSupply));
233222
_deposit(alice, userBalance);
234223
_requestFullWithdrawal(alice);
@@ -280,9 +269,7 @@ contract WithdrawalsTest is BaseMarketTest {
280269
);
281270
}
282271

283-
function test_queueFullWithdrawal(
284-
uint128 userBalance
285-
) external asAccount(alice) {
272+
function test_queueFullWithdrawal(uint128 userBalance) external asAccount(alice) {
286273
userBalance = uint128(bound(userBalance, 2, DefaultMaximumSupply));
287274
_deposit(alice, userBalance);
288275
_requestFullWithdrawal(alice);
@@ -347,7 +334,7 @@ contract WithdrawalsTest is BaseMarketTest {
347334
uint32 expiry = uint32(block.timestamp + parameters.withdrawalBatchDuration);
348335
_closeMarket();
349336
fastForward(parameters.withdrawalBatchDuration + 1);
350-
_trackExecuteWithdrawal(pendingState(), expiry, alice, 1e18, false);
337+
_trackExecuteWithdrawal(pendingState(), expiry, alice, 1e18, false);
351338
vm.prank(alice);
352339
market.executeWithdrawal(alice, expiry);
353340
}
@@ -357,7 +344,7 @@ contract WithdrawalsTest is BaseMarketTest {
357344
_requestWithdrawal(alice, 1e18);
358345
uint32 expiry = uint32(block.timestamp + parameters.withdrawalBatchDuration);
359346
_closeMarket();
360-
_trackExecuteWithdrawal(pendingState(), expiry, alice, 1e18, false);
347+
_trackExecuteWithdrawal(pendingState(), expiry, alice, 1e18, false);
361348
vm.prank(alice);
362349
market.executeWithdrawal(alice, expiry);
363350
}
@@ -533,8 +520,7 @@ contract WithdrawalsTest is BaseMarketTest {
533520
market.repayAndProcessUnpaidWithdrawalBatches(0, 1);
534521

535522
uint scaledAvailableLiquidity = state.scaleAmount(feesAccruedOnWithdrawal);
536-
uint normalizedAmountPaid = MathUtils
537-
.mulDiv(scaledAvailableLiquidity, state.scaleFactor, RAY);
523+
uint normalizedAmountPaid = MathUtils.mulDiv(scaledAvailableLiquidity, state.scaleFactor, RAY);
538524
_checkBatch(expiry, 1e18, 1e18, 1e18 + normalizedAmountPaid);
539525
assertEq(market.getUnpaidBatchExpiries().length, 0);
540526
_checkState();
@@ -792,7 +778,7 @@ contract WithdrawalsTest is BaseMarketTest {
792778
_depositBorrowWithdraw(alice, 1e18, 8e17, 1e18);
793779
uint32 expiry = uint32(block.timestamp + parameters.withdrawalBatchDuration);
794780
asset.mint(address(market), 8e17);
795-
fastForward( parameters.withdrawalBatchDuration + 1);
781+
fastForward(parameters.withdrawalBatchDuration + 1);
796782
market.updateState();
797783
}
798784
}

0 commit comments

Comments
 (0)