Skip to content

Commit

Permalink
Merge pull request #683 from liquity/zappers_coverage
Browse files Browse the repository at this point in the history
Add tests to increase coverage
  • Loading branch information
bingen authored Jan 9, 2025
2 parents 345d567 + 4245081 commit 198d08d
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 15 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/contracts-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,11 @@ jobs:
lcov --remove lcov_merged.info -o lcov_merged.info
'test/*'
'script/*'
'src/Interfaces/*'
'src/Dependencies/Ownable.sol'
'src/Zappers/Modules/Exchanges/UniswapV3/UniPriceConverter.sol'
'src/NFTMetadata/*'
'src/Types/*'
'src/MultiTroveGetter.sol'
'src/HintHelpers.sol'

# Send to coveralls
- name: Coveralls
Expand Down
7 changes: 4 additions & 3 deletions contracts/script/coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ cp lcov_foundry.info lcov_merged.info
lcov --remove lcov_merged.info -o lcov_merged.info \
'test/*' \
'script/*' \
'src/Interfaces/*' \
'src/Dependencies/Ownable.sol' \
'src/Zappers/Modules/Exchanges/UniswapV3/UniPriceConverter.sol' \
'src/NFTMetadata/*' \
'src/Types/*' \
'src/MultiTroveGetter.sol'
'src/MultiTroveGetter.sol' \
'src/HintHelpers.sol'

genhtml lcov_merged.info --output-directory coverage
28 changes: 24 additions & 4 deletions contracts/test/liquidations.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ contract LiquidationsTest is DevTestSetup {
collToken.balanceOf(address(collSurplusPool)),
collSurplusAmount,
1,
"CollSurplusPoll should have received collateral"
"CollSurplusPool should have received collateral"
);
assertEq(
collToken.balanceOf(address(collSurplusPool)),
collSurplusPool.getCollBalance(),
"CollSurplusPool balance and getter should match"
);
vm.startPrank(A);
borrowerOperations.claimCollateral();
Expand Down Expand Up @@ -194,7 +199,12 @@ contract LiquidationsTest is DevTestSetup {
);

// Check there’s no surplus
assertEq(collToken.balanceOf(address(collSurplusPool)), 0, "CollSurplusPoll should be empty");
assertEq(collToken.balanceOf(address(collSurplusPool)), 0, "CollSurplusPool should be empty");
assertEq(
collToken.balanceOf(address(collSurplusPool)),
collSurplusPool.getCollBalance(),
"CollSurplusPool balance and getter should match"
);

vm.startPrank(A);
vm.expectRevert("CollSurplusPool: No collateral available to claim");
Expand Down Expand Up @@ -284,7 +294,12 @@ contract LiquidationsTest is DevTestSetup {
"B trove coll mismatch"
);

assertEq(collToken.balanceOf(address(collSurplusPool)), 0, "CollSurplusPoll should be empty");
assertEq(collToken.balanceOf(address(collSurplusPool)), 0, "CollSurplusPool should be empty");
assertEq(
collToken.balanceOf(address(collSurplusPool)),
collSurplusPool.getCollBalance(),
"CollSurplusPool balance and getter should match"
);
}

