Skip to content

Commit b67985e

Browse files
committed
docs: add docs to security monitor tests
1 parent 2669987 commit b67985e

File tree

1 file changed

+121
-11
lines changed

1 file changed

+121
-11
lines changed

packages/contracts/test/dollar/core/PoolLiquidityMonitorTest.t.sol packages/contracts/test/dollar/core/UbiquityPoolSecurityMonitorTest.sol

+121-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {MockCurveStableSwapNG} from "../../../src/dollar/mocks/MockCurveStableSw
1212
import {MockCurveTwocryptoOptimized} from "../../../src/dollar/mocks/MockCurveTwocryptoOptimized.sol";
1313
import {ERC20Ubiquity} from "../../../src/dollar/core/ERC20Ubiquity.sol";
1414

15-
contract PoolLiquidityMonitorTest is DiamondTestSetup {
15+
contract UbiquityPoolSecurityMonitorTest is DiamondTestSetup {
1616
UbiquityPoolSecurityMonitor monitor;
1717
address defenderRelayer = address(0x456);
1818
address unauthorized = address(0x123);
@@ -258,15 +258,25 @@ contract PoolLiquidityMonitorTest is DiamondTestSetup {
258258
monitor.setThresholdPercentage(newThresholdPercentage);
259259
}
260260

261+
/**
262+
* @notice Tests the dropLiquidityVertex function and ensures the correct event is emitted.
263+
* @dev Simulates a call from an account with the DEFAULT_ADMIN_ROLE to drop the liquidity vertex.
264+
* Verifies that the current collateral liquidity is set as the new liquidity vertex and the
265+
* LiquidityVertexDropped event is emitted with the correct value.
266+
*/
261267
function testDropLiquidityVertex() public {
268+
// Get the current collateral liquidity from the UbiquityPoolFacet
262269
uint256 currentCollateralLiquidity = ubiquityPoolFacet
263270
.collateralUsdBalance();
264271

272+
// Expect the LiquidityVertexDropped event to be emitted with the current collateral liquidity
265273
vm.expectEmit(true, true, true, false);
266274
emit LiquidityVertexDropped(currentCollateralLiquidity);
267275

276+
// Simulate the admin account calling the dropLiquidityVertex function
268277
vm.prank(admin);
269278
monitor.dropLiquidityVertex();
279+
// The LiquidityVertexDropped event should be emitted with the correct liquidity value
270280
}
271281

272282
function testUnauthorizedDropLiquidityVertex() public {
@@ -287,16 +297,25 @@ contract PoolLiquidityMonitorTest is DiamondTestSetup {
287297
monitor.togglePaused();
288298
}
289299

300+
/**
301+
* @notice Tests the update of liquidity vertex after the collateral liquidity is increased via minting.
302+
* @dev Simulates a user increasing liquidity by calling mintDollar and then checks if the liquidity vertex
303+
* is updated correctly when the defender relayer calls checkLiquidityVertex.
304+
*/
290305
function testCheckLiquidity() public {
306+
// Simulate the user minting dollars to increase the collateral liquidity
291307
vm.prank(user);
292308
ubiquityPoolFacet.mintDollar(1, 1e18, 0.9e18, 1e18, 0, true);
293309

310+
// Fetch the updated collateral liquidity after minting
294311
uint256 currentCollateralLiquidity = ubiquityPoolFacet
295312
.collateralUsdBalance();
296313

314+
// Expect the LiquidityVertexUpdated event to be emitted with the new liquidity value
297315
vm.expectEmit(true, true, true, false);
298316
emit LiquidityVertexUpdated(currentCollateralLiquidity);
299317

318+
// Simulate the defender relayer calling checkLiquidityVertex to update the liquidity vertex
300319
vm.prank(defenderRelayer);
301320
monitor.checkLiquidityVertex();
302321
}
@@ -308,6 +327,11 @@ contract PoolLiquidityMonitorTest is DiamondTestSetup {
308327
monitor.checkLiquidityVertex();
309328
}
310329

330+
/**
331+
* @notice Tests that the `MonitorPaused` event is emitted when the liquidity drops below the configured threshold.
332+
* @dev Simulates a scenario where the collateral liquidity drops below the threshold by redeeming dollars,
333+
* and checks if the monitor pauses and emits the `MonitorPaused` event.
334+
*/
311335
function testMonitorPausedEventEmittedAfterLiquidityDropBelowThreshold()
312336
public
313337
{
@@ -316,157 +340,223 @@ contract PoolLiquidityMonitorTest is DiamondTestSetup {
316340
vm.prank(user);
317341
ubiquityPoolFacet.redeemDollar(0, 1e18, 0, 0);
318342

343+
// Fetch the current collateral liquidity after redemption
319344
uint256 currentCollateralLiquidity = ubiquityPoolFacet
320345
.collateralUsdBalance();
321346

347+
// Expect the MonitorPaused event to be emitted with the current liquidity and percentage drop
322348
vm.expectEmit(true, true, true, false);
323-
emit MonitorPaused(currentCollateralLiquidity, 32);
349+
emit MonitorPaused(currentCollateralLiquidity, 32); // 32 represents the percentage difference
324350

351+
// Simulate the defender relayer calling checkLiquidityVertex to trigger the liquidity check
325352
vm.prank(defenderRelayer);
326353
monitor.checkLiquidityVertex();
327354
}
328355

356+
/**
357+
* @notice Tests that the `checkLiquidityVertex` function reverts with "Monitor paused" after the monitor is paused due to liquidity dropping below the threshold.
358+
* @dev Simulates a drop in collateral liquidity by redeeming dollars and ensures that once the liquidity drop exceeds the threshold,
359+
* the monitor is paused and subsequent calls to `checkLiquidityVertex` revert with the message "Monitor paused".
360+
*/
329361
function testMonitorPausedRevertAfterLiquidityDropBelowThreshold() public {
330362
curveDollarPlainPool.updateMockParams(0.99e18);
331363

364+
// Simulate a user redeeming dollars, leading to a decrease in collateral liquidity
332365
vm.prank(user);
333366
ubiquityPoolFacet.redeemDollar(0, 1e18, 0, 0);
334367

368+
// Simulate the defender relayer calling checkLiquidityVertex to trigger the monitor pause
335369
vm.prank(defenderRelayer);
336370
monitor.checkLiquidityVertex();
337371

372+
// Expect a revert with "Monitor paused" message when trying to check liquidity again
338373
vm.expectRevert("Monitor paused");
339374
vm.prank(defenderRelayer);
340375
monitor.checkLiquidityVertex();
341376
}
342377

378+
/**
379+
* @notice Tests that both the monitor and the Ubiquity Dollar are paused after a liquidity drop below the threshold.
380+
* @dev Simulates a collateral price drop and ensures that:
381+
* - The monitor is paused after the liquidity drop.
382+
* - The collateral information is no longer valid and reverts with "Invalid collateral".
383+
* - The Ubiquity Dollar token is paused after the liquidity drop.
384+
*/
343385
function testMonitorAndDollarPauseAfterLiquidityDropBelowThreshold()
344386
public
345387
{
346388
curveDollarPlainPool.updateMockParams(0.99e18);
347389

390+
// Simulate a user redeeming dollars, leading to a decrease in collateral liquidity
348391
vm.prank(user);
349392
ubiquityPoolFacet.redeemDollar(0, 1e18, 0, 0);
350393

394+
// Simulate the defender relayer calling checkLiquidityVertex to trigger the monitor pause
351395
vm.prank(defenderRelayer);
352396
monitor.checkLiquidityVertex();
353397

398+
// Expect a revert with "Invalid collateral" when trying to retrieve collateral information
354399
vm.expectRevert("Invalid collateral");
355400
ubiquityPoolFacet.collateralInformation(address(collateralToken));
356401

402+
// Assert that the monitor is paused
357403
bool monitorPaused = monitor.monitorPaused();
358-
359404
assertTrue(
360405
monitorPaused,
361406
"Monitor should be paused after liquidity drop"
362407
);
363408

409+
// Assert that the Ubiquity Dollar token is paused
364410
ERC20Ubiquity dollarToken = ERC20Ubiquity(
365411
managerFacet.dollarTokenAddress()
366412
);
367413
bool dollarIsPaused = dollarToken.paused();
368-
369414
assertTrue(
370415
dollarIsPaused,
371416
"Dollar should be paused after liquidity drop"
372417
);
373418
}
374419

375-
function testLiquidityDropDoesNotPauseMonitorBelowThreshold() public {
420+
/**
421+
* @notice Tests that the monitor is not paused when the liquidity drop does not exceed the configured threshold.
422+
* @dev Simulates a small collateral liquidity drop by redeeming dollars and ensures that:
423+
* - The monitor does not pause if the liquidity drop remains above the threshold.
424+
* - Collateral information remains valid and accessible after the liquidity drop.
425+
*/
426+
function testLiquidityDropDoesNotPauseMonitor() public {
376427
curveDollarPlainPool.updateMockParams(0.99e18);
377428

429+
// Simulate a user redeeming a small amount of dollars, causing a minor decrease in collateral liquidity
378430
vm.prank(user);
379431
ubiquityPoolFacet.redeemDollar(0, 1e17, 0, 0);
380432

433+
// Simulate the defender relayer calling checkLiquidityVertex to verify the monitor status
381434
vm.prank(defenderRelayer);
382435
monitor.checkLiquidityVertex();
383436

437+
// Ensure collateral information remains valid after the minor liquidity drop
384438
ubiquityPoolFacet.collateralInformation(address(collateralToken));
385439

440+
// Assert that the monitor is not paused after the liquidity drop
386441
bool monitorPaused = monitor.monitorPaused();
387-
388442
assertFalse(
389443
monitorPaused,
390444
"Monitor should Not be paused after liquidity drop"
391445
);
392446
}
393447

394-
function testLiquidityDropPausesMonitorWhenCollateralToggledAfterThreshold()
395-
public
396-
{
448+
/**
449+
* @notice Tests that the monitor is paused after a significant liquidity drop, even when collateral was toggled before.
450+
* @dev Simulates a scenario where collateral liquidity drops below the threshold and collateral is toggled prior to the incident.
451+
* Ensures that:
452+
* - The monitor pauses after the liquidity drop.
453+
* - Any collateral that was toggled prior to the liquidity check does not interfere with the monitor's behavior.
454+
* - Collateral information becomes inaccessible after the monitor is paused.
455+
*/
456+
function testLiquidityDropPausesMonitorWhenCollateralToggled() public {
397457
curveDollarPlainPool.updateMockParams(0.99e18);
398458

459+
// Simulate a user redeeming dollars, causing a significant liquidity drop
399460
vm.prank(user);
400461
ubiquityPoolFacet.redeemDollar(0, 1e18, 0, 0);
401462

463+
// Simulate the admin toggling the collateral state
402464
vm.prank(admin);
403465
ubiquityPoolFacet.toggleCollateral(0);
404466

467+
// Simulate the defender relayer calling checkLiquidityVertex to trigger the monitor pause
405468
vm.prank(defenderRelayer);
406469
monitor.checkLiquidityVertex();
407470

471+
// Assert that the monitor is paused after the liquidity drop
408472
bool monitorPaused = monitor.monitorPaused();
409-
410473
assertTrue(
411474
monitorPaused,
412475
"Monitor should be paused after liquidity drop, and any prior manipulation of collateral does not interfere with the ongoing incident management process."
413476
);
414477

478+
// Ensure that collateral information is inaccessible after the monitor is paused
415479
address[] memory allCollaterals = ubiquityPoolFacet.allCollaterals();
416480
for (uint256 i = 0; i < allCollaterals.length; i++) {
417481
vm.expectRevert("Invalid collateral");
418482

483+
// Simulate the user trying to access collateral information, expecting a revert
419484
vm.prank(user);
420485
ubiquityPoolFacet.collateralInformation(allCollaterals[i]);
421486
}
422487
}
423488

489+
/**
490+
* @notice Tests that the monitor is not paused when the liquidity drop does not exceed the threshold, even if collateral is toggled.
491+
* @dev Simulates a scenario where collateral liquidity drops but not enough to trigger the monitor pause.
492+
* Ensures that:
493+
* - The monitor remains active after a minor liquidity drop.
494+
* - Any collateral that was toggled prior to the liquidity check does not affect the monitor’s behavior.
495+
*/
424496
function testLiquidityDropDoesNotPauseMonitorWhenCollateralToggled()
425497
public
426498
{
427499
curveDollarPlainPool.updateMockParams(0.99e18);
428500

501+
// Simulate a user redeeming a small amount of dollars, causing a minor liquidity drop
429502
vm.prank(user);
430503
ubiquityPoolFacet.redeemDollar(0, 1e17, 0, 0);
431504

505+
// Simulate the admin toggling the collateral state
432506
vm.prank(admin);
433507
ubiquityPoolFacet.toggleCollateral(0);
434508

509+
// Simulate the defender relayer calling checkLiquidityVertex to verify the monitor status
435510
vm.prank(defenderRelayer);
436511
monitor.checkLiquidityVertex();
437512

513+
// Assert that the monitor is not paused after the minor liquidity drop
438514
bool monitorPaused = monitor.monitorPaused();
439-
440515
assertFalse(
441516
monitorPaused,
442517
"Monitor should Not be paused after liquidity drop, and any prior manipulation of collateral does not affect it"
443518
);
444519
}
445520

521+
/**
522+
* @notice Tests that `checkLiquidityVertex` reverts with "Monitor paused" when the monitor is manually paused.
523+
* @dev Simulates pausing the monitor and ensures that any subsequent calls to `checkLiquidityVertex` revert with the appropriate error message.
524+
*/
446525
function testCheckLiquidityRevertsWhenMonitorIsPaused() public {
526+
// Expect the PausedToggled event to be emitted when the monitor is paused
447527
vm.expectEmit(true, true, true, false);
448528
emit PausedToggled(true);
449529

530+
// Simulate the admin manually pausing the monitor
450531
vm.prank(admin);
451532
monitor.togglePaused();
452533

534+
// Expect a revert with "Monitor paused" when checkLiquidityVertex is called while the monitor is paused
453535
vm.expectRevert("Monitor paused");
454536

537+
// Simulate the defender relayer attempting to check liquidity while the monitor is paused
455538
vm.prank(defenderRelayer);
456539
monitor.checkLiquidityVertex();
457540
}
458541

542+
/**
543+
* @notice Tests that the `mintDollar` function reverts with "Collateral disabled" due to a liquidity drop.
544+
* @dev Simulates a liquidity drop below the threshold and ensures that collateral is disabled, causing subsequent attempts to mint dollars to fail.
545+
*/
459546
function testMintDollarRevertsWhenCollateralDisabledDueToLiquidityDrop()
460547
public
461548
{
462549
curveDollarPlainPool.updateMockParams(0.99e18);
463550

551+
// Simulate a user redeeming dollars, causing a significant liquidity drop
464552
vm.prank(user);
465553
ubiquityPoolFacet.redeemDollar(0, 1e18, 0, 0);
466554

555+
// Simulate the defender relayer calling checkLiquidityVertex to trigger the monitor pause and disable collateral
467556
vm.prank(defenderRelayer);
468557
monitor.checkLiquidityVertex();
469558

559+
// Attempt to mint dollars for each collateral, expecting a revert with "Collateral disabled"
470560
uint256 collateralCount = 3;
471561
for (uint256 i = 0; i < collateralCount; i++) {
472562
vm.expectRevert("Collateral disabled");
@@ -476,44 +566,64 @@ contract PoolLiquidityMonitorTest is DiamondTestSetup {
476566
}
477567
}
478568

569+
/**
570+
* @notice Tests that the `redeemDollar` function reverts with "Collateral disabled" due to a liquidity drop.
571+
* @dev Simulates a liquidity drop below the threshold and ensures that collateral is disabled, causing subsequent attempts to redeem dollars to fail.
572+
*/
479573
function testRedeemDollarRevertsWhenCollateralDisabledDueToLiquidityDrop()
480574
public
481575
{
482576
curveDollarPlainPool.updateMockParams(0.99e18);
483577

578+
// Simulate a user redeeming dollars, causing a significant liquidity drop
484579
vm.prank(user);
485580
ubiquityPoolFacet.redeemDollar(0, 1e18, 0, 0);
486581

582+
// Simulate the defender relayer calling checkLiquidityVertex to trigger the monitor pause and disable collateral
487583
vm.prank(defenderRelayer);
488584
monitor.checkLiquidityVertex();
489585

586+
// Expect a revert with "Collateral disabled" when trying to redeem dollars after the collateral is disabled
490587
vm.expectRevert("Collateral disabled");
588+
589+
// Simulate the user attempting to redeem dollars, which should revert due to disabled collateral
491590
vm.prank(user);
492591
ubiquityPoolFacet.redeemDollar(1, 1e18, 0, 0);
493592
}
494593

594+
/**
595+
* @notice Tests that the Ubiquity Dollar token reverts transfers with "Pausable: paused" when the token is paused due to a liquidity drop.
596+
* @dev Simulates a liquidity drop below the threshold and ensures that the Ubiquity Dollar token is paused, preventing transfers.
597+
*/
495598
function testDollarTokenRevertsOnTransferWhenPausedDueToLiquidityDrop()
496599
public
497600
{
498601
curveDollarPlainPool.updateMockParams(0.99e18);
499602

603+
// Simulate a user redeeming dollars, causing a significant liquidity drop
500604
vm.prank(user);
501605
ubiquityPoolFacet.redeemDollar(0, 1e18, 0, 0);
502606

607+
// Simulate the defender relayer calling checkLiquidityVertex to trigger the monitor pause and pause the dollar token
503608
vm.prank(defenderRelayer);
504609
monitor.checkLiquidityVertex();
505610

611+
// Assert that the Dollar token is paused after the liquidity drop
506612
bool isPaused = dollarToken.paused();
507613
assertTrue(
508614
isPaused,
509615
"Expected the Dollar token to be paused after the liquidity drop"
510616
);
511617

618+
// Get the Ubiquity Dollar token contract
512619
ERC20Ubiquity dollarToken = ERC20Ubiquity(
513620
managerFacet.dollarTokenAddress()
514621
);
515622

623+
// Expect a revert with "Pausable: paused" when trying to transfer the paused token
516624
vm.expectRevert("Pausable: paused");
625+
626+
// Simulate the user attempting to transfer the paused dollar token, which should revert
517627
vm.prank(user);
518628
dollarToken.transfer(address(0x123), 1e18);
519629
}

0 commit comments

Comments
 (0)