Skip to content

Commit

Permalink
ci: add coverage back
Browse files Browse the repository at this point in the history
  • Loading branch information
lucas-manuel committed Jul 4, 2024
1 parent db667d1 commit 57bacf6
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 88 deletions.
86 changes: 43 additions & 43 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,51 +37,51 @@ jobs:
BASE_RPC_URL: ${{secrets.BASE_RPC_URL}}
run: FOUNDRY_PROFILE=pr forge test -vv --show-progress

# coverage:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

# - name: Install Foundry
# uses: foundry-rs/foundry-toolchain@v1
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

# - name: Run coverage
# env:
# MAINNET_RPC_URL: ${{secrets.MAINNET_RPC_URL}}
# OPTIMISM_RPC_URL: ${{secrets.OPTIMISM_RPC_URL}}
# ARBITRUM_ONE_RPC_URL: ${{secrets.ARBITRUM_ONE_RPC_URL}}
# ARBITRUM_NOVA_RPC_URL: ${{secrets.ARBITRUM_NOVA_RPC_URL}}
# GNOSIS_CHAIN_RPC_URL: ${{secrets.GNOSIS_CHAIN_RPC_URL}}
# BASE_RPC_URL: ${{secrets.BASE_RPC_URL}}
# run: forge coverage --report summary --report lcov
- name: Run coverage
env:
MAINNET_RPC_URL: ${{secrets.MAINNET_RPC_URL}}
OPTIMISM_RPC_URL: ${{secrets.OPTIMISM_RPC_URL}}
ARBITRUM_ONE_RPC_URL: ${{secrets.ARBITRUM_ONE_RPC_URL}}
ARBITRUM_NOVA_RPC_URL: ${{secrets.ARBITRUM_NOVA_RPC_URL}}
GNOSIS_CHAIN_RPC_URL: ${{secrets.GNOSIS_CHAIN_RPC_URL}}
BASE_RPC_URL: ${{secrets.BASE_RPC_URL}}
run: forge coverage --report summary --report lcov

# # To ignore coverage for certain directories modify the paths in this step as needed. The
# # below default ignores coverage results for the test and script directories. Alternatively,
# # to include coverage in all directories, comment out this step. Note that because this
# # filtering applies to the lcov file, the summary table generated in the previous step will
# # still include all files and directories.
# # The `--rc lcov_branch_coverage=1` part keeps branch info in the filtered report, since lcov
# # defaults to removing branch info.
# - name: Filter directories
# run: |
# sudo apt update && sudo apt install -y lcov
# lcov --remove lcov.info 'test/*' 'script/*' --output-file lcov.info --rc lcov_branch_coverage=1
# To ignore coverage for certain directories modify the paths in this step as needed. The
# below default ignores coverage results for the test and script directories. Alternatively,
# to include coverage in all directories, comment out this step. Note that because this
# filtering applies to the lcov file, the summary table generated in the previous step will
# still include all files and directories.
# The `--rc lcov_branch_coverage=1` part keeps branch info in the filtered report, since lcov
# defaults to removing branch info.
- name: Filter directories
run: |
sudo apt update && sudo apt install -y lcov
lcov --remove lcov.info 'test/*' 'script/*' --output-file lcov.info --rc lcov_branch_coverage=1
# # This step posts a detailed coverage report as a comment and deletes previous comments on
# # each push. The below step is used to fail coverage if the specified coverage threshold is
# # not met. The below step can post a comment (when it's `github-token` is specified) but it's
# # not as useful, and this action cannot fail CI based on a minimum coverage threshold, which
# # is why we use both in this way.
# - name: Post coverage report
# if: github.event_name == 'pull_request' # This action fails when ran outside of a pull request.
# uses: romeovs/[email protected]
# with:
# delete-old-comments: true
# lcov-file: ./lcov.info
# github-token: ${{ secrets.GITHUB_TOKEN }} # Adds a coverage summary comment to the PR.
# This step posts a detailed coverage report as a comment and deletes previous comments on
# each push. The below step is used to fail coverage if the specified coverage threshold is
# not met. The below step can post a comment (when it's `github-token` is specified) but it's
# not as useful, and this action cannot fail CI based on a minimum coverage threshold, which
# is why we use both in this way.
- name: Post coverage report
if: github.event_name == 'pull_request' # This action fails when ran outside of a pull request.
uses: romeovs/[email protected]
with:
delete-old-comments: true
lcov-file: ./lcov.info
github-token: ${{ secrets.GITHUB_TOKEN }} # Adds a coverage summary comment to the PR.