// Offset and Redistribution
Expand Down Expand Up @@ -393,7 +408,12 @@ contract LiquidationsTest is DevTestSetup {
collToken.balanceOf(address(collSurplusPool)),
collSurplusAmount,
10,
"CollSurplusPoll should have received collateral"
"CollSurplusPool should have received collateral"
);
assertEq(
collToken.balanceOf(address(collSurplusPool)),
collSurplusPool.getCollBalance(),
"CollSurplusPool balance and getter should match"
);
vm.startPrank(A);
borrowerOperations.claimCollateral();
Expand Down
14 changes: 12 additions & 2 deletions contracts/test/liquidationsLST.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ contract LiquidationsLSTTest is DevTestSetup {
collToken.balanceOf(address(collSurplusPool)),
collSurplusAmount,
10,
"CollSurplusPoll should have received collateral"
"CollSurplusPool should have received collateral"
);
assertEq(
collToken.balanceOf(address(collSurplusPool)),
collSurplusPool.getCollBalance(),
"CollSurplusPool balance and getter should match"
);
vm.startPrank(A);
borrowerOperations.claimCollateral();
Expand Down Expand Up @@ -296,7 +301,12 @@ contract LiquidationsLSTTest is DevTestSetup {
collSurplusAmount = finalValues.collToLiquidate - collPenalty;
}
assertApproxEqAbs(
collToken.balanceOf(address(collSurplusPool)), collSurplusAmount, 1e9, "CollSurplusPoll mismatch"
collToken.balanceOf(address(collSurplusPool)), collSurplusAmount, 1e9, "CollSurplusPool mismatch"
);
assertEq(
collToken.balanceOf(address(collSurplusPool)),
collSurplusPool.getCollBalance(),
"CollSurplusPool balance and getter should match"
);
if (collSurplusAmount > 0) {
vm.startPrank(A);
Expand Down
29 changes: 26 additions & 3 deletions contracts/test/multicollateral.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ contract MulticollateralTest is DevTestSetup {
}
}

