// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {Ownable} from '@solady/auth/Ownable.sol';
import {LPFeeLibrary} from '@uniswap/v4-core/src/libraries/LPFeeLibrary.sol';
/**
* This contract will allow for specific addresses to have reduced or nullified fees for all
* swaps transactions within the pool. These will be allocated to partners that need a more
* consistent underlying price to ensure their protocol can operate using Flaunch pools.
*/
contract FeeExemptions is Ownable {
using LPFeeLibrary for uint24;
error FeeExemptionInvalid(uint24 _invalidFee, uint24 _maxFee);
error NoBeneficiaryExemption(address _beneficiary);
/// Emitted when a beneficiary exemption is set or updated
event BeneficiaryFeeSet(address _beneficiary, uint24 _flatFee);
/// Emitted when a beneficiary exemption is removed
event BeneficiaryFeeRemoved(address _beneficiary);
/**
* Defines the fee exemption that a beneficiary will receive if enabled.
*
* @member flatFee The flat fee value that the `_beneficiary` will receive
* @member enabled If the exemption is enabled
*/
struct FeeExemption {
uint24 flatFee;
bool enabled;
}
/// Stores a mapping of beneficiaries and that flat fee exemptions
mapping (address _beneficiary => FeeExemption _exemption) internal _feeExemption;
/**
* Registers the caller as the contract owner.
*
* @param _protocolOwner The initial EOA owner of the contract
*/
constructor (address _protocolOwner) {
// Grant ownership permissions to the caller
_initializeOwner(_protocolOwner);
}
/**
* Gets the `FeeExemption` data struct for a beneficiary address.
*
* @param _beneficiary The address of the beneficiary
*
* @return The FeeExemption struct for the beneficiary
*/
function feeExemption(address _beneficiary) public view returns (FeeExemption memory) {
return _feeExemption[_beneficiary];
}
/**
* Set our beneficiary's flat fee rate across all pools. If a beneficiary is set, then
* the fee processed during a swap will be overwritten if this fee exemption value is
* lower than the otherwise determined fee.
*
* @param _beneficiary The swap `sender` that will receive the exemption
* @param _flatFee The flat fee value that the `_beneficiary` will receive
*/
function setFeeExemption(address _beneficiary, uint24 _flatFee) public onlyOwner {
// Ensure that our custom fee conforms to Uniswap V4 requirements
if (!_flatFee.isValid()) revert FeeExemptionInvalid(_flatFee, LPFeeLibrary.MAX_LP_FEE);
_feeExemption[_beneficiary] = FeeExemption(_flatFee, true);
emit BeneficiaryFeeSet(_beneficiary, _flatFee);
}
/**
* Removes a beneficiary fee exemption.
*
* @dev If the `beneficiary` does not already have an exemption, this call will revert.
*
* @param _beneficiary The address to remove the fee exemption from
*/
function removeFeeExemption(address _beneficiary) public onlyOwner {
// Check that a beneficiary is currently enabled
if (!_feeExemption[_beneficiary].enabled) revert NoBeneficiaryExemption(_beneficiary);
delete _feeExemption[_beneficiary];
emit BeneficiaryFeeRemoved(_beneficiary);
}
/**
* Override to return true to make `_initializeOwner` prevent double-initialization.
*
* @return bool Set to `true` to prevent owner being reinitialized.
*/
function _guardInitializeOwner() internal pure override returns (bool) {
return true;
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "_protocolOwner",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "AlreadyInitialized",
"type": "error",
"inputs": []
},
{
"name": "FeeExemptionInvalid",
"type": "error",
"inputs": [
{
"name": "_invalidFee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "_maxFee",
"type": "uint24",
"internalType": "uint24"
}
]
},
{
"name": "NewOwnerIsZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "NoBeneficiaryExemption",
"type": "error",
"inputs": [
{
"name": "_beneficiary",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "NoHandoverRequest",
"type": "error",
"inputs": []
},
{
"name": "Unauthorized",
"type": "error",
"inputs": []
},
{
"name": "BeneficiaryFeeRemoved",
"type": "event",
"inputs": [
{
"name": "_beneficiary",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "BeneficiaryFeeSet",
"type": "event",
"inputs": [
{
"name": "_beneficiary",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "_flatFee",
"type": "uint24",
"indexed": false,
"internalType": "uint24"
}
],
"anonymous": false
},
{
"name": "OwnershipHandoverCanceled",
"type": "event",
"inputs": [
{
"name": "pendingOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipHandoverRequested",
"type": "event",
"inputs": [
{
"name": "pendingOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "oldOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "cancelOwnershipHandover",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "completeOwnershipHandover",
"type": "function",
"inputs": [
{
"name": "pendingOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "feeExemption",
"type": "function",
"inputs": [
{
"name": "_beneficiary",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "tuple",
"components": [
{
"name": "flatFee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "enabled",
"type": "bool",
"internalType": "bool"
}
],
"internalType": "struct FeeExemptions.FeeExemption"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "result",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "ownershipHandoverExpiresAt",
"type": "function",
"inputs": [
{
"name": "pendingOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "result",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "removeFeeExemption",
"type": "function",
"inputs": [
{
"name": "_beneficiary",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "requestOwnershipHandover",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "setFeeExemption",
"type": "function",
"inputs": [
{
"name": "_beneficiary",
"type": "address",
"internalType": "address"
},
{
"name": "_flatFee",
"type": "uint24",
"internalType": "uint24"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
}
]0x6080604052348015600e575f80fd5b50604051610654380380610654833981016040819052602b91608e565b6032816037565b5060b9565b638b78c6d819805415605057630dc149f05f526004601cfd5b6001600160a01b03909116801560ff1b8117909155805f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b5f60208284031215609d575f80fd5b81516001600160a01b038116811460b2575f80fd5b9392505050565b61058e806100c65f395ff3fe608060405260043610610080575f3560e01c8063176a57811461008457806325692962146100a5578063360507b6146100ad57806354d1f13d146100cc578063715018a6146100d45780638da5cb5b146100dc578063f04e283e14610105578063f2fde38b14610118578063f6a23d981461012b578063fee81cf4146101b7575b5f80fd5b34801561008f575f80fd5b506100a361009e3660046104e8565b6101f6565b005b6100a36102cc565b3480156100b8575f80fd5b506100a36100c7366004610524565b610318565b6100a36103be565b6100a36103f7565b3480156100e7575f80fd5b50638b78c6d819546040516100fc9190610544565b60405180910390f35b6100a3610113366004610524565b61040a565b6100a3610126366004610524565b610447565b348015610136575f80fd5b50610195610145366004610524565b604080518082019091525f8082526020820152506001600160a01b03165f908152602081815260409182902082518084019093525462ffffff811683526301000000900460ff1615159082015290565b60408051825162ffffff168152602092830151151592810192909252016100fc565b3480156101c2575f80fd5b506101e86101d1366004610524565b63389a75e1600c9081525f91909152602090205490565b6040519081526020016100fc565b6101fe61046d565b620f424062ffffff8216111561023c57604051636b4f872960e11b815262ffffff82166004820152620f424060248201526044015b60405180910390fd5b60408051808201825262ffffff838116808352600160208085019182526001600160a01b0388165f818152808352879020955186549351151563010000000263ffffffff19909416951694909417919091179093558351918252918101919091527f39ed56833ed68b7ad31bc19f04583da5de5c8e83ed9a66115f9066117b5c1920910160405180910390a15050565b5f6202a3006001600160401b03164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b61032061046d565b6001600160a01b0381165f908152602081905260409020546301000000900460ff1661036157806040516338f3c55360e11b81526004016102339190610544565b6001600160a01b0381165f9081526020819052604090819020805463ffffffff19169055517f91891b9cc37faa20e065508e849de7e93346686dcf16e1f34b01f0fa87d01ccb906103b3908390610544565b60405180910390a150565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b6103ff61046d565b6104085f610487565b565b61041261046d565b63389a75e1600c52805f526020600c20805442111561043857636f5e88185f526004601cfd5b5f905561044481610487565b50565b61044f61046d565b8060601b61046457637448fbae5f526004601cfd5b61044481610487565b638b78c6d819543314610408576382b429005f526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3811560ff1b8217905550565b80356001600160a01b03811681146104e3575f80fd5b919050565b5f80604083850312156104f9575f80fd5b610502836104cd565b9150602083013562ffffff81168114610519575f80fd5b809150509250929050565b5f60208284031215610534575f80fd5b61053d826104cd565b9392505050565b6001600160a01b039190911681526020019056fea264697066735822122072b2430160d5a9d5506f84fda0b594ee10619e5e2f193fe7f47aca0ebb003a3e64736f6c634300081a00330000000000000000000000008ed5234a06dbdc71aecf4580a366c725f29f68e7
0x608060405260043610610080575f3560e01c8063176a57811461008457806325692962146100a5578063360507b6146100ad57806354d1f13d146100cc578063715018a6146100d45780638da5cb5b146100dc578063f04e283e14610105578063f2fde38b14610118578063f6a23d981461012b578063fee81cf4146101b7575b5f80fd5b34801561008f575f80fd5b506100a361009e3660046104e8565b6101f6565b005b6100a36102cc565b3480156100b8575f80fd5b506100a36100c7366004610524565b610318565b6100a36103be565b6100a36103f7565b3480156100e7575f80fd5b50638b78c6d819546040516100fc9190610544565b60405180910390f35b6100a3610113366004610524565b61040a565b6100a3610126366004610524565b610447565b348015610136575f80fd5b50610195610145366004610524565b604080518082019091525f8082526020820152506001600160a01b03165f908152602081815260409182902082518084019093525462ffffff811683526301000000900460ff1615159082015290565b60408051825162ffffff168152602092830151151592810192909252016100fc565b3480156101c2575f80fd5b506101e86101d1366004610524565b63389a75e1600c9081525f91909152602090205490565b6040519081526020016100fc565b6101fe61046d565b620f424062ffffff8216111561023c57604051636b4f872960e11b815262ffffff82166004820152620f424060248201526044015b60405180910390fd5b60408051808201825262ffffff838116808352600160208085019182526001600160a01b0388165f818152808352879020955186549351151563010000000263ffffffff19909416951694909417919091179093558351918252918101919091527f39ed56833ed68b7ad31bc19f04583da5de5c8e83ed9a66115f9066117b5c1920910160405180910390a15050565b5f6202a3006001600160401b03164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b61032061046d565b6001600160a01b0381165f908152602081905260409020546301000000900460ff1661036157806040516338f3c55360e11b81526004016102339190610544565b6001600160a01b0381165f9081526020819052604090819020805463ffffffff19169055517f91891b9cc37faa20e065508e849de7e93346686dcf16e1f34b01f0fa87d01ccb906103b3908390610544565b60405180910390a150565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b6103ff61046d565b6104085f610487565b565b61041261046d565b63389a75e1600c52805f526020600c20805442111561043857636f5e88185f526004601cfd5b5f905561044481610487565b50565b61044f61046d565b8060601b61046457637448fbae5f526004601cfd5b61044481610487565b638b78c6d819543314610408576382b429005f526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3811560ff1b8217905550565b80356001600160a01b03811681146104e3575f80fd5b919050565b5f80604083850312156104f9575f80fd5b610502836104cd565b9150602083013562ffffff81168114610519575f80fd5b809150509250929050565b5f60208284031215610534575f80fd5b61053d826104cd565b9392505050565b6001600160a01b039190911681526020019056fea264697066735822122072b2430160d5a9d5506f84fda0b594ee10619e5e2f193fe7f47aca0ebb003a3e64736f6c634300081a0033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x7a998b…55d24a | 29 days agoFri, 17 Jul 2026 13:59:01 UTC | 0x8be007…57e0 | [0] 0x000000000000…f29f68e7 [1] 0x000000000000…5e4a74ce |
| 0x1fcb82…db8cee | 29 days agoFri, 17 Jul 2026 13:58:58 UTC | 0x8be007…57e0 | [0] 0x000000000000…00000000 [1] 0x000000000000…f29f68e7 |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| no token transfers for this address yet | |||||||||
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| no internal transactions found for this address yet (traced blocks + on-demand) | ||||||||
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x7a998b…55d24a | transferOwnership | 12,173,383 | 29 days agoFri, 17 Jul 2026 13:59:01 UTC | 0x8ed5…68e7 | IN | FeeExemptions | $0.000 ETH | 0.00000209 |