V4Forwarder

Description:

Decentralized Finance (DeFi) protocol contract providing Swap, Factory functionality.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/V4Forwarder.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "./libraries/SafeTransferLib.sol";

/**
 * @title V4Forwarder
 * @notice Unified Forwarder + Uniswap V4 "hook sink" helper
 * - Splits engine-directed ETH (dev 1.69% / treasury remainder)
 * - Applies swap tax for a V4 pool and forwards to dev/treasury
 * - NEW: paySwapTax(engine) forwards msg.value to engine.creditSwapTax()
 */
contract V4Forwarder {
    using SafeTransferLib for address payable;

    // ---- Admin ----
    address public owner;
    address payable public dev;
    address payable public treasury;

    // 1.69% to dev on credits / taxes
    uint16 public constant DEV_BIPS = 169;

    // ---- V4 Hook Config ----
    address public weth;
    address public ploop;
    address public pool;
    bool    public hookEnabled;

    // % tax (in bips) to levy on pool swaps (default 10%)
    uint16 public taxBips = 1000;

    // ---- Simple Reentrancy Guard ----
    bool private _entered;
    modifier nonReentrant() {
        require(!_entered, "REENTRANT");
        _entered = true;
        _;
        _entered = false;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "NOT_OWNER");
        _;
    }

    // ---- Events ----
    event OwnerSet(address indexed newOwner);
    event DevSet(address indexed newDev);
    event TreasurySet(address indexed newTreasury);
    event TaxBipsSet(uint16 newBips);
    event HookConfigured(address weth, address ploop, address pool);
    event HookToggle(bool enabled);
    event CreditForwarded(address indexed from, uint256 devAmt, uint256 treasAmt);
    event SwapTaxApplied(address indexed sender, uint256 taxWei, uint256 toTreasury, uint256 toDev);
    event SwapTaxForwarded(address indexed engine, uint256 amountWei);

    // ---- Constructor ----
    constructor(address _owner) {
        owner = _owner;
        emit OwnerSet(_owner);
    }

    // ---- Owner functions ----
    function setOwner(address _owner) external onlyOwner {
        owner = _owner;
        emit OwnerSet(_owner);
    }

    function setDev(address payable _dev) external onlyOwner {
        dev = _dev;
        emit DevSet(_dev);
    }

    function setTreasury(address payable _treasury) external onlyOwner {
        treasury = _treasury;
        emit TreasurySet(_treasury);
    }

    function setTaxBips(uint16 b) external onlyOwner {
        require(b <= 2000, "TOO_HIGH");
        taxBips = b;
        emit TaxBipsSet(b);
    }

    function configureHook(address _weth, address _ploop, address _pool) external onlyOwner {
        weth = _weth;
        ploop = _ploop;
        pool = _pool;
        hookEnabled = true;
        emit HookConfigured(_weth, _ploop, _pool);
    }

    function toggleHook(bool e) external onlyOwner {
        hookEnabled = e;
        emit HookToggle(e);
    }

    // ======================================================
    //  ENGINE CREDIT PATHS (for presales / relist / ETH choice)
    // ======================================================

    /**
     * @notice Receives value from PunkLoopEngine and splits between dev/treasury
     * @dev msg.value must equal devAmt + treasuryAmt
     */
    function creditFromEngine(
        address _dev,
        address _treasury,
        uint256 devAmt,
        uint256 treasuryAmt
    ) external payable nonReentrant {
        require(msg.value == devAmt + treasuryAmt, "BAD_VALUE");
        if (devAmt > 0) payable(_dev).safeTransferETH(devAmt);
        if (treasuryAmt > 0) payable(_treasury).safeTransferETH(treasuryAmt);
        emit CreditForwarded(msg.sender, devAmt, treasuryAmt);
    }

    // ======================================================
    //  UNISWAP V4 HOOK TAX LOGIC
    // ======================================================

    /**
     * @notice Called automatically by a Uniswap V4 pool during swap execution.
     * @dev Must be set as the pool's hook recipient (off-chain integration).
     *      Applies a fixed % tax on swaps (10% default),
     *      then forwards the split (1.69% dev / rest treasury).
     */
    function applySwapTax() external payable nonReentrant {
        require(hookEnabled, "HOOK_OFF");
        require(msg.sender == pool, "NOT_POOL");
        require(msg.value > 0, "NO_VALUE");

        uint256 tax = (msg.value * taxBips) / 10_000;
        if (tax == 0) return;

        uint256 devCut = (tax * DEV_BIPS) / 10_000;
        uint256 treasCut = tax - devCut;

        if (devCut > 0) dev.safeTransferETH(devCut);
        if (treasCut > 0) treasury.safeTransferETH(treasCut);

        emit SwapTaxApplied(msg.sender, tax, treasCut, devCut);
    }

    // ======================================================
    //  NEW: Forward swap-tax ETH directly to the Engine
    // ======================================================

    /**
     * @notice Convenience sink for hooks/keepers:
     *         forwards msg.value to engine.creditSwapTax().
     * @param engine Address of PunkLoopEngine
     */
    function paySwapTax(address engine) external payable nonReentrant {
        require(engine != address(0), "ENGINE_0");
        // Forward all ETH to the engine's creditSwapTax()
        (bool ok, ) = engine.call{value: msg.value}(abi.encodeWithSignature("creditSwapTax()"));
        require(ok, "ENGINE_FORWARD_FAIL");
        emit SwapTaxForwarded(engine, msg.value);
    }

    // ======================================================
    //  FALLBACKS
    // ======================================================
    receive() external payable {}
    fallback() external payable {}
}
"
    },
    "contracts/libraries/SafeTransferLib.sol": {
      "content": "
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

library SafeTransferLib {
    function safeTransferETH(address to, uint256 amount) internal {
        (bool ok, ) = to.call{value: amount}("");
        require(ok, "ETH_TRANSFER_FAIL");
    }
}
"
    }
  },
  "settings": {
    "remappings": [
      "forge-std/=lib/forge-std/src/"
    ],
    "optimizer": {
      "enabled": true,
      "runs": 400
    },
    "metadata": {
      "useLiteralContent": false,
      "bytecodeHash": "ipfs",
      "appendCBOR": true
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "evmVersion": "cancun",
    "viaIR": true
  }
}}

Tags:
DeFi, Swap, Factory|addr:0xf9f1b276fc465200a1451c1efc1da094689a754f|verified:true|block:23683611|tx:0x0cb698815ea73110437a9eac3f4558fbdd1d728a251cd03d9b85297f308313d3|first_check:1761754926

Submitted on: 2025-10-29 17:22:06

Comments

Log in to comment.

No comments yet.