Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xD7C7ff50Ac296F58969Cee5Ad217dd012ED40352
Balance 0 ETH
Nonce 1
Code Size 3916 bytes
Indexed Transactions Index loading...
External Etherscan · Sourcify

Contract Bytecode

3916 bytes
0x6080604052600436101561001d575b366102b15761001b610f0c565b005b6100275f35610086565b80633ef13367146100815780636b9f96ea1461007c5780638f84aa091461007757806396a4154e14610072578063a6f9dae11461006d5763feb0a1410361000e5761027c565b61023a565b610207565b6101d2565b610139565b6100f7565b60e01c90565b60405190565b5f80fd5b5f80fd5b60018060a01b031690565b6100ae9061009a565b90565b6100ba816100a5565b036100c157565b5f80fd5b905035906100d2826100b1565b565b906020828203126100ed576100ea915f016100c5565b90565b610096565b5f0190565b346101255761010f61010a3660046100d4565b610828565b61011761008c565b80610121816100f2565b0390f35b610092565b5f91031261013457565b610096565b346101675761014936600461012a565b610151610a8f565b61015961008c565b80610163816100f2565b0390f35b610092565b1c90565b60018060a01b031690565b61018b906008610190930261016c565b610170565b90565b9061019e915461017b565b90565b6101ad60015f90610193565b90565b6101b9906100a5565b9052565b91906101d0905f602085019401906101b0565b565b34610202576101e236600461012a565b6101fe6101ed6101a1565b6101f561008c565b918291826101bd565b0390f35b610092565b346102355761021f61021a3660046100d4565b610c2d565b61022761008c565b80610231816100f2565b0390f35b610092565b346102685761025261024d3660046100d4565b610d5a565b61025a61008c565b80610264816100f2565b0390f35b610092565b61027960025f90610193565b90565b346102ac5761028c36600461012a565b6102a861029761026d565b61029f61008c565b918291826101bd565b0390f35b610092565b5f80fd5b5f1c90565b6102c66102cb916102b5565b610170565b90565b6102d890546102ba565b90565b336102f76102f16102ec60016102ce565b6100a5565b916100a5565b14158061032a575b61030e5761030c90610625565b565b5f63ea8e4eb560e01b815280610326600482016100f2565b0390fd5b503361034761034161033c60026102ce565b6100a5565b916100a5565b14156102ff565b90565b61036561036061036a9261009a565b61034e565b61009a565b90565b61037690610351565b90565b6103829061036d565b90565b61038e90610351565b90565b61039a90610385565b90565b6103a690610385565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103d1906103a9565b810190811067ffffffffffffffff8211176103eb57604052565b6103b3565b60e01b90565b90565b610402816103f6565b0361040957565b5f80fd5b9050519061041a826103f9565b565b9060208282031261043557610432915f0161040d565b90565b610096565b61044261008c565b3d5f823e3d90fd5b90565b61046161045c6104669261044a565b61034e565b6103f6565b90565b63ffffffff1690565b63ffffffff60e01b1690565b61049261048d61049792610469565b6103f0565b610472565b90565b6104a3906103f6565b9052565b9160206104c89294936104c160408201965f8301906101b0565b019061049a565b565b906104dd6104d661008c565b92836103c7565b565b67ffffffffffffffff81116104fd576104f96020916103a9565b0190565b6103b3565b9061051461050f836104df565b6104ca565b918252565b606090565b3d5f146105395761052e3d610502565b903d5f602084013e5b565b610541610519565b90610537565b151590565b5190565b61055981610547565b0361056057565b5f80fd5b9050519061057182610550565b565b9060208282031261058c57610589915f01610564565b90565b610096565b60209181520190565b5f7f546f6b656e20666c757368000000000000000000000000000000000000000000910152565b6105ce600b602092610591565b6105d78161059a565b0190565b6105f09060208101905f8183039101526105c1565b90565b60409061061c610623949695939661061260608401985f8501906101b0565b602083019061049a565b01906101b0565b565b61062e81610379565b9061066f602061063d84610391565b6370a082319061066461064f3061039d565b9261065861008c565b958694859384936103f0565b8352600483016101bd565b03915afa908115610823575f916107f5575b5091826106966106905f61044d565b916103f6565b146107d9575f6106a68192610391565b60046106ee6106b863a9059cbb61047e565b6106df6106c560016102ce565b89906106cf61008c565b95869460208601908152016104a7565b602082018103825203826103c7565b82602082019151925af161070a61070361051e565b9115610547565b908115610781575b5061075e576107203061039d565b9190916107597fb4bdccee2343c0b5e592d459c20eb1fa451c96bf88fb685a11aecda6b4ec76b19361075061008c565b938493846105f3565b0390a1565b61076661008c565b6312dfddb360e01b81528061077d600482016105db565b0390fd5b905061078c8161054c565b61079e6107985f61044d565b916103f6565b141590816107ae575b505f610712565b6107d391506107cd9060206107c28261054c565b818301019101610573565b15610547565b5f6107a7565b5f631e9acf1760e31b8152806107f1600482016100f2565b0390fd5b610816915060203d811161081c575b61080e81836103c7565b81019061041c565b5f610681565b503d610804565b61043a565b610831906102db565b565b90565b610842610847916102b5565b610833565b90565b6108549054610836565b90565b90565b61086e61086961087392610857565b61034e565b6103f6565b90565b610880600261085a565b90565b5f1b90565b906108945f1991610883565b9181191691161790565b6108b26108ad6108b7926103f6565b61034e565b6103f6565b90565b90565b906108d26108cd6108d99261089e565b6108ba565b8254610888565b9055565b90565b6108f46108ef6108f9926108dd565b61034e565b6103f6565b90565b61090660016108e0565b90565b6109125f61084a565b61092b610925610920610876565b6103f6565b916103f6565b1461095c5761094161093b610876565b5f6108bd565b6109496109f1565b61095a6109546108fc565b5f6108bd565b565b5f6308605d7760e11b815280610974600482016100f2565b0390fd5b905090565b6109885f8092610978565b0190565b6109959061097d565b90565b5f7f45544820666c7573680000000000000000000000000000000000000000000000910152565b6109cc6009602092610591565b6109d581610998565b0190565b6109ee9060208101905f8183039101526109bf565b90565b6109fa3061039d565b3180610a0e610a085f61044d565b916103f6565b14610a73575f80610a4a92610a2360016102ce565b90610a2c61008c565b9081610a378161098c565b03925af1610a4361051e565b5015610547565b610a5057565b610a5861008c565b6312dfddb360e01b815280610a6f600482016109d9565b0390fd5b5f631e9acf1760e31b815280610a8b600482016100f2565b0390fd5b610a97610909565b565b33610ab5610aaf610aaa60016102ce565b6100a5565b916100a5565b03610ac557610ac390610b53565b565b5f63ea8e4eb560e01b815280610add600482016100f2565b0390fd5b610af5610af0610afa9261044a565b61034e565b61009a565b90565b610b0690610ae1565b90565b90610b1a60018060a01b0391610883565b9181191691161790565b610b2d90610385565b90565b90565b90610b48610b43610b4f92610b24565b610b30565b8254610b09565b9055565b80610b6e610b68610b635f610afd565b6100a5565b916100a5565b14610c115780610b8f610b89610b8460026102ce565b6100a5565b916100a5565b14610bf557610b9e60026102ce565b610ba9826002610b33565b90610bdd610bd77f625c25044c8d718e4765e900b5b31f518b0933e15f7738b5739377fdb315380593610b24565b91610b24565b91610be661008c565b80610bf0816100f2565b0390a3565b5f631c8cd0c760e21b815280610c0d600482016100f2565b0390fd5b5f6320278ad760e01b815280610c29600482016100f2565b0390fd5b610c3690610a99565b565b33610c54610c4e610c4960016102ce565b6100a5565b916100a5565b03610c6457610c6290610c80565b565b5f63ea8e4eb560e01b815280610c7c600482016100f2565b0390fd5b80610c9b610c95610c905f610afd565b6100a5565b916100a5565b14610d3e5780610cbc610cb6610cb160016102ce565b6100a5565b916100a5565b14610d2257610ccb60016102ce565b610cd6826001610b33565b90610d0a610d047fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c93610b24565b91610b24565b91610d1361008c565b80610d1d816100f2565b0390a3565b5f631c8cd0c760e21b815280610d3a600482016100f2565b0390fd5b5f6349e27cff60e01b815280610d56600482016100f2565b0390fd5b610d6390610c38565b565b610d6e5f61084a565b610d87610d81610d7c610876565b6103f6565b916103f6565b14610db857610d9d610d97610876565b5f6108bd565b610da5610e42565b610db6610db06108fc565b5f6108bd565b565b5f6308605d7760e11b815280610dd0600482016100f2565b0390fd5b5f7f45544820666f7277617264000000000000000000000000000000000000000000910152565b610e08600b602092610591565b610e1181610dd4565b0190565b610e2a9060208101905f818303910152610dfb565b90565b9190610e40905f6020850194019061049a565b565b610e785f80610e5160016102ce565b34610e5a61008c565b9081610e658161098c565b03925af1610e7161051e565b5015610547565b610ee95733610e863061039d565b610e9060016102ce565b903492610ee4610ed2610ecc610ec67f518f6e264ff4f299a58c6e1e9de5a14fac95f0f289b919a1e2cd628d9b6fbde094610b24565b94610b24565b94610b24565b94610edb61008c565b91829182610e2d565b0390a4565b610ef161008c565b6312dfddb360e01b815280610f0860048201610e15565b0390fd5b610f14610d65565b56fea2646970667358221220340deaaa9fd4e9d9e2369f500ee1f8f4402c7436d2bc7766372c97f8983bf87264736f6c634300081c0033

