Contract 0x067170777BA8027cED27E034102D54074d062d71 8

 

Contract Overview

Balance:
0.000376191800479599 ETH

EtherValue:
$1.16 (@ $3,082.44/ETH)

Token:
Txn Hash Method
Block
From
To
Value
0x1ab203c9f2ed5a4b42560cf2040bfe3bc32e7a36d8b28841a07a491e281c4a8eSwap Balance132306792024-04-16 6:58:255 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003693779711.516576743
0x6454847aef4a75b6797d2f9874e8dd7b0c841ed0cefc5891d4a619f3b44ac374Swap Balance132303792024-04-16 6:48:2515 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0005322652581.518542177
0x82de22754c32c892c68085518e1bb02ce2d280ebf15464d7473de9d94a824bdeSwap Balance132300782024-04-16 6:38:2325 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003025687491.51982472
0x7e1281dc6486f8df74a170c41494d502ed2d8989f11eaa1697890aef8bdb57e9Swap Balance132297842024-04-16 6:28:3534 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003094318161.52095404
0x549206a1c9653cab877181ecf9895f7da8e624e92a986b89911429c4060ca0baSwap Balance132285822024-04-16 5:48:311 hr 15 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0002843777431.518144901
0xc50a31658f01552b15fded378a246dd30648ffe00c39bac9a3e5ae2bbaad4bebSwap Balance132285782024-04-16 5:48:231 hr 15 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0006018307491.51819813
0x9a2408370163638dd598dbab8d00391ef0adc49faac84a68caea4571ea8c0083Swap Balance132279792024-04-16 5:28:251 hr 35 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0005941859041.526822641
0x7d24449d9ab5c925e807914e51d093fff8dfa70f96435ad50880e4004d3dc0e4Swap Balance132270792024-04-16 4:58:252 hrs 5 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0006630423521.534837486
0x9e43b7eee958ca00da2ff253f0aa4ef9c45214fbc6f30dbd9e03e1b6a2a72147Swap Balance132264812024-04-16 4:38:292 hrs 25 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0002876824861.525142537
0x1a51080ca5a64749139b532d34ecb5cc1af281d0e1965859dcf56504ddb892d5Swap Balance132264772024-04-16 4:38:212 hrs 25 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0005853580821.52494305
0x30a19475ec7c29bbe6c8267fcaa14b7cf6a9ba5970cbbefe83279001d8558163Swap Balance132258782024-04-16 4:18:232 hrs 45 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003599335241.525911167
0xf68d9fbbe10681b4aac131cfd5f32117f961358c96467a1ddb5ba16b0fd3d87cSwap Balance132255792024-04-16 4:08:252 hrs 55 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003812640451.522066259
0x424a1621ae3dc21432cb62a34e57059d8bf9a24fe41dacc08f6f8e840a3a8865Swap Balance132252802024-04-16 3:58:273 hrs 5 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.000284857391.522920279
0x31330f267919b5c0e6766a0091ed9194490a2a247b6f92af7ace7d7807e56d0eSwap Balance132252762024-04-16 3:58:193 hrs 5 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0005287745381.522974628
0x9cc029294eac5f6e6fe889049e5193ae4ce8695821c98797ad18fc999d48c552Swap Balance132243782024-04-16 3:28:233 hrs 35 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0004205089921.522900914
0x00941878d6e3b9199242ac43deeb0fe91aaf6d671ae3e13dc831eee5c3037c9dSwap Balance132240792024-04-16 3:18:253 hrs 45 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003154213441.527915043
0x9f1b715422da37aca73494d3a747b2c7c69757c32d4757c64005afe84d0e09a2Swap Balance132237772024-04-16 3:08:213 hrs 55 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003114386051.531472385
0x599c36efc717d55caf36d24504d3fee0d269fd5421857b99f07ce9ba617aebd0Swap Balance132231802024-04-16 2:48:274 hrs 15 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0006119100611.540543475
0xea6a45872c11d09a98b4498b963d73ff1de63de82f8d03e7daade25aa09f2a59Swap Balance132228802024-04-16 2:38:274 hrs 25 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0002862546771.539516098
0xe11b6eca2cd58d5b0fad378828ae34613aa8bda2b6c84d0ff0378f8fb3057251Swap Balance132228762024-04-16 2:38:194 hrs 25 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0008397650961.539571288
0x3d082d667950f053e3305a3f2661372c3010a6eac2e45118a2fc2797112192eeSwap Balance132225792024-04-16 2:28:254 hrs 35 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003666225351.535372261
0xf4d439a75a1fdad5baa728abc37b5d9eb715103289516eaa6c5883e106d68491Swap Balance132222762024-04-16 2:18:194 hrs 45 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003592653071.533148718
0x5478dd6a511af3216d51d471d7f5aad7d40c3925571de6117db0c60cea2ae89fSwap Balance132219792024-04-16 2:08:254 hrs 55 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0005324149061.531356178
0xf528a526790eada6c38be8550de383758f2d68670f1e2ff954224e82a796d516Swap Balance132216792024-04-16 1:58:255 hrs 5 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003881541111.530069918
0x330b1941a30c4fa49b6b56dc6af7d017c991d99bd81a0e0359e53abb2a6092e6Swap Balance132213822024-04-16 1:48:315 hrs 15 mins ago0xbe84d31b2ee049dcb1d8e7c798511632b44d1b55 IN  0x067170777ba8027ced27e034102d54074d062d710 ETH0.0003326923821.528416605
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xe95152b07b38c95cc03c6c2ec364b712d26fd7956d6ba90071d3914b5af5faa6131680542024-04-14 20:10:551 day 10 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000008946433558986 ETH
0x95c28962079dad3eba10ad2aaf0d8ca8be26b32813c7848849f2ab5e53b0d332131345202024-04-14 1:33:072 days 5 hrs ago 0x332d3cf8bbb5fce8bd35b0ece778c07a39343976 0x067170777ba8027ced27e034102d54074d062d710.000001924664633795 ETH
0x7a02eb8bc834db7024a9a9c0596872fd7bc919ba305d7f3cc31e8fd4ef0e8131130484262024-04-12 1:43:194 days 5 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000002550250330791 ETH
0xf04480ad2c60275e49f87a0366b6e4585762ba1554049e2dd99aa46b9215b670130481022024-04-12 1:32:314 days 5 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000050270340788687 ETH
0xdc77f5bf496d2f60fa624eea834012351d834352e1d869262d9e23e53f34b6f8130472592024-04-12 1:04:254 days 5 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000002759388450033 ETH
0x5f6fd7d18372fc13f24e1688178c1dc42aa4f4f2976947e72129081b6836f1c3130470622024-04-12 0:57:514 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000005235290270219 ETH
0x1acc29adc3b9698e954caae112001db67763d66f6c02c66e3150b2edae980d8b130470002024-04-12 0:55:474 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000043561401075613 ETH
0xcfac2686f453dea1b458324c0b22271937239dfdf5ac392623d541dbbf669733130466112024-04-12 0:42:494 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.00000516850675573 ETH
0xf11a039420c55b632c6415d333759473f43ad2267f3a8864cd0aacae879a9b63130466062024-04-12 0:42:394 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000008597427792459 ETH
0x0df099f456da4e3f7a14657af7108d5ed3597fd9d81210182cb1bed5c1afb7bd130462902024-04-12 0:32:074 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000003310602076176 ETH
0xe46c6c4093e98318028a964646f179d11ec5f85c0c6b903b117e35b35d4862a5130462592024-04-12 0:31:054 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000003081428693207 ETH
0xd4c183f8fc07aa6450c7a30715ad82c8e43152a9b919411e960ae6af9f96b500130460522024-04-12 0:24:114 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.00000298826828847 ETH
0x97e5dc68b4bfaa30921d2f8a331790811f86db83577e0c23ffbd810da187553f130460342024-04-12 0:23:354 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000014484455553059 ETH
0xcf3da3367ad9987121c7b3025d4001254e8ac776cf5fd3593b3f29dd6d04b6fd130455292024-04-12 0:06:454 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000002863420565983 ETH
0x45b5da2292b4170a4d5b7b86c7b7594faf16a86d05cecb734c750e9c389eb9b7130454962024-04-12 0:05:394 days 6 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000158584457941521 ETH
0x5d60a536a9c943bf8d74ba854d682179cf8430ebe92eca53a1be7ece00fc37fa130453952024-04-12 0:02:174 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000003137854844957 ETH
0x7090e909d316d1a0632281028dd399263c9dde211d2827911db88e183f4beb67130453762024-04-12 0:01:394 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000002972596125795 ETH
0x19d88be1c9b0659a85cbb2b875a4a832c98adda2228536a15a1f55a2179d91f5130453662024-04-12 0:01:194 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000002886663110848 ETH
0xf1ac5af525fc366b71ca3b424aad73512f210caeda1989b3a8c8935840813384130452882024-04-11 23:58:434 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000003718396279513 ETH
0xfcdb903b57125d152a1c3431a6bcf0cb220064c12f9627853d213c06323cf2ae130451902024-04-11 23:55:274 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000017522709825539 ETH
0x6c94f9524f5a0e8fb59a5e6b138513f1a786c4cae9f535f17c058347ea3061c2130450822024-04-11 23:51:514 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000005618967431913 ETH
0x1c772a1db64c86b27b81f4d19de6c089e09e6d85e41998c54806bbbd1af7676a130449462024-04-11 23:47:194 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000009592853969054 ETH
0x1a3c1e364534d2d5d8666c3c3217b0b5d08affa80185cbf8f04d6c6359724a10130446432024-04-11 23:37:134 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000001937169718132 ETH
0x8a54387d9bb4f1687e963e1880df8e59e2d433e86cbe99ca89a6c98190ddac72130446422024-04-11 23:37:114 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000001816563480806 ETH
0x53ae63f168f0408252ef04a57b309f0fa0ec31addd7ed59f9952ca85f9770a99130446122024-04-11 23:36:114 days 7 hrs ago 0xbce464703fbac06df8e738a4642d2f3585513255 0x067170777ba8027ced27e034102d54074d062d710.000003634550201722 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FeeCollector

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 8 : FeeCollector.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {Owned} from "solmate/auth/Owned.sol";
import {ERC20} from "solmate/tokens/ERC20.sol";
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";
import {IFeeCollector} from "./interfaces/IFeeCollector.sol";
import {IPermit2} from "./external/IPermit2.sol";

