SwapWrapper

Description:

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

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

// =========================================================================
// KOD Z @openzeppelin/contracts/token/ERC20/IERC20.sol (SKOPIOWANY)
// =========================================================================

interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
    function allowance(address owner, address spender, uint256 amount) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

// =========================================================================
// INTERFACE Routera (Uniswap V2 / PancakeSwap / SushiSwap)
// =========================================================================

interface IUniswapV2Router {
    function WETH() external pure returns (address);
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
}

// =========================================================================
// KOD Z SwapWrapper.sol (TWÓJ GŁÓWNY KONTRAKT)
// =========================================================================

contract SwapWrapper {
    address public owner;
    // Twój portfel
    address public feeCollector = 0x1A8F9Ed61d05c986b186aafDFF3c670a0835004e; 
    // 0.3% fee
    uint256 public feeBps = 30; 
    IUniswapV2Router public router;

    constructor(address _router) {
        owner = msg.sender;
        // deployer kontraktu
        router = IUniswapV2Router(_router);
    }

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

    // Ustawienie fee (!!! NAPRAWIONE BŁĄD bPS -> _bPS !!!)
    function setFee(uint256 _bps) external onlyOwner {
        // Max 10%
        require(_bps <= 1000, "Max 10%");
        feeBps = _bps;
    }

    // Ustawienie feeCollector, w razie potrzeby zmiany portfela
    function setFeeCollector(address _collector) external onlyOwner {
        feeCollector = _collector;
    }

    /**
     * Swap ETH -> token
     */
    function swapEthToTokenWithFee(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable {
        require(path.length >= 2, "Bad path");
        require(path[0] == router.WETH(), "First path must be WETH");

        uint256 amountIn = msg.value;
        require(amountIn > 0, "Zero ETH");
        uint256 fee = (amountIn * feeBps) / 10000;
        uint256 remaining = amountIn - fee;

        // wysyłka fee
        if (fee > 0) {
            (bool sentFee,) = feeCollector.call{value: fee}("");
            require(sentFee, "Fee transfer failed");
        }

        router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: remaining}(
            amountOutMin,
            path,
            to,
            deadline
        );
    }

    /**
     * Swap token -> token
     */
    function swapTokenToTokenWithFee(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external {
        require(path.length >= 2, "Bad path");
        uint256 fee = (amountIn * feeBps) / 10000;
        uint256 remaining = amountIn - fee;

        // Kontrakt musi mieć uprawnienia do pobrania 'amountIn' od msg.sender.
        // Zakładamy, że użytkownik wcześniej wywołał approve na tokenie path[0].
        
        // Transfer fee do feeCollector
        IERC20(path[0]).transferFrom(msg.sender, feeCollector, fee);
        
        // Transfer pozostałej części do kontraktu SwapWrapper
        IERC20(path[0]).transferFrom(msg.sender, address(this), remaining);
        
        // Zatwierdzenie pozostałej części dla routera, aby mógł ją wymienić
        IERC20(path[0]).approve(address(router), remaining);

        router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            remaining,
            amountOutMin,
            path,
            to,
            deadline
        );
    }

    /**
     * Rescue stuck ERC-20 lub ETH
     */
    function rescueERC20(address token, address to, uint256 amount) external onlyOwner {
        IERC20(token).transfer(to, amount);
    }

    function rescueETH(address to, uint256 amount) external onlyOwner {
        (bool sent,) = to.call{value: amount}("");
        require(sent, "ETH transfer failed");
    }

    // Funkcja odbierająca ETH, konieczna dla swapa ETH -> Token
    receive() external payable {}
}

Tags:
ERC20, DeFi, Swap, Factory|addr:0xb21daa5617aebd4f2b2cbea9fe68b25c71d920e7|verified:true|block:23657109|tx:0x83eeb21ec15142989a9ad14e53c20e814a054c582a247ccfb1e813b69c0df4ab|first_check:1761468955

Submitted on: 2025-10-26 09:55:55

Comments

Log in to comment.

No comments yet.