Verified Source Code Full Match

Compiler: v0.8.28+commit.7893614a EVM: cancun Optimization: No
ERC20Interface.sol 13 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

/**
 * Contract that exposes the needed ERC20 token functions
 */
interface ERC20Interface {
    // Send _value amount of tokens to address _to
    function transfer(address _to, uint256 _value) external returns (bool);

    // Get the account balance of another account with address _owner
    function balanceOf(address _owner) external view returns (uint256 balance);
}
Forwarder.sol 144 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import "./ERC20Interface.sol";

/**
 * Contract that will forward any incoming Ether and tokens to a designated destination address
 */
contract Forwarder {
    uint256 private constant _UNLOCKED = 1;
    uint256 private constant _LOCKED = 2;
    uint256 private lock;

    // Address to which any funds sent to this contract will be forwarded
    address public ownerAddress;
    // Address that can trigger flush
    address public tokenFlusherAddress;

    event ForwardedDeposit(address indexed from, address indexed to, address indexed forwardedTo, uint256 _amount);
    event TokensFlushed(address forwarderAddress, uint value, address tokenContractAddress);
    event OwnerChanged(address indexed oldOwner, address indexed newOwner);
    event TokenFlusherChanged(address indexed oldFlusher, address indexed newFlusher);

    error InvalidOwner();
    error InvalidFlusher();
    error NotAuthorized();
    error TransferFailed(string transferType);
    error InsufficientBalance();
    error NewValueMustBeDifferent();
    error ReentrantCallDetected();

    /**
     * Create the contract, and sets the owner address and token flusher address
     */
    constructor(address ownerAddress_, address tokenFlusherAddress_) {
        if (ownerAddress_ == address(0)) {
            revert InvalidOwner();
        }
        if (tokenFlusherAddress_ == address(0)) {
            revert InvalidFlusher();
        }
        ownerAddress = ownerAddress_;
        tokenFlusherAddress = tokenFlusherAddress_;
        lock = _UNLOCKED;
    }

    /**
     * Default function; Gets called when Ether is deposited, and forwards it to the owner address
     */
    receive() external payable nonReentrant {
        (bool success,) = ownerAddress.call{value: msg.value}("");
        if (!success) {
            revert TransferFailed("ETH forward");
        }
        emit ForwardedDeposit(msg.sender, address(this), ownerAddress, msg.value);
    }

    /**
     * It is possible that funds were sent to this address before the contract was deployed.
     * We can flush those funds to the parent address.
     */
    function flush() public nonReentrant {
        uint256 balance = address(this).balance;
        if (balance == 0) {
            revert InsufficientBalance();
        }
        (bool success,) = ownerAddress.call{value: balance}("");
        if (!success) {
            revert TransferFailed("ETH flush");
        }
    }

    /**
     * Execute a token transfer of the full balance from the forwarder token to the parent address
     * @param tokenContractAddress the address of the ERC20 token contract
     */
    function flushTokens(address tokenContractAddress) public onlyOwnerOrTokenFlusher {
        ERC20Interface instance = ERC20Interface(tokenContractAddress);
        uint256 forwarderBalance = instance.balanceOf(address(this));
        if (forwarderBalance == 0) {
            revert InsufficientBalance();
        }

        // Use low-level call to handle tokens that don't return a value
        (bool success, bytes memory data) = address(instance).call(
            abi.encodeWithSelector(instance.transfer.selector, ownerAddress, forwarderBalance)
        );

        if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
            revert TransferFailed("Token flush");
        }

        emit TokensFlushed(address(this), forwarderBalance, tokenContractAddress);
    }

    modifier onlyOwnerOrTokenFlusher {
        if (msg.sender != ownerAddress && msg.sender != tokenFlusherAddress) {
            revert NotAuthorized();
        }
        _;
    }

    modifier onlyOwner {
        if (msg.sender != ownerAddress) {
            revert NotAuthorized();
        }
        _;
    }

    function changeOwner(address newOwner) public onlyOwner {
        if (newOwner == address(0)) {
            revert InvalidOwner();
        }
        if (newOwner == ownerAddress) {
            revert NewValueMustBeDifferent();
        }

        address oldOwner = ownerAddress;
        ownerAddress = newOwner;
        emit OwnerChanged(oldOwner, newOwner);
    }

    function changeTokenFlusher(address newFlusher) public onlyOwner {
        if (newFlusher == address(0)) {
            revert InvalidFlusher();
        }
        if (newFlusher == tokenFlusherAddress) {
            revert NewValueMustBeDifferent();
        }

        address oldFlusher = tokenFlusherAddress;
        tokenFlusherAddress = newFlusher;
        emit TokenFlusherChanged(oldFlusher, newFlusher);
    }

    modifier nonReentrant() {
        if (lock == _LOCKED) {
            revert ReentrantCallDetected();
        }
        lock = _LOCKED;
        _;
        lock = _UNLOCKED;
    }
}

Read Contract

ownerAddress 0x8f84aa09 → address
tokenFlusherAddress 0xfeb0a141 → address

Write Contract 4 functions

These functions modify contract state and require a wallet transaction to execute.

changeOwner 0xa6f9dae1
address newOwner
changeTokenFlusher 0x96a4154e
address newFlusher
flush 0x6b9f96ea
No parameters
flushTokens 0x3ef13367
address tokenContractAddress

Recent Transactions

Transaction index is loading. Only unfinalized transactions are shown while the index starts up.