/// @notice The collector of protocol fees that will be used to swap and send to a fee recipient address.
contract FeeCollector is Owned, IFeeCollector {
    using SafeTransferLib for ERC20;

    error UniversalRouterCallFailed();

    address private immutable universalRouter;

    ERC20 private immutable feeToken;
    IPermit2 private immutable permit2;

    uint256 private constant MAX_APPROVAL_AMOUNT = type(uint256).max;
    uint160 private constant MAX_PERMIT2_APPROVAL_AMOUNT = type(uint160).max;
    uint48 private constant MAX_PERMIT2_DEADLINE = type(uint48).max;

    constructor(address _owner, address _universalRouter, address _permit2, address _feeToken) Owned(_owner) {
        universalRouter = _universalRouter;
        feeToken = ERC20(_feeToken);
        permit2 = IPermit2(_permit2);
    }

    /// @inheritdoc IFeeCollector
    function swapBalance(bytes calldata swapData, uint256 nativeValue) external onlyOwner {
        _execute(swapData, nativeValue);
    }

    /// @inheritdoc IFeeCollector
    function swapBalance(bytes calldata swapData, uint256 nativeValue, ERC20[] calldata tokensToApprove)
        external
        onlyOwner
    {
        unchecked {
            for (uint256 i = 0; i < tokensToApprove.length; i++) {
                tokensToApprove[i].safeApprove(address(permit2), MAX_APPROVAL_AMOUNT);
                permit2.approve(
                    address(tokensToApprove[i]), universalRouter, MAX_PERMIT2_APPROVAL_AMOUNT, MAX_PERMIT2_DEADLINE
                );
            }
        }

        _execute(swapData, nativeValue);
    }

    /// @notice Helper function to call UniversalRouter.
    /// @param swapData The bytes call data to be forwarded to UniversalRouter.
    /// @param nativeValue The amount of native currency to send to UniversalRouter.
    function _execute(bytes calldata swapData, uint256 nativeValue) internal {
        (bool success,) = universalRouter.call{value: nativeValue}(swapData);
        if (!success) revert UniversalRouterCallFailed();
    }

    /// @inheritdoc IFeeCollector
    function withdrawFeeToken(address feeRecipient, uint256 amount) external onlyOwner {
        feeToken.safeTransfer(feeRecipient, amount);
    }

    receive() external payable {}
}