function testMultiCollateralDeployment() public view {
function testMultiCollateralDeployment() public {
// check deployment
assertEq(collateralRegistry.totalCollaterals(), NUM_COLLATERALS, "Wrong number of branches");
for (uint256 c = 0; c < NUM_COLLATERALS; c++) {
Expand All @@ -121,6 +121,11 @@ contract MulticollateralTest is DevTestSetup {
assertEq(address(collateralRegistry.getToken(c)), ZERO_ADDRESS, "Extra collateral token");
assertEq(address(collateralRegistry.getTroveManager(c)), ZERO_ADDRESS, "Extra TroveManager");
}
// reverts for invalid index
vm.expectRevert("Invalid index");
collateralRegistry.getToken(10);
vm.expectRevert("Invalid index");
collateralRegistry.getTroveManager(10);
}

struct TestValues {
Expand Down Expand Up @@ -161,8 +166,10 @@ contract MulticollateralTest is DevTestSetup {
testValues4.troveId = openMulticollateralTroveNoHints100pctWithIndex(3, A, 0, 10e18, 10000e18, 5e16);
makeMulticollateralSPDepositAndClaim(3, A, 10000e18);

// let time go by to reduce redemption rate (/16)
vm.warp(block.timestamp + 1 days);

// Check A’s final bal
// TODO: change when we switch to new gas compensation
assertEq(boldToken.balanceOf(A), 16000e18, "Wrong Bold balance before redemption");

// initial balances
Expand Down Expand Up @@ -195,11 +202,27 @@ contract MulticollateralTest is DevTestSetup {
testValues3.fee = fee * testValues3.redeemAmount / redeemAmount * DECIMAL_PRECISION / testValues3.price;
testValues4.fee = fee * testValues4.redeemAmount / redeemAmount * DECIMAL_PRECISION / testValues4.price;

// Check redemption rate
assertApproxEqAbs(
collateralRegistry.getRedemptionFeeWithDecay(redeemAmount),
redeemAmount * (INITIAL_BASE_RATE / 16 + REDEMPTION_FEE_FLOOR) / DECIMAL_PRECISION,
1e7,
"Wrong redemption fee with decay"
);

uint256 initialBoldSupply = boldToken.totalSupply();

// A redeems 1.6k
redeem(A, redeemAmount);

// Check redemption rate
assertApproxEqAbs(
collateralRegistry.getRedemptionRate(),
INITIAL_BASE_RATE / 16 + REDEMPTION_FEE_FLOOR + redeemAmount * DECIMAL_PRECISION / initialBoldSupply,
1e5,
"Wrong redemption rate");

// Check bold balance
// TODO: change when we switch to new gas compensation
assertApproxEqAbs(boldToken.balanceOf(A), 14400e18, 10, "Wrong Bold balance after redemption");

// Check collateral balances
Expand Down
144 changes: 143 additions & 1 deletion contracts/test/zapperGasComp.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,71 @@ contract ZapperGasCompTest is DevTestSetup {
assertEq(collToken.balanceOf(A), collBalanceBefore - collAmount, "Coll bal mismatch");
}

function testCanOpenTroveWithBatchManager() external {
uint256 collAmount = 10 ether;
uint256 boldAmount = 10000e18;

uint256 ethBalanceBefore = A.balance;
uint256 collBalanceBefore = collToken.balanceOf(A);

registerBatchManager(B);

IZapper.OpenTroveParams memory params = IZapper.OpenTroveParams({
owner: A,
ownerIndex: 0,
collAmount: collAmount,
boldAmount: boldAmount,
upperHint: 0,
lowerHint: 0,
annualInterestRate: 0,
batchManager: B,
maxUpfrontFee: 1000e18,
addManager: address(0),
removeManager: address(0),
receiver: address(0)
});
vm.startPrank(A);
uint256 troveId = gasCompZapper.openTroveWithRawETH{value: ETH_GAS_COMPENSATION}(params);
vm.stopPrank();

assertEq(troveNFT.ownerOf(troveId), A, "Wrong owner");
assertGt(troveId, 0, "Trove id should be set");
assertEq(troveManager.getTroveEntireColl(troveId), collAmount, "Coll mismatch");
assertGt(troveManager.getTroveEntireDebt(troveId), boldAmount, "Debt mismatch");
assertEq(boldToken.balanceOf(A), boldAmount, "BOLD bal mismatch");
assertEq(A.balance, ethBalanceBefore - ETH_GAS_COMPENSATION, "ETH bal mismatch");
assertEq(collToken.balanceOf(A), collBalanceBefore - collAmount, "Coll bal mismatch");
assertEq(borrowerOperations.interestBatchManagerOf(troveId), B, "Wrong batch manager");
(,,,,,,,, address tmBatchManagerAddress,) = troveManager.Troves(troveId);
assertEq(tmBatchManagerAddress, B, "Wrong batch manager (TM)");
}

function testCanNotOpenTroveWithBatchManagerAndInterest() external {
uint256 collAmount = 10 ether;
uint256 boldAmount = 10000e18;

registerBatchManager(B);

IZapper.OpenTroveParams memory params = IZapper.OpenTroveParams({
owner: A,
ownerIndex: 0,
collAmount: collAmount,
boldAmount: boldAmount,
upperHint: 0,
lowerHint: 0,
annualInterestRate: 5e16,
batchManager: B,
maxUpfrontFee: 1000e18,
addManager: address(0),
removeManager: address(0),
receiver: address(0)
});
vm.startPrank(A);
vm.expectRevert("GCZ: Cannot choose interest if joining a batch");
gasCompZapper.openTroveWithRawETH{value: ETH_GAS_COMPENSATION}(params);
vm.stopPrank();
}

function testCanAddColl() external {
uint256 collAmount1 = 10 ether;
uint256 boldAmount = 10000e18;
Expand Down Expand Up @@ -164,6 +229,35 @@ contract ZapperGasCompTest is DevTestSetup {
assertEq(collToken.balanceOf(A), collBalanceBefore + collAmount2, "Coll bal mismatch");
}

function testCanNotAddReceiverWithoutRemoveManager() external {
uint256 collAmount = 10 ether;
uint256 boldAmount1 = 10000e18;

IZapper.OpenTroveParams memory params = IZapper.OpenTroveParams({
owner: A,
ownerIndex: 0,
collAmount: collAmount,
boldAmount: boldAmount1,
upperHint: 0,
lowerHint: 0,
annualInterestRate: MIN_ANNUAL_INTEREST_RATE,
batchManager: address(0),
maxUpfrontFee: 1000e18,
addManager: address(0),
removeManager: address(0),
receiver: address(0)
});
vm.startPrank(A);
uint256 troveId = gasCompZapper.openTroveWithRawETH{value: ETH_GAS_COMPENSATION}(params);
vm.stopPrank();

// Try to add a receiver for the zapper without remove manager
vm.startPrank(A);
vm.expectRevert(AddRemoveManagers.EmptyManager.selector);
gasCompZapper.setRemoveManagerWithReceiver(troveId, address(0), B);
vm.stopPrank();
}

function testCanRepayBold() external {
uint256 collAmount = 10 ether;
uint256 boldAmount1 = 10000e18;
Expand Down Expand Up @@ -262,7 +356,6 @@ contract ZapperGasCompTest is DevTestSetup {
assertEq(collToken.balanceOf(B), collBalanceBeforeB, "B Coll bal mismatch");
}

// TODO: more adjustment combinations
function testCanAdjustTroveWithdrawCollAndBold() external {
uint256 collAmount1 = 10 ether;
uint256 collAmount2 = 1 ether;
Expand Down Expand Up @@ -312,6 +405,55 @@ contract ZapperGasCompTest is DevTestSetup {
assertEq(collToken.balanceOf(B), collBalanceBeforeB, "B Coll bal mismatch");
}

function testCanAdjustTroveAddCollAndWithdrawBold() external {
uint256 collAmount1 = 10 ether;
uint256 collAmount2 = 1 ether;
uint256 boldAmount1 = 10000e18;
uint256 boldAmount2 = 1000e18;

IZapper.OpenTroveParams memory params = IZapper.OpenTroveParams({
owner: A,
ownerIndex: 0,
collAmount: collAmount1,
boldAmount: boldAmount1,
upperHint: 0,
lowerHint: 0,
annualInterestRate: MIN_ANNUAL_INTEREST_RATE,
batchManager: address(0),
maxUpfrontFee: 1000e18,
addManager: address(0),
removeManager: address(0),
receiver: address(0)
});
vm.startPrank(A);
uint256 troveId = gasCompZapper.openTroveWithRawETH{value: ETH_GAS_COMPENSATION}(params);
vm.stopPrank();

uint256 boldBalanceBeforeA = boldToken.balanceOf(A);
uint256 collBalanceBeforeA = collToken.balanceOf(A);
uint256 boldBalanceBeforeB = boldToken.balanceOf(B);
uint256 collBalanceBeforeB = collToken.balanceOf(B);

// Add a remove manager for the zapper
vm.startPrank(A);
gasCompZapper.setRemoveManagerWithReceiver(troveId, B, A);
vm.stopPrank();

// Adjust (add coll and withdraw Bold)
vm.startPrank(B);
gasCompZapper.adjustTrove(troveId, collAmount2, true, boldAmount2, true, boldAmount2);
vm.stopPrank();

assertEq(troveManager.getTroveEntireColl(troveId), collAmount1 + collAmount2, "Trove coll mismatch");
assertApproxEqAbs(
troveManager.getTroveEntireDebt(troveId), boldAmount1 + boldAmount2, 2e18, "Trove debt mismatch"
);
assertEq(boldToken.balanceOf(A), boldBalanceBeforeA + boldAmount2, "A BOLD bal mismatch");
assertEq(collToken.balanceOf(A), collBalanceBeforeA, "A Coll bal mismatch");
assertEq(boldToken.balanceOf(B), boldBalanceBeforeB, "B BOLD bal mismatch");
assertEq(collToken.balanceOf(B), collBalanceBeforeB - collAmount2, "B Coll bal mismatch");
}

// TODO: more adjustment combinations
function testCanAdjustZombieTroveWithdrawCollAndBold() external {
uint256 collAmount1 = 10 ether;
Expand Down
Loading

0 comments on commit 198d08d

Please sign in to comment.