# - name: Verify minimum coverage
# uses: zgosalvez/github-actions-report-lcov@v2
# with:
# coverage-files: ./lcov.info
# minimum-coverage: 90 # Set coverage threshold.
- name: Verify minimum coverage
uses: zgosalvez/github-actions-report-lcov@v2
with:
coverage-files: ./lcov.info
minimum-coverage: 100 # Set coverage threshold.
102 changes: 57 additions & 45 deletions test/unit/Withdraw.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,14 @@ contract PSMWithdrawTests is PSMTestBase {
);
}

struct WithdrawFuzzTestVars {
uint256 totalUsdc;
uint256 totalValue;
uint256 expectedWithdrawnAmount1;
uint256 expectedWithdrawnAmount2;
uint256 expectedWithdrawnAmount3;
}

// NOTE: For `assertApproxEqAbs` assertions, a difference calculation is used here instead of comparing
// the two values because this approach inherently asserts that the shares remaining are lower than the
// theoretical value, proving the PSM rounds against the user.
Expand All @@ -309,121 +317,120 @@ contract PSMWithdrawTests is PSMTestBase {
_deposit(address(usdc), user2, depositAmount2);
_deposit(address(sDai), user2, depositAmount3);

uint256 totalUsdc = depositAmount1 + depositAmount2;
uint256 totalValue = totalUsdc * 1e12 + depositAmount3 * 125/100;
WithdrawFuzzTestVars memory vars;

vars.totalUsdc = depositAmount1 + depositAmount2;
vars.totalValue = vars.totalUsdc * 1e12 + depositAmount3 * 125/100;

assertEq(usdc.balanceOf(user1), 0);
assertEq(usdc.balanceOf(receiver1), 0);
assertEq(usdc.balanceOf(address(psm)), totalUsdc);
assertEq(usdc.balanceOf(address(psm)), vars.totalUsdc);

assertEq(psm.shares(user1), depositAmount1 * 1e12);
assertEq(psm.totalShares(), totalValue);
assertEq(psm.totalShares(), vars.totalValue);

uint256 expectedWithdrawnAmount1
= _getExpectedWithdrawnAmount(usdc, user1, withdrawAmount1);
vars.expectedWithdrawnAmount1 = _getExpectedWithdrawnAmount(usdc, user1, withdrawAmount1);

vm.prank(user1);
uint256 amount = psm.withdraw(address(usdc), receiver1, withdrawAmount1);

assertEq(amount, expectedWithdrawnAmount1);
assertEq(amount, vars.expectedWithdrawnAmount1);

_checkPsmInvariant();

assertEq(
usdc.balanceOf(receiver1) * 1e12 + psm.getPsmTotalValue(),
totalValue
vars.totalValue
);

// NOTE: User 1 doesn't need a tolerance because their shares are 1e6 precision because they only
// deposited USDC. User 2 has a tolerance because they deposited sDAI which has 1e18 precision
// so there is a chance that the rounding will be off by up to 1e12.
assertEq(usdc.balanceOf(user1), 0);
assertEq(usdc.balanceOf(receiver1), expectedWithdrawnAmount1);
assertEq(usdc.balanceOf(receiver1), vars.expectedWithdrawnAmount1);
assertEq(usdc.balanceOf(user2), 0);
assertEq(usdc.balanceOf(receiver2), 0);
assertEq(usdc.balanceOf(address(psm)), totalUsdc - expectedWithdrawnAmount1);
assertEq(usdc.balanceOf(address(psm)), vars.totalUsdc - vars.expectedWithdrawnAmount1);

assertEq(psm.shares(user1), (depositAmount1 - expectedWithdrawnAmount1) * 1e12);
assertEq(psm.shares(user1), (depositAmount1 - vars.expectedWithdrawnAmount1) * 1e12);
assertEq(psm.shares(user2), depositAmount2 * 1e12 + depositAmount3 * 125/100); // Includes sDAI deposit
assertEq(psm.totalShares(), totalValue - expectedWithdrawnAmount1 * 1e12);
assertEq(psm.totalShares(), vars.totalValue - vars.expectedWithdrawnAmount1 * 1e12);

uint256 expectedWithdrawnAmount2
= _getExpectedWithdrawnAmount(usdc, user2, withdrawAmount2);
vars.expectedWithdrawnAmount2 = _getExpectedWithdrawnAmount(usdc, user2, withdrawAmount2);

vm.prank(user2);
amount = psm.withdraw(address(usdc), receiver2, withdrawAmount2);

assertEq(amount, expectedWithdrawnAmount2);
assertEq(amount, vars.expectedWithdrawnAmount2);

_checkPsmInvariant();

assertEq(
(usdc.balanceOf(receiver1) + usdc.balanceOf(receiver2)) * 1e12 + psm.getPsmTotalValue(),
totalValue
vars.totalValue
);

assertEq(usdc.balanceOf(user1), 0);
assertEq(usdc.balanceOf(receiver1), expectedWithdrawnAmount1);
assertEq(usdc.balanceOf(receiver1), vars.expectedWithdrawnAmount1);
assertEq(usdc.balanceOf(user2), 0);
assertEq(usdc.balanceOf(receiver2), expectedWithdrawnAmount2);
assertEq(usdc.balanceOf(address(psm)), totalUsdc - (expectedWithdrawnAmount1 + expectedWithdrawnAmount2));
assertEq(usdc.balanceOf(receiver2), vars.expectedWithdrawnAmount2);
assertEq(usdc.balanceOf(address(psm)), vars.totalUsdc - (vars.expectedWithdrawnAmount1 + vars.expectedWithdrawnAmount2));

assertEq(sDai.balanceOf(user2), 0);
assertEq(sDai.balanceOf(receiver2), 0);
assertEq(sDai.balanceOf(address(psm)), depositAmount3);

assertEq(psm.shares(user1), (depositAmount1 - expectedWithdrawnAmount1) * 1e12);
assertEq(psm.shares(user1), (depositAmount1 - vars.expectedWithdrawnAmount1) * 1e12);

assertApproxEqAbs(
((depositAmount2 * 1e12) + (depositAmount3 * 125/100) - (expectedWithdrawnAmount2 * 1e12)) - psm.shares(user2),
((depositAmount2 * 1e12) + (depositAmount3 * 125/100) - (vars.expectedWithdrawnAmount2 * 1e12)) - psm.shares(user2),
0,
usdcShareTolerance
);

assertApproxEqAbs(
(totalValue - (expectedWithdrawnAmount1 + expectedWithdrawnAmount2) * 1e12) - psm.totalShares(),
(vars.totalValue - (vars.expectedWithdrawnAmount1 + vars.expectedWithdrawnAmount2) * 1e12) - psm.totalShares(),
0,
usdcShareTolerance
);

uint256 expectedWithdrawnAmount3
= _getExpectedWithdrawnAmount(sDai, user2, withdrawAmount3);
vars.expectedWithdrawnAmount3 = _getExpectedWithdrawnAmount(sDai, user2, withdrawAmount3);

vm.prank(user2);
amount = psm.withdraw(address(sDai), receiver2, withdrawAmount3);

assertApproxEqAbs(amount, expectedWithdrawnAmount3, 1);
assertApproxEqAbs(amount, vars.expectedWithdrawnAmount3, 1);

_checkPsmInvariant();

assertApproxEqAbs(
(usdc.balanceOf(receiver1) + usdc.balanceOf(receiver2)) * 1e12
+ (sDai.balanceOf(receiver2) * rateProvider.getConversionRate() / 1e27)
+ psm.getPsmTotalValue(),
totalValue,
vars.totalValue,
1
);

assertEq(usdc.balanceOf(user1), 0);
assertEq(usdc.balanceOf(receiver1), expectedWithdrawnAmount1);
assertEq(usdc.balanceOf(receiver1), vars.expectedWithdrawnAmount1);
assertEq(usdc.balanceOf(user2), 0);
assertEq(usdc.balanceOf(receiver2), expectedWithdrawnAmount2);
assertEq(usdc.balanceOf(address(psm)), totalUsdc - (expectedWithdrawnAmount1 + expectedWithdrawnAmount2));
assertEq(usdc.balanceOf(receiver2), vars.expectedWithdrawnAmount2);
assertEq(usdc.balanceOf(address(psm)), vars.totalUsdc - (vars.expectedWithdrawnAmount1 + vars.expectedWithdrawnAmount2));

assertApproxEqAbs(sDai.balanceOf(user2), 0, 0);
assertApproxEqAbs(sDai.balanceOf(receiver2), expectedWithdrawnAmount3, 1);
assertApproxEqAbs(sDai.balanceOf(address(psm)), depositAmount3 - expectedWithdrawnAmount3, 1);
assertApproxEqAbs(sDai.balanceOf(receiver2), vars.expectedWithdrawnAmount3, 1);
assertApproxEqAbs(sDai.balanceOf(address(psm)), depositAmount3 - vars.expectedWithdrawnAmount3, 1);

assertEq(psm.shares(user1), (depositAmount1 - expectedWithdrawnAmount1) * 1e12);
assertEq(psm.shares(user1), (depositAmount1 - vars.expectedWithdrawnAmount1) * 1e12);

assertApproxEqAbs(
((depositAmount2 * 1e12) + (depositAmount3 * 125/100) - (expectedWithdrawnAmount2 * 1e12) - (expectedWithdrawnAmount3 * 125/100)) - psm.shares(user2),
((depositAmount2 * 1e12) + (depositAmount3 * 125/100) - (vars.expectedWithdrawnAmount2 * 1e12) - (vars.expectedWithdrawnAmount3 * 125/100)) - psm.shares(user2),
0,
usdcShareTolerance + 1 // 1 is added to the tolerance because of rounding error in sDAI calculations
);

assertApproxEqAbs(
totalValue - (expectedWithdrawnAmount1 + expectedWithdrawnAmount2) * 1e12 - (expectedWithdrawnAmount3 * 125/100) - psm.totalShares(),
vars.totalValue - (vars.expectedWithdrawnAmount1 + vars.expectedWithdrawnAmount2) * 1e12 - (vars.expectedWithdrawnAmount3 * 125/100) - psm.totalShares(),
0,
usdcShareTolerance + 1 // 1 is added to the tolerance because of rounding error in sDAI calculations
);
Expand Down Expand Up @@ -563,25 +570,30 @@ contract PSMWithdrawTests is PSMTestBase {
vm.prank(user1);
amount = psm.withdraw(address(sDai), user1, type(uint256).max);

// User1s remaining shares are used
uint256 user1SDai = (user1Shares - expectedUser1SharesBurned)

{
// User1s remaining shares are used
uint256 user1SDai = (user1Shares - expectedUser1SharesBurned)
* totalValue
/ totalShares
* 1e27
/ conversionRate;

assertApproxEqAbs(sDai.balanceOf(user1), user1SDai, 2);
assertApproxEqAbs(sDai.balanceOf(user2), 0, 0);
assertApproxEqAbs(sDai.balanceOf(address(psm)), sDaiAmount - user1SDai, 2);
assertApproxEqAbs(sDai.balanceOf(user1), user1SDai, 2);
assertApproxEqAbs(sDai.balanceOf(user2), 0, 0);
assertApproxEqAbs(sDai.balanceOf(address(psm)), sDaiAmount - user1SDai, 2);

vm.prank(user2);
amount = psm.withdraw(address(sDai), user2, type(uint256).max);
vm.prank(user2);
amount = psm.withdraw(address(sDai), user2, type(uint256).max);

assertApproxEqAbs(amount, sDaiAmount - user1SDai, 2);

assertApproxEqAbs(sDai.balanceOf(user1), user1SDai, 2);
assertApproxEqAbs(sDai.balanceOf(user2), sDaiAmount - user1SDai, 2);
assertApproxEqAbs(sDai.balanceOf(address(psm)), 0, 2);
}

assertApproxEqAbs(amount, sDaiAmount - user1SDai, 2);

assertApproxEqAbs(sDai.balanceOf(user1), user1SDai, 2);
assertApproxEqAbs(sDai.balanceOf(user2), sDaiAmount - user1SDai, 2);
assertApproxEqAbs(sDai.balanceOf(address(psm)), 0, 2);

assertLe(psm.totalShares(), 1);
assertLe(psm.shares(user1), 1);
Expand Down

0 comments on commit 57bacf6

Please sign in to comment.