use super::helpers::*; #[test] fn test_zero_management_fee_when_not_live() { let mut contract = setup_vault_with_fees(200, 0); // 2% management fee // Set up state as if vault has assets but is not live set_total_shares(&mut contract, 100_000 * USDC_UNIT); set_share_price(&mut contract, RATE_PRECISION); // 1:1 rate // Vault is not live (live_at = 0) assert_eq!(contract.live_at.0, 0); // Fast forward time fast_forward_time(ONE_YEAR_NS); // Get management fee preview - should be 0 because vault not live let fee = contract.get_current_management_fee_preview(); assert_eq!(fee.0, 0, "Management fee should be 0 when vault not live"); } #[test] fn test_zero_management_fee_with_zero_time() { let mut contract = setup_vault_with_fees(200, 0); // 2% management fee // Start vault let current_time = current_timestamp(); start_vault_at(&mut contract, current_time); // Set up state set_total_shares(&mut contract, 100_000 * USDC_UNIT); set_share_price(&mut contract, RATE_PRECISION); // Set previous update time to current (zero elapsed) set_previous_update_time(&mut contract, current_time); // No time has elapsed (just started) let fee = contract.get_current_management_fee_preview(); assert_eq!(fee.0, 0, "Management fee should be 0 when no time elapsed"); } #[test] fn test_zero_management_fee_with_zero_tvl() { let mut contract = setup_vault_with_fees(200, 0); // 2% management fee // Start vault start_vault(&mut contract); // Set up state with zero shares (empty vault) set_total_shares(&mut contract, 0); set_share_price(&mut contract, RATE_PRECISION); // Fast forward time fast_forward_time(ONE_YEAR_NS); // Get management fee - should be 0 because TVL is zero let fee = contract.get_current_management_fee_preview(); assert_eq!(fee.0, 0, "Management fee should be 0 when TVL is zero"); } #[test] fn test_management_fee_calculation_one_year() { let mut contract = setup_vault_with_fees(200, 0); // 2% management fee // Start vault let start_time = current_timestamp(); start_vault_at(&mut contract, start_time); // Set up state: 1,000,000 USDC TVL let asset_amount = 1_000_000 * USDC_UNIT; set_total_shares(&mut contract, asset_amount); set_share_price(&mut contract, RATE_PRECISION); // 1:1 rate // Calculate expected TVL - should match asset amount at 1:1 rate let actual_shares = contract.state.total_shares.0; let tvl = calculate_tvl(actual_shares, RATE_PRECISION, RATE_PRECISION); assert_eq!( tvl, asset_amount, "TVL should equal asset amount at 1:1 rate" ); // Set previous update time to start set_previous_update_time(&mut contract, start_time); // Fast forward exactly one year fast_forward_time(ONE_YEAR_NS); // Get management fee preview let fee = contract.get_current_management_fee_preview(); // Expected fee: 1,000,000 USDC * 2% = 20,000 USDC let expected_fee = 20_000 * USDC_UNIT; // Allow small tolerance for rounding assert_fee_within_tolerance(expected_fee, fee.0, 10); // 0.1% tolerance } #[test] fn test_management_fee_scales_with_time() { let mut contract = setup_vault_with_fees(200, 0); // 2% management fee // Start vault let start_time = current_timestamp(); start_vault_at(&mut contract, start_time); // Set up state: 1,000,000 USDC TVL let total_shares = 1_000_000 * USDC_UNIT; set_total_shares(&mut contract, total_shares); set_share_price(&mut contract, RATE_PRECISION); // Set previous update time set_previous_update_time(&mut contract, start_time); // Fast forward 6 months (half a year) fast_forward_time(ONE_YEAR_NS / 2); // Get management fee let fee_6_months = contract.get_current_management_fee_preview(); // Expected fee for 6 months: 20,000 USDC * 0.5 = 10,000 USDC let expected_fee = 10_000 * USDC_UNIT; assert_fee_within_tolerance(expected_fee, fee_6_months.0, 10); // Fast forward another 6 months (total 1 year) fast_forward_time(ONE_YEAR_NS / 2); // Fee should now be approximately double let fee_1_year = contract.get_current_management_fee_preview(); let expected_fee_year = 20_000 * USDC_UNIT; assert_fee_within_tolerance(expected_fee_year, fee_1_year.0, 10); } #[test] fn test_management_fee_scales_with_tvl() { let mut contract = setup_vault_with_fees(200, 0); // 2% management fee // Start vault let start_time = current_timestamp(); start_vault_at(&mut contract, start_time); // Test with 500,000 USDC TVL let total_shares_1 = 500_000 * USDC_UNIT; set_total_shares(&mut contract, total_shares_1); set_share_price(&mut contract, RATE_PRECISION); set_previous_update_time(&mut contract, start_time); // Fast forward one year fast_forward_time(ONE_YEAR_NS); let fee_500k = contract.get_current_management_fee_preview(); // Reset time set_timestamp(start_time); set_previous_update_time(&mut contract, start_time); // Now test with 1,000,000 USDC TVL (2x) let total_shares_2 = 1_000_000 * USDC_UNIT; set_total_shares(&mut contract, total_shares_2); // Fast forward one year again fast_forward_time(ONE_YEAR_NS); let fee_1m = contract.get_current_management_fee_preview(); // Fee should be approximately 2x for 2x TVL assert_within_percent(fee_500k.0 * 2, fee_1m.0, 1); } #[test] fn test_management_fee_rounding() { let mut contract = setup_vault_with_fees(1, 0); // 0.01% management fee // Start vault let start_time = current_timestamp(); start_vault_at(&mut contract, start_time); // Small TVL that will produce fractional fees let total_shares = 1000 * USDC_UNIT; set_total_shares(&mut contract, total_shares); set_share_price(&mut contract, RATE_PRECISION); set_previous_update_time(&mut contract, start_time); // Fast forward a short time fast_forward_time(ONE_DAY_NS); let fee = contract.get_current_management_fee_preview(); // Fee should round up (conservative for fee collector) // Even tiny fees should not be zero if time elapsed assert!(fee.0 > 0, "Fee should round up, not down to zero"); }