Skip to main content
PulseScanner.io

Address

0x3e17f5f2f2a5ef9b4b2faf81297e2ced705d578d
Current 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 {}
}