Skip to main content

tempo_contracts/precompiles/
tip_fee_manager.rs

1pub use IFeeManager::{IFeeManagerErrors as FeeManagerError, IFeeManagerEvents as FeeManagerEvent};
2pub use ITIPFeeAMM::{ITIPFeeAMMErrors as TIPFeeAMMError, ITIPFeeAMMEvents as TIPFeeAMMEvent};
3
4crate::sol! {
5    /// FeeManager interface for managing gas fee collection and distribution.
6    ///
7    /// IMPORTANT: FeeManager inherits from TIPFeeAMM and shares the same storage layout.
8    /// This means:
9    /// - FeeManager has all the functionality of TIPFeeAMM (pool management, swaps, liquidity operations)
10    /// - Both contracts use the same storage slots for AMM data (pools, reserves, liquidity balances)
11    /// - FeeManager extends TIPFeeAMM with additional storage slots (4-15) for fee-specific data
12    /// - When deployed, FeeManager IS a TIPFeeAMM with additional fee management capabilities
13    ///
14    /// Storage layout:
15    /// - Slots 0-3: TIPFeeAMM storage (pools, pool exists, liquidity data)
16    /// - Slots 4+: FeeManager-specific storage (validator tokens, user tokens, collected fees, etc.)
17    #[derive(Debug, PartialEq, Eq)]
18    #[sol(abi)]
19    interface IFeeManager {
20        // Structs
21        struct FeeInfo {
22            uint128 amount;
23            bool hasBeenSet;
24        }
25
26        // User preferences
27        function userTokens(address user) external view returns (address);
28        function validatorTokens(address validator) external view returns (address);
29        function setUserToken(address token) external;
30        function setValidatorToken(address token) external;
31
32        // Fee functions
33        function distributeFees(address validator, address token) external;
34        function collectedFees(address validator, address token) external view returns (uint256);
35        // NOTE: collectFeePreTx is a protocol-internal function called directly by the
36        // execution handler, not exposed via the dispatch interface.
37
38        // Events
39        event UserTokenSet(address indexed user, address indexed token);
40        event ValidatorTokenSet(address indexed validator, address indexed token);
41        event FeesDistributed(address indexed validator, address indexed token, uint256 amount);
42
43        // Errors
44        error OnlyValidator();
45        error OnlySystemContract();
46        error InvalidToken();
47        error PoolDoesNotExist();
48        error InsufficientFeeTokenBalance();
49        error InternalError();
50        error CannotChangeWithinBlock();
51        error CannotChangeWithPendingFees();
52        error TokenPolicyForbids();
53    }
54}
55
56sol! {
57    /// TIPFeeAMM interface defining the base AMM functionality for stablecoin pools.
58    /// This interface provides core liquidity pool management and swap operations.
59    ///
60    /// NOTE: The FeeManager contract inherits from TIPFeeAMM and shares the same storage layout.
61    /// When FeeManager is deployed, it effectively "is" a TIPFeeAMM with additional fee management
62    /// capabilities layered on top. Both contracts operate on the same storage slots.
63    #[derive(Debug, PartialEq, Eq)]
64    #[allow(clippy::too_many_arguments)]
65    interface ITIPFeeAMM {
66        // Structs
67        struct Pool {
68            uint128 reserveUserToken;
69            uint128 reserveValidatorToken;
70        }
71
72        struct PoolKey {
73            address token0;
74            address token1;
75        }
76
77
78        // Constants
79        function M() external view returns (uint256);
80        function N() external view returns (uint256);
81        function SCALE() external view returns (uint256);
82        function MIN_LIQUIDITY() external view returns (uint256);
83
84        // Pool Management
85        function getPoolId(address userToken, address validatorToken) external pure returns (bytes32);
86        function getPool(address userToken, address validatorToken) external view returns (Pool memory);
87        function pools(bytes32 poolId) external view returns (Pool memory);
88
89        // Liquidity Operations
90        function mint(address userToken, address validatorToken, uint256 amountValidatorToken, address to) external returns (uint256 liquidity);
91        function burn(address userToken, address validatorToken, uint256 liquidity, address to) external returns (uint256 amountUserToken, uint256 amountValidatorToken);
92
93        // Liquidity Balances
94        function totalSupply(bytes32 poolId) external view returns (uint256);
95        function liquidityBalances(bytes32 poolId, address user) external view returns (uint256);
96
97        // Swapping
98        function rebalanceSwap(address userToken, address validatorToken, uint256 amountOut, address to) external returns (uint256 amountIn);
99
100        // Events
101        event Mint(address sender, address indexed to, address indexed userToken, address indexed validatorToken, uint256 amountValidatorToken, uint256 liquidity);
102        event Burn(address indexed sender, address indexed userToken, address indexed validatorToken, uint256 amountUserToken, uint256 amountValidatorToken, uint256 liquidity, address to);
103        event RebalanceSwap(address indexed userToken, address indexed validatorToken, address indexed swapper, uint256 amountIn, uint256 amountOut);
104
105        // Errors
106        error IdenticalAddresses();
107        error InvalidToken();
108        error InsufficientLiquidity();
109        error InsufficientReserves();
110        error InvalidAmount();
111        error DivisionByZero();
112        error InvalidSwapCalculation();
113    }
114}
115
116impl FeeManagerError {
117    /// Creates an error for only validator access.
118    pub const fn only_validator() -> Self {
119        Self::OnlyValidator(IFeeManager::OnlyValidator {})
120    }
121
122    /// Creates an error for only system contract access.
123    pub const fn only_system_contract() -> Self {
124        Self::OnlySystemContract(IFeeManager::OnlySystemContract {})
125    }
126
127    /// Creates an error for invalid token.
128    pub const fn invalid_token() -> Self {
129        Self::InvalidToken(IFeeManager::InvalidToken {})
130    }
131
132    /// Creates an error when pool does not exist.
133    pub const fn pool_does_not_exist() -> Self {
134        Self::PoolDoesNotExist(IFeeManager::PoolDoesNotExist {})
135    }
136
137    /// Creates an error for insufficient fee token balance.
138    pub const fn insufficient_fee_token_balance() -> Self {
139        Self::InsufficientFeeTokenBalance(IFeeManager::InsufficientFeeTokenBalance {})
140    }
141
142    /// Creates an error for cannot change within block.
143    pub const fn cannot_change_within_block() -> Self {
144        Self::CannotChangeWithinBlock(IFeeManager::CannotChangeWithinBlock {})
145    }
146
147    /// Creates an error for cannot change with pending fees.
148    pub const fn cannot_change_with_pending_fees() -> Self {
149        Self::CannotChangeWithPendingFees(IFeeManager::CannotChangeWithPendingFees {})
150    }
151
152    /// Creates an error for token policy forbids.
153    pub const fn token_policy_forbids() -> Self {
154        Self::TokenPolicyForbids(IFeeManager::TokenPolicyForbids {})
155    }
156}
157
158impl TIPFeeAMMError {
159    /// Creates an error for identical token addresses.
160    pub const fn identical_addresses() -> Self {
161        Self::IdenticalAddresses(ITIPFeeAMM::IdenticalAddresses {})
162    }
163
164    /// Creates an error for invalid token.
165    pub const fn invalid_token() -> Self {
166        Self::InvalidToken(ITIPFeeAMM::InvalidToken {})
167    }
168
169    /// Creates an error for insufficient liquidity.
170    pub const fn insufficient_liquidity() -> Self {
171        Self::InsufficientLiquidity(ITIPFeeAMM::InsufficientLiquidity {})
172    }
173
174    /// Creates an error for insufficient reserves.
175    pub const fn insufficient_reserves() -> Self {
176        Self::InsufficientReserves(ITIPFeeAMM::InsufficientReserves {})
177    }
178    /// Creates an error for invalid amount.
179    pub const fn invalid_amount() -> Self {
180        Self::InvalidAmount(ITIPFeeAMM::InvalidAmount {})
181    }
182
183    /// Creates an error for invalid swap calculation.
184    pub const fn invalid_swap_calculation() -> Self {
185        Self::InvalidSwapCalculation(ITIPFeeAMM::InvalidSwapCalculation {})
186    }
187
188    /// Creates an error for division by zero.
189    pub const fn division_by_zero() -> Self {
190        Self::DivisionByZero(ITIPFeeAMM::DivisionByZero {})
191    }
192}