> ## Documentation Index
> Fetch the complete documentation index at: https://phylaxsystems-docs-project-incidents.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Fee Calculations

> Make sure that the fees do not change unexpectedly

## Use Case & Applications

Prevents unauthorized fee manipulation in AMMs and DeFi protocols by using a whitelist approach to control fee changes. Critical for AMMs (Velodrome, Aerodrome, Curve), DEX aggregators, lending protocols with origination fees, yield aggregators with performance fees, and cross-chain bridges with transfer fees.

Unexpected fee changes can lead to unauthorized manipulation, protocol revenue loss, user losses, or market manipulation through fee bypasses.

## Explanation

Uses a whitelist approach to control fee changes:

* `registerStorageChangeTrigger()`: Detect changes to fee storage slot
* `ph.load()`: Retrieve new fee value after change
* `getStateChangesUint()`: Verify all state changes for fee storage slot
* Maintains hardcoded allowed fee values for stable pools (0.1%, 0.15%) and non-stable pools (0.25%, 0.30%)

When triggered, verifies the new fee matches one of the allowed values, preventing unauthorized modifications while allowing proper protocol updates.

For more information about cheatcodes, see the [Cheatcodes Documentation](/credible/cheatcodes-reference).

## Code Example

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {Assertion} from "credible-std/Assertion.sol";
import {PhEvm} from "credible-std/PhEvm.sol";

// Check that fee invariants are maintained
contract AmmFeeVerificationAssertion is Assertion {
    // Hardcoded whitelist of allowed fee values
    uint256 private constant STABLE_POOL_FEE_1 = 1; // 0.1%
    uint256 private constant STABLE_POOL_FEE_2 = 15; // 0.15%
    uint256 private constant NON_STABLE_POOL_FEE_1 = 25; // 0.25%
    uint256 private constant NON_STABLE_POOL_FEE_2 = 30; // 0.30%

    function triggers() external view override {
        // Register trigger for changes to the fee storage slot
        registerStorageChangeTrigger(this.assertFeeVerification.selector, bytes32(uint256(1))); // Assuming fee is in slot 1
    }

    // Verify that any fee change is to an allowed value
    function assertFeeVerification() external view {
        // Get the assertion adopter address
        IPool adopter = IPool(ph.getAssertionAdopter());

        // Get the new fee value and pool type
        bool isStable = adopter.stable();
        uint256 newFee = uint256(ph.load(address(adopter), bytes32(uint256(1))));

        // Check if the new fee is in the whitelist
        bool isAllowed = isStable
            ? (newFee == STABLE_POOL_FEE_1 || newFee == STABLE_POOL_FEE_2)
            : (newFee == NON_STABLE_POOL_FEE_1 || newFee == NON_STABLE_POOL_FEE_2);

        require(isAllowed, "Fee change to unauthorized value");

        // If the simple check passes, verify no unauthorized changes in the callstack
        uint256[] memory changes = getStateChangesUint(address(adopter), bytes32(uint256(1)));

        // Check each change against the whitelist
        for (uint256 i = 0; i < changes.length; i++) {
            isAllowed = isStable
                ? (changes[i] == STABLE_POOL_FEE_1 || changes[i] == STABLE_POOL_FEE_2)
                : (changes[i] == NON_STABLE_POOL_FEE_1 || changes[i] == NON_STABLE_POOL_FEE_2);
            require(isAllowed, "Unauthorized fee change detected in callstack");
        }
    }
}

// Aerodrome style interface
interface IPool {
    function fee() external view returns (uint256);
    function stable() external view returns (bool);
}
```

<Note>Full examples with tests available in the [Phylax Assertion Examples Repository](https://github.com/phylaxsystems/assertion-examples/blob/main/assertions/).</Note>

## Related Assertions

* [Price Within Ticks](/assertions-book/assertions/ass15-price-within-ticks)
