// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "forge-std/Test.sol"; import "../../contracts/vault/RateAccrual.sol"; contract RateAccrualTest is Test { RateAccrual public rateAccrual; address public admin = address(0x1); address public asset = address(0x100); uint256 public constant INTEREST_RATE = 500; // 5% annual function setUp() public { rateAccrual = new RateAccrual(admin); } function test_SetInterestRate() public { vm.prank(admin); rateAccrual.setInterestRate(asset, INTEREST_RATE); assertEq(rateAccrual.interestRate(asset), INTEREST_RATE); } function test_AccrueInterest_Initial() public { vm.prank(admin); rateAccrual.setInterestRate(asset, INTEREST_RATE); vm.prank(address(0x2)); uint256 accumulator = rateAccrual.accrueInterest(asset); assertEq(accumulator, 1e27); // RAY = initial value } function test_AccrueInterest_OverTime() public { vm.prank(admin); rateAccrual.setInterestRate(asset, INTEREST_RATE); // Initial accrual vm.prank(address(0x2)); rateAccrual.accrueInterest(asset); uint256 accumulator1 = rateAccrual.getRateAccumulator(asset); // Fast forward 1 year vm.warp(block.timestamp + 365 days); vm.prank(address(0x2)); rateAccrual.accrueInterest(asset); uint256 accumulator2 = rateAccrual.getRateAccumulator(asset); // Accumulator should increase (approximately 5% over 1 year) assertGt(accumulator2, accumulator1, "Accumulator should increase with time"); } function test_GetRateAccumulator_ViewOnly() public { vm.prank(admin); rateAccrual.setInterestRate(asset, INTEREST_RATE); // Get accumulator without state change (view function) uint256 accumulator1 = rateAccrual.getRateAccumulator(asset); assertEq(accumulator1, 1e27); // Initial RAY // Fast forward time vm.warp(block.timestamp + 365 days); // Get accumulator again (should accrue interest in view function) uint256 accumulator2 = rateAccrual.getRateAccumulator(asset); assertGt(accumulator2, accumulator1, "View function should accrue interest"); } function test_CalculateDebtWithInterest() public { vm.prank(admin); rateAccrual.setInterestRate(asset, INTEREST_RATE); uint256 principalDebt = 1000e18; // Calculate with initial accumulator (no interest yet) uint256 debt1 = rateAccrual.calculateDebtWithInterest(asset, principalDebt); assertEq(debt1, principalDebt); // Fast forward 1 year and accrue interest vm.warp(block.timestamp + 365 days); vm.prank(address(0x2)); rateAccrual.accrueInterest(asset); // Calculate debt with accrued interest uint256 debt2 = rateAccrual.calculateDebtWithInterest(asset, principalDebt); // Debt should be greater due to interest (~5% increase) assertGt(debt2, principalDebt, "Debt should increase with interest"); } function test_ZeroInterestRate() public { vm.prank(admin); rateAccrual.setInterestRate(asset, 0); // 0% interest vm.prank(address(0x2)); uint256 accumulator1 = rateAccrual.accrueInterest(asset); vm.warp(block.timestamp + 365 days); vm.prank(address(0x2)); uint256 accumulator2 = rateAccrual.accrueInterest(asset); // Accumulator should remain unchanged with 0% interest assertEq(accumulator1, accumulator2); } }