File 2 of 8 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

File 3 of 8 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 4 of 8 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

File 5 of 8 : IFeeCollector.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.13;

import {ERC20} from "solmate/tokens/ERC20.sol";

/// @notice The collector of protocol fees that will be used to swap and send to a fee recipient address.
interface IFeeCollector {
    /// @notice Swaps the contract balance.
    /// @param swapData The bytes call data to be forwarded to UniversalRouter.
    /// @param nativeValue The amount of native currency to send to UniversalRouter.
    function swapBalance(bytes calldata swapData, uint256 nativeValue) external;

    /// @notice Approves tokens for swapping and then swaps the contract balance.
    /// @param swapData The bytes call data to be forwarded to UniversalRouter.
    /// @param nativeValue The amount of native currency to send to UniversalRouter.
    /// @param tokensToApprove An array of ERC20 tokens to approve for spending.
    function swapBalance(bytes calldata swapData, uint256 nativeValue, ERC20[] calldata tokensToApprove) external;

    /// @notice Transfers the fee token balance from this contract to the fee recipient.
    /// @param feeRecipient The address to send the fee token balance to.
    /// @param amount The amount to withdraw.
    function withdrawFeeToken(address feeRecipient, uint256 amount) external;
}

File 6 of 8 : IPermit2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IAllowanceTransfer} from "./IAllowanceTransfer.sol";

