use super::helpers::*; #[test] fn test_protocol_fee_split_zero_cut() { let mut contract = setup_vault_with_protocol_cuts(0, 0); // No protocol cuts let asset = contract.base_asset.clone(); // Add some total fee let total_fee = 1000 * USDC_UNIT; // Split the fee contract.internal_add_fees(asset.clone(), total_fee.into(), 0); // All fees should go to vault creator assert_eq!( contract.get_fees_owed_for_asset(&asset).0, total_fee, "All fees should go to vault when protocol cut is 0" ); assert_eq!( contract.get_protocol_fees_owed_for_asset(&asset).0, 0, "No fees should go to protocol" ); } #[test] fn test_protocol_fee_split_20_percent() { let mut contract = setup_vault_with_protocol_cuts(2000, 2000); // 20% cuts let asset = contract.base_asset.clone(); // Add total fee let total_fee = 1000 * USDC_UNIT; // Split the fee using 20% protocol cut contract.internal_add_fees(asset.clone(), total_fee.into(), 2000); // Calculate expected split let expected_protocol = calculate_protocol_cut(total_fee, 2000); let expected_vault = total_fee - expected_protocol; // Verify split assert_fee_within_tolerance( expected_vault, contract.get_fees_owed_for_asset(&asset).0, 10, ); assert_fee_within_tolerance( expected_protocol, contract.get_protocol_fees_owed_for_asset(&asset).0, 10, ); } #[test] fn test_protocol_fee_split_100_percent() { let mut contract = setup_vault_with_protocol_cuts(10000, 10000); // 100% to protocol let asset = contract.base_asset.clone(); // Add total fee let total_fee = 1000 * USDC_UNIT; // Split with 100% protocol cut contract.internal_add_fees(asset.clone(), total_fee.into(), 10000); // All fees should go to protocol assert_fee_within_tolerance( 0, contract.get_fees_owed_for_asset(&asset).0, 1, // Allow 1 basis point tolerance for rounding ); assert_fee_within_tolerance( total_fee, contract.get_protocol_fees_owed_for_asset(&asset).0, 10, ); } #[test] #[should_panic(expected = "No protocol fees to claim")] fn test_protocol_claim_fails_no_fees() { let mut contract = create_test_contract(); let asset = contract.base_asset.clone(); // Verify no fees owed assert_eq!(contract.get_protocol_fees_owed_for_asset(&asset).0, 0); // Set predecessor to protocol account set_predecessor(contract.protocol_account.clone()); // Try to claim - should panic contract.protocol_claim_fees_for_asset(asset); } #[test] fn test_protocol_claim_fees_success() { let mut contract = setup_vault_with_protocol_cuts(2000, 2000); let asset = contract.base_asset.clone(); // Add some fees let total_fee = 1000 * USDC_UNIT; contract.internal_add_fees(asset.clone(), total_fee.into(), 2000); // Verify protocol has fees to claim let protocol_fees_before = contract.get_protocol_fees_owed_for_asset(&asset).0; assert!(protocol_fees_before > 0, "Protocol should have fees"); // Note: We can't easily test the actual claim function without // integration tests because it returns a Promise. This test verifies // the state before claiming. // Verify the fee amount is reasonable let expected_protocol = calculate_protocol_cut(total_fee, 2000); assert_fee_within_tolerance(expected_protocol, protocol_fees_before, 10); } #[test] #[should_panic] fn test_protocol_fee_overflow_protection() { let mut contract = create_test_contract(); let asset = contract.base_asset.clone(); // Set fees_owed for asset to max contract .state .fees_owed .insert(asset.clone(), u128::MAX.into()); // Try to add more fees - should panic on overflow contract.internal_add_fees(asset.clone(), 1.into(), 0); }