Agent

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/Agent.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

import "contracts/SafeERC20.sol";
import "contracts/IERC20.sol";
import "contracts/IUniswapV2Pair.sol";
import "contracts/IUniswapV2Router.sol";

// This contract simply calls multiple targets sequentially, ensuring WETH balance before and after

contract Agent {
    // using SafeERC20 for IERC20;

    address private immutable owner;
    address private immutable executor;

    address private constant WETH_ADDR = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
    IERC20 private constant WETH = IERC20(WETH_ADDR);

    modifier onlyExecutor() {
        require(msg.sender == executor);
        _;
    }

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

    constructor() {
        executor = msg.sender;
        owner = address(0x1b7BC083290bc24EdA9a24ff44aB974Da44c752a);
    }

    /// WETH -> token via pair, send WETH then swap
    function sB(address pairAddress, uint256 amount0Out, uint256 amount1Out, uint256 amountIn) external onlyExecutor {
        _safeTransfer(WETH_ADDR, pairAddress, amountIn);
        IUniswapV2Pair(pairAddress).swap(amount0Out, amount1Out, address(this), bytes(""));
    }

    function sB_Ex(address _router, address _pair, address _token, uint256 amountIn, uint256 amountOutMin, bool token0) external onlyExecutor {
        IUniswapV2Pair pair = IUniswapV2Pair(_pair);
        IUniswapV2Router router = IUniswapV2Router(_router);
        address[] memory path =  new address[](2);
        path[0] = WETH_ADDR;
        path[1] = _token;
        uint256[] memory amounts = router.getAmountsOut(amountIn, path);
        require(amounts[1] >= amountOutMin, '!amountOutMin');
        WETH.transfer(_pair, amountIn);
        pair.swap(token0 ? 0 : amounts[1], token0 ? amounts[1] : 0, address(this), new bytes(0));
    }

    // token -> token via pair; forwards provided token amount then swap; tips miner with any ETH balance
    function sS(address pairAddress, address tokenAddress, uint256 amount0Out, uint256 amount1Out, uint256 amountIn) external onlyExecutor {
        _safeTransfer(tokenAddress, pairAddress, amountIn);
        IUniswapV2Pair(pairAddress).swap(amount0Out, amount1Out, address(this), bytes(""));

        uint256 bal = address(this).balance;
        if (bal != 0) {
            // send available ETH (e.g., MEV tip) to coinbase
            // (still uses transfer to keep behavior; can switch to call for stipend issues)
            block.coinbase.transfer(bal);
        }
    }

    function sS_Ex(address _router, address _pair, address _token, uint256 amountOutMin, bool token0) external onlyExecutor payable {
        IUniswapV2Pair pair = IUniswapV2Pair(_pair);
        IERC20 token = IERC20(_token);
        uint256 balance = token.balanceOf(address(this));
        token.transfer(_pair, balance);
        IUniswapV2Router router = IUniswapV2Router(_router);
        address[] memory path =  new address[](2);
        path[0] = _token;
        path[1] = WETH_ADDR;
        uint256[] memory amounts = router.getAmountsOut(balance, path);
        require(amounts[1] >= amountOutMin, '!amountOutMin');
        pair.swap(token0 ? amounts[1] : 0, token0 ? 0 : amounts[1], address(this), new bytes(0));
        if (address(this).balance > 0) {
            block.coinbase.transfer(address(this).balance);
        }
    }

    function sendBribe(uint256 amount) external onlyExecutor {
        block.coinbase.transfer(amount);
    }

    function sW(address _token, address _to, uint256 _amount) external onlyOwner {
        require(IERC20(_token).balanceOf(address(this)) >= _amount, "bal");
        if (_token == WETH_ADDR) {
            WETH.withdraw(_amount);
            _safeTransferETH(_to, _amount);
        } else {
            _safeTransfer(_token, _to, _amount); // works with USDT-style tokens
        }
    }

    receive() external payable {
    }

    function call(address payable _to, uint256 _value, bytes calldata _data) external onlyOwner payable returns (bytes memory) {
        require(_to != address(0));
        (bool _success, bytes memory _result) = _to.call{value: _value}(_data);
        require(_success);
        return _result;
    }

    // ===== internal helpers =====

    function _safeTransfer(address token, address to, uint256 value) internal {
        // (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "xfer");
    }

    function _safeTransferETH(address to, uint256 value) internal {
        (bool ok, ) = to.call{value: value}("");
        require(ok, "eth");
    }
}
"
    },
    "contracts/IUniswapV2Router.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

interface IUniswapV2Router {
    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

     function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
}"
    },
    "contracts/IUniswapV2Pair.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

interface IUniswapV2Pair {
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function token0() external view returns (address);
    function token1() external view returns (address);
}"
    },
    "contracts/IERC20.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

interface IERC20 {
    function transfer(address to, uint value) external returns (bool);
    function balanceOf(address) external returns (uint256);
    function deposit() external payable;
    function withdraw(uint256 amount) external;
}"
    },
    "contracts/SafeERC20.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

library SafeERC20 {
    function safeTransfer(address token, address to, uint256 amount) internal {
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(bytes4(keccak256("transfer(address,uint256)")), to, amount)
        );
        require(success, "Transfer failed");

        // If the token returns data, it should be true; if not, assume success
        if (data.length > 0) {
            require(abi.decode(data, (bool)), "Transfer returned false");
        }
    }

    function safeApprove(address token, address spender, uint256 amount) internal {
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(bytes4(keccak256("approve(address,uint256)")), spender, amount)
        );
        require(success, "Approve failed");

        if (data.length > 0) {
            require(abi.decode(data, (bool)), "Approve returned false");
        }
    }
}"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": []
  }
}}

Tags:
DeFi, Swap, Factory|addr:0xf33f86e550c36e61e44f7cfe98fe278c5ac33a9f|verified:true|block:23419219|tx:0xc772b85aa075c0e207b932df9ae15e79d6e6f42eb68b80a148f0a7445234c278|first_check:1758555604

Submitted on: 2025-09-22 17:40:04

Comments

Log in to comment.

No comments yet.