/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.
/// @dev Users must approve Permit2 before calling any of the transfer functions.
interface IPermit2 is IAllowanceTransfer {
// IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.
}

File 7 of 8 : IAllowanceTransfer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IEIP712} from "./IEIP712.sol";

/// @title AllowanceTransfer
/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts
/// @dev Requires user's token approval on the Permit2 contract
interface IAllowanceTransfer is IEIP712 {
    /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.
    /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]
    /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.
    function allowance(address user, address token, address spender)
        external
        view
        returns (uint160 amount, uint48 expiration, uint48 nonce);

    /// @notice Approves the spender to use up to amount of the specified token up until the expiration
    /// @param token The token to approve
    /// @param spender The spender address to approve
    /// @param amount The approved amount of the token
    /// @param expiration The timestamp at which the approval is no longer valid
    /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve
    /// @dev Setting amount to type(uint160).max sets an unlimited approval
    function approve(address token, address spender, uint160 amount, uint48 expiration) external;
}

File 8 of 8 : IEIP712.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IEIP712 {
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/permit2/lib/openzeppelin-contracts/",
    "permit2/=lib/permit2/",
    "solmate/=lib/solmate/src/",
    "v2-core/=lib/v2-core/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_universalRouter","type":"address"},{"internalType":"address","name":"_permit2","type":"address"},{"internalType":"address","name":"_feeToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"UniversalRouterCallFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"swapData","type":"bytes"},{"internalType":"uint256","name":"nativeValue","type":"uint256"}],"name":"swapBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"swapData","type":"bytes"},{"internalType":"uint256","name":"nativeValue","type":"uint256"},{"internalType":"contract ERC20[]","name":"tokensToApprove","type":"address[]"}],"name":"swapBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"feeRecipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFeeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e060405234801561001057600080fd5b506040516108df3803806108df83398101604081905261002f916100b1565b600080546001600160a01b0319166001600160a01b03861690811782556040518692907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160a01b03928316608052821660a0521660c05250610105565b80516001600160a01b03811681146100ac57600080fd5b919050565b600080600080608085870312156100c757600080fd5b6100d085610095565b93506100de60208601610095565b92506100ec60408601610095565b91506100fa60608601610095565b905092959194509250565b60805160a05160c05161079d610142600039600081816101f70152610252015260006101920152600081816102cc01526103d3015261079d6000f3fe60806040526004361061004e5760003560e01c80631ac169861461005a5780638da5cb5b1461007c578063b2ef14e3146100b8578063bbf20c15146100d8578063f2fde38b146100f857600080fd5b3661005557005b600080fd5b34801561006657600080fd5b5061007a6100753660046105c0565b610118565b005b34801561008857600080fd5b5060005461009c906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b3480156100c457600080fd5b5061007a6100d3366004610624565b61015b565b3480156100e457600080fd5b5061007a6100f3366004610650565b6101bd565b34801561010457600080fd5b5061007a6101133660046106f7565b61035a565b6000546001600160a01b0316331461014b5760405162461bcd60e51b81526004016101429061071b565b60405180910390fd5b6101568383836103cf565b505050565b6000546001600160a01b031633146101855760405162461bcd60e51b81526004016101429061071b565b6101b96001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168383610476565b5050565b6000546001600160a01b031633146101e75760405162461bcd60e51b81526004016101429061071b565b60005b81811015610347576102507f000000000000000000000000000000000000000000000000000000000000000060001985858581811061022b5761022b610741565b905060200201602081019061024091906106f7565b6001600160a01b031691906104f7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166387517c4584848481811061029157610291610741565b90506020020160208101906102a691906106f7565b6040516001600160e01b031960e084901b1681526001600160a01b0391821660048201527f000000000000000000000000000000000000000000000000000000000000000082166024820152604481019190915265ffffffffffff6064820152608401600060405180830381600087803b15801561032357600080fd5b505af1158015610337573d6000803e3d6000fd5b5050600190920191506101ea9050565b506103538585856103cf565b5050505050565b6000546001600160a01b031633146103845760405162461bcd60e51b81526004016101429061071b565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031682858560405161040c929190610757565b60006040518083038185875af1925050503d8060008114610449576040519150601f19603f3d011682016040523d82523d6000602084013e61044e565b606091505b50509050806104705760405163cee8b77760e01b815260040160405180910390fd5b50505050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806104705760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610142565b600060405163095ea7b360e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806104705760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b6044820152606401610142565b60008083601f84011261058957600080fd5b50813567ffffffffffffffff8111156105a157600080fd5b6020830191508360208285010111156105b957600080fd5b9250929050565b6000806000604084860312156105d557600080fd5b833567ffffffffffffffff8111156105ec57600080fd5b6105f886828701610577565b909790965060209590950135949350505050565b6001600160a01b038116811461062157600080fd5b50565b6000806040838503121561063757600080fd5b82356106428161060c565b946020939093013593505050565b60008060008060006060868803121561066857600080fd5b853567ffffffffffffffff8082111561068057600080fd5b61068c89838a01610577565b90975095506020880135945060408801359150808211156106ac57600080fd5b818801915088601f8301126106c057600080fd5b8135818111156106cf57600080fd5b8960208260051b85010111156106e457600080fd5b9699959850939650602001949392505050565b60006020828403121561070957600080fd5b81356107148161060c565b9392505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b818382376000910190815291905056fea264697066735822122037bdcf04c668f6b3803f7db34f6a1d9cca1083f77a1b65ee311aec8d127d7abb64736f6c634300081300330000000000000000000000003c6d5c150ee29b698c6c821b53886c41d239669c000000000000000000000000198ef79f1f515f02dfe9e3115ed9fc07183f02fc000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913

