Address
0x3e17f5f2f2a5ef9b4b2faf81297e2ced705d578dCurrent Holdings
$0.00
TXs sent
not counted
First Active
2026-03-01
block 25,909,866
Last Active
202 days ago
block 25,909,870
Funded By
not identified
Net worth historyi
No net-worth snapshots recorded yet
exact matchFeeDistributorsolc 0.8.31+commit.fd3a2265runtime exact · creation exact
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
/**
* @title FeeDistributor
* @notice Collects and distributes trading fees for PulsePump protocol
* @dev Owner can adjust fee percentage (0-1000 basis points = 0-10%)
*/
contract FeeDistributor is Ownable, ReentrancyGuard {
using SafeERC20 for IERC20;
// Fee in basis points (100 = 1%, max 1000 = 10%)
uint256 public tradingFee;
uint256 public constant MAX_FEE = 1000; // 10%
uint256 public constant FEE_DENOMINATOR = 10000;
// Treasury address for fee distribution
address public treasury;
// Authorized routers that can deposit fees
mapping(address => bool) public authorizedRouters;
// Total fees collected per token
mapping(address => uint256) public feesCollected;
// Events
event FeeUpdated(uint256 oldFee, uint256 newFee);
event TreasuryUpdated(address oldTreasury, address newTreasury);
event RouterAuthorized(address router, bool authorized);
event FeesDeposited(address indexed token, uint256 amount);
event FeesWithdrawn(address indexed token, address indexed to, uint256 amount);
event ETHWithdrawn(address indexed to, uint256 amount);
constructor(address _treasury, uint256 _initialFee) Ownable(msg.sender) {
require(_treasury != address(0), "Invalid treasury");
require(_initialFee <= MAX_FEE, "Fee too high");
treasury = _treasury;
tradingFee = _initialFee;
}
// ============ Admin Functions ============
/**
* @notice Set the trading fee (owner can set to 0)
* @param _newFee Fee in basis points (0-1000)
*/
function setTradingFee(uint256 _newFee) external onlyOwner {
require(_newFee <= MAX_FEE, "Fee too high");
uint256 oldFee = tradingFee;
tradingFee = _newFee;
emit FeeUpdated(oldFee, _newFee);
}
/**
* @notice Update treasury address
* @param _newTreasury New treasury address
*/
function setTreasury(address _newTreasury) external onlyOwner {
require(_newTreasury != address(0), "Invalid treasury");
address oldTreasury = treasury;
treasury = _newTreasury;
emit TreasuryUpdated(oldTreasury, _newTreasury);
}
/**
* @notice Authorize or revoke router access
* @param _router Router address
* @param _authorized Authorization status
*/
function setRouterAuthorization(address _router, bool _authorized) external onlyOwner {
authorizedRouters[_router] = _authorized;
emit RouterAuthorized(_router, _authorized);
}
// ============ Fee Collection ============
/**
* @notice Deposit fees (called by router during trades)
* @param _token Token address (address(0) for native PLS)
* @param _amount Amount of fees
*/
function depositFees(address _token, uint256 _amount) external payable nonReentrant {
require(authorizedRouters[msg.sender], "Not authorized");
if (_token == address(0)) {
require(msg.value == _amount, "Invalid ETH amount");
} else {
IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);
}
feesCollected[_token] += _amount;
emit FeesDeposited(_token, _amount);
}
/**
* @notice Calculate fee amount for a trade
* @param _amount Trade amount
* @return Fee amount to collect
*/
function calculateFee(uint256 _amount) external view returns (uint256) {
return (_amount * tradingFee) / FEE_DENOMINATOR;
}
// ============ Withdrawal Functions ============
/**
* @notice Withdraw collected ERC20 fees to treasury
* @param _token Token address
*/
function withdrawFees(address _token) external nonReentrant {
require(_token != address(0), "Use withdrawETH for native");
uint256 balance = IERC20(_token).balanceOf(address(this));
require(balance > 0, "No fees to withdraw");
IERC20(_token).safeTransfer(treasury, balance);
emit FeesWithdrawn(_token, treasury, balance);
}
/**
* @notice Withdraw collected native PLS to treasury
*/
function withdrawETH() external nonReentrant {
uint256 balance = address(this).balance;
require(balance > 0, "No ETH to withdraw");
(bool success, ) = treasury.call{value: balance}("");
require(success, "ETH transfer failed");
emit ETHWithdrawn(treasury, balance);
}
/**
* @notice Emergency withdraw any stuck tokens
* @param _token Token address
* @param _to Recipient address
*/
function emergencyWithdraw(address _token, address _to) external onlyOwner {
if (_token == address(0)) {
uint256 balance = address(this).balance;
(bool success, ) = _to.call{value: balance}("");
require(success, "ETH transfer failed");
} else {
uint256 balance = IERC20(_token).balanceOf(address(this));
IERC20(_token).safeTransfer(_to, balance);
}
}
// ============ View Functions ============
/**
* @notice Get current fee percentage
* @return Fee as a percentage (e.g., 100 = 1%)
*/
function getFeePercentage() external view returns (uint256) {
return tradingFee;
}
/**
* @notice Check if address is authorized router
* @param _router Router address to check
*/
function isAuthorizedRouter(address _router) external view returns (bool) {
return authorizedRouters[_router];
}
receive() external payable {}
}