Deployed Bytecode

0x60806040526004361061004e5760003560e01c80631ac169861461005a5780638da5cb5b1461007c578063b2ef14e3146100b8578063bbf20c15146100d8578063f2fde38b146100f857600080fd5b3661005557005b600080fd5b34801561006657600080fd5b5061007a6100753660046105c0565b610118565b005b34801561008857600080fd5b5060005461009c906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b3480156100c457600080fd5b5061007a6100d3366004610624565b61015b565b3480156100e457600080fd5b5061007a6100f3366004610650565b6101bd565b34801561010457600080fd5b5061007a6101133660046106f7565b61035a565b6000546001600160a01b0316331461014b5760405162461bcd60e51b81526004016101429061071b565b60405180910390fd5b6101568383836103cf565b505050565b6000546001600160a01b031633146101855760405162461bcd60e51b81526004016101429061071b565b6101b96001600160a01b037f000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913168383610476565b5050565b6000546001600160a01b031633146101e75760405162461bcd60e51b81526004016101429061071b565b60005b81811015610347576102507f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba360001985858581811061022b5761022b610741565b905060200201602081019061024091906106f7565b6001600160a01b031691906104f7565b7f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba36001600160a01b03166387517c4584848481811061029157610291610741565b90506020020160208101906102a691906106f7565b6040516001600160e01b031960e084901b1681526001600160a01b0391821660048201527f000000000000000000000000198ef79f1f515f02dfe9e3115ed9fc07183f02fc82166024820152604481019190915265ffffffffffff6064820152608401600060405180830381600087803b15801561032357600080fd5b505af1158015610337573d6000803e3d6000fd5b5050600190920191506101ea9050565b506103538585856103cf565b5050505050565b6000546001600160a01b031633146103845760405162461bcd60e51b81526004016101429061071b565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b60007f000000000000000000000000198ef79f1f515f02dfe9e3115ed9fc07183f02fc6001600160a01b031682858560405161040c929190610757565b60006040518083038185875af1925050503d8060008114610449576040519150601f19603f3d011682016040523d82523d6000602084013e61044e565b606091505b50509050806104705760405163cee8b77760e01b815260040160405180910390fd5b50505050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806104705760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610142565b600060405163095ea7b360e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806104705760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b6044820152606401610142565b60008083601f84011261058957600080fd5b50813567ffffffffffffffff8111156105a157600080fd5b6020830191508360208285010111156105b957600080fd5b9250929050565b6000806000604084860312156105d557600080fd5b833567ffffffffffffffff8111156105ec57600080fd5b6105f886828701610577565b909790965060209590950135949350505050565b6001600160a01b038116811461062157600080fd5b50565b6000806040838503121561063757600080fd5b82356106428161060c565b946020939093013593505050565b60008060008060006060868803121561066857600080fd5b853567ffffffffffffffff8082111561068057600080fd5b61068c89838a01610577565b90975095506020880135945060408801359150808211156106ac57600080fd5b818801915088601f8301126106c057600080fd5b8135818111156106cf57600080fd5b8960208260051b85010111156106e457600080fd5b9699959850939650602001949392505050565b60006020828403121561070957600080fd5b81356107148161060c565b9392505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b818382376000910190815291905056fea264697066735822122037bdcf04c668f6b3803f7db34f6a1d9cca1083f77a1b65ee311aec8d127d7abb64736f6c63430008130033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000003c6d5c150ee29b698c6c821b53886c41d239669c000000000000000000000000198ef79f1f515f02dfe9e3115ed9fc07183f02fc000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913

-----Decoded View---------------
Arg [0] : _owner (address): 0x3c6D5c150EE29B698c6C821B53886C41d239669c
Arg [1] : _universalRouter (address): 0x198EF79F1F515F02dFE9e3115eD9fC07183f02fC
Arg [2] : _permit2 (address): 0x000000000022D473030F116dDEE9F6B43aC78BA3
Arg [3] : _feeToken (address): 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000003c6d5c150ee29b698c6c821b53886c41d239669c
Arg [1] : 000000000000000000000000198ef79f1f515f02dfe9e3115ed9fc07183f02fc
Arg [2] : 000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3
Arg [3] : 000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.