ETH Price: $2,956.44 (+0.99%)

Contract

0x0000000000001fF3684f28c67538d4D072C22734
Transaction Hash
Block
From
To
0x2213bc0b249621752026-01-24 13:06:2932 mins ago1769259989IN
0x00000000...072C22734
0 ETH0.000000360.00150025
0x2213bc0b249615452026-01-24 12:45:2953 mins ago1769258729IN
0x00000000...072C22734
0 ETH0.000000240.00150025
0x2213bc0b249615452026-01-24 12:45:2953 mins ago1769258729IN
0x00000000...072C22734
0 ETH0.000000380.00150025
0x2213bc0b249612852026-01-24 12:36:491 hr ago1769258209IN
0x00000000...072C22734
0 ETH0.000000540.00150025
0x2213bc0b249612852026-01-24 12:36:491 hr ago1769258209IN
0x00000000...072C22734
0 ETH0.00000050.00150025
0x2213bc0b249612842026-01-24 12:36:471 hr ago1769258207IN
0x00000000...072C22734
0 ETH0.000000450.00150025
0x2213bc0b249611552026-01-24 12:32:291 hr ago1769257949IN
0x00000000...072C22734
0 ETH0.000000440.00150025
0x2213bc0b249611552026-01-24 12:32:291 hr ago1769257949IN
0x00000000...072C22734
0 ETH0.000000550.00150025
0x2213bc0b249608882026-01-24 12:23:351 hr ago1769257415IN
0x00000000...072C22734
0 ETH0.000000440.00150025
0x2213bc0b249608882026-01-24 12:23:351 hr ago1769257415IN
0x00000000...072C22734
0 ETH0.000000450.00150025
0x2213bc0b249607842026-01-24 12:20:071 hr ago1769257207IN
0x00000000...072C22734
0 ETH0.000001620.00450025
0x2213bc0b249607602026-01-24 12:19:191 hr ago1769257159IN
0x00000000...072C22734
0 ETH0.000000350.00150025
0x2213bc0b249607602026-01-24 12:19:191 hr ago1769257159IN
0x00000000...072C22734
0 ETH0.00000050.00150025
0x2213bc0b249607592026-01-24 12:19:171 hr ago1769257157IN
0x00000000...072C22734
0 ETH0.000000450.00150025
0x2213bc0b249606582026-01-24 12:15:551 hr ago1769256955IN
0x00000000...072C22734
0 ETH0.000000550.00150025
0x2213bc0b249606582026-01-24 12:15:551 hr ago1769256955IN
0x00000000...072C22734
0 ETH0.000000410.00150025
0x2213bc0b249606572026-01-24 12:15:531 hr ago1769256953IN
0x00000000...072C22734
0 ETH0.000000350.00150025
0x2213bc0b249606572026-01-24 12:15:531 hr ago1769256953IN
0x00000000...072C22734
0 ETH0.000000360.00150025
0x2213bc0b249604782026-01-24 12:09:551 hr ago1769256595IN
0x00000000...072C22734
0 ETH0.000000250.00150025
0x2213bc0b249604782026-01-24 12:09:551 hr ago1769256595IN
0x00000000...072C22734
0 ETH0.000000590.00150025
0x2213bc0b249604772026-01-24 12:09:531 hr ago1769256593IN
0x00000000...072C22734
0 ETH0.000000540.00150025
0x2213bc0b249604772026-01-24 12:09:531 hr ago1769256593IN
0x00000000...072C22734
0 ETH0.000000450.00150025
0x2213bc0b249604522026-01-24 12:09:031 hr ago1769256543IN
0x00000000...072C22734
0 ETH0.000000460.00150025
0x2213bc0b249604522026-01-24 12:09:031 hr ago1769256543IN
0x00000000...072C22734
0 ETH0.000000460.00150025
0x2213bc0b249604242026-01-24 12:08:071 hr ago1769256487IN
0x00000000...072C22734
0 ETH0.000000260.00150025
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
249577142026-01-24 10:37:473 hrs ago1769251067
0x00000000...072C22734
0.0001 ETH
249577142026-01-24 10:37:473 hrs ago1769251067
0x00000000...072C22734
0.0001 ETH
249530222026-01-24 8:01:235 hrs ago1769241683
0x00000000...072C22734
0.01435642 ETH
249530222026-01-24 8:01:235 hrs ago1769241683
0x00000000...072C22734
0.01435642 ETH
249522112026-01-24 7:34:216 hrs ago1769240061
0x00000000...072C22734
0.00012709 ETH
249522112026-01-24 7:34:216 hrs ago1769240061
0x00000000...072C22734
0.00012709 ETH
249521912026-01-24 7:33:416 hrs ago1769240021
0x00000000...072C22734
0.00025897 ETH
249521912026-01-24 7:33:416 hrs ago1769240021
0x00000000...072C22734
0.00025897 ETH
249422242026-01-24 2:01:2711 hrs ago1769220087
0x00000000...072C22734
0.00003386 ETH
249422242026-01-24 2:01:2711 hrs ago1769220087
0x00000000...072C22734
0.00003386 ETH
249421992026-01-24 2:00:3711 hrs ago1769220037
0x00000000...072C22734
0.00003388 ETH
249421992026-01-24 2:00:3711 hrs ago1769220037
0x00000000...072C22734
0.00003388 ETH
249421782026-01-24 1:59:5511 hrs ago1769219995
0x00000000...072C22734
0.00003387 ETH
249421782026-01-24 1:59:5511 hrs ago1769219995
0x00000000...072C22734
0.00003387 ETH
249421502026-01-24 1:58:5911 hrs ago1769219939
0x00000000...072C22734
0.00003388 ETH
249421502026-01-24 1:58:5911 hrs ago1769219939
0x00000000...072C22734
0.00003388 ETH
249421302026-01-24 1:58:1911 hrs ago1769219899
0x00000000...072C22734
0.00003388 ETH
249421302026-01-24 1:58:1911 hrs ago1769219899
0x00000000...072C22734
0.00003388 ETH
249419882026-01-24 1:53:3511 hrs ago1769219615
0x00000000...072C22734
0.000253 ETH
249419882026-01-24 1:53:3511 hrs ago1769219615
0x00000000...072C22734
0.000253 ETH
249397802026-01-24 0:39:5912 hrs ago1769215199
0x00000000...072C22734
0.00079152 ETH
249397802026-01-24 0:39:5912 hrs ago1769215199
0x00000000...072C22734
0.00079152 ETH
249372472026-01-23 23:15:3314 hrs ago1769210133
0x00000000...072C22734
0.00003387 ETH
249372472026-01-23 23:15:3314 hrs ago1769210133
0x00000000...072C22734
0.00003387 ETH
249372272026-01-23 23:14:5314 hrs ago1769210093
0x00000000...072C22734
0.00003387 ETH
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AllowanceHolder

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
cancun EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity =0.8.25;

import {AllowanceHolderBase} from "./AllowanceHolderBase.sol";
import {TransientStorage} from "./TransientStorage.sol";

/// @custom:security-contact [email protected]
contract AllowanceHolder is TransientStorage, AllowanceHolderBase {
    constructor() {
        require(address(this) == 0x0000000000001fF3684f28c67538d4D072C22734 || block.chainid == 31337);
    }

    /// @inheritdoc AllowanceHolderBase
    function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data)
        internal
        override
        returns (bytes memory)
    {
        (bytes memory result, address sender, TSlot allowance) = _exec(operator, token, amount, target, data);
        // EIP-3074 seems unlikely
        if (sender != tx.origin) {
            _set(allowance, 0);
        }
        return result;
    }
}

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

import {IAllowanceHolder} from "./IAllowanceHolder.sol";
import {IERC20} from "@forge-std/interfaces/IERC20.sol";
import {SafeTransferLib} from "../vendor/SafeTransferLib_Solmate.sol";
import {CheckCall} from "../utils/CheckCall.sol";
import {FreeMemory} from "../utils/FreeMemory.sol";
import {TransientStorageLayout} from "./TransientStorageLayout.sol";

/// @notice Thrown when validating the target, avoiding executing against an ERC20 directly
error ConfusedDeputy();

abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory {
    using SafeTransferLib for IERC20;
    using CheckCall for address payable;

    function _rejectIfERC20(address payable maybeERC20, bytes calldata data) private view DANGEROUS_freeMemory {
        // We could just choose a random address for this check, but to make
        // confused deputy attacks harder for tokens that might be badly behaved
        // (e.g. tokens with blacklists), we choose to copy the first argument
        // out of `data` and mask it as an address. If there isn't enough
        // `data`, we use 0xdead instead.
        address target;
        if (data.length > 0x10) {
            target = address(uint160(bytes20(data[0x10:])));
        }
        // EIP-1352 (not adopted) specifies 0xffff as the maximum precompile
        if (target <= address(0xffff)) {
            // 0xdead is a conventional burn address; we assume that it is not treated specially
            target = address(0xdead);
        }
        bytes memory testData = abi.encodeCall(IERC20.balanceOf, target);
        if (maybeERC20.checkCall(testData, 0x20)) revert ConfusedDeputy();
    }

    function _msgSender() private view returns (address sender) {
        if ((sender = msg.sender) == address(this)) {
            assembly ("memory-safe") {
                sender := shr(0x60, calldataload(sub(calldatasize(), 0x14)))
            }
        }
    }

    /// @dev This virtual function provides the implementation for the function
    ///      of the same name in `IAllowanceHolder`. It is unimplemented in this
    ///      base contract to accommodate the customization required to support
    ///      both chains that have EIP-1153 (transient storage) and those that
    ///      don't.
    function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data)
        internal
        virtual
        returns (bytes memory result);

    /// @dev This is the majority of the implementation of IAllowanceHolder.exec
    ///      . The arguments have the same meaning as documented there.
    /// @return result
    /// @return sender The (possibly forwarded) message sender that is
    ///                requesting the allowance be set. Provided to avoid
    ///                duplicated computation in customized `exec`
    /// @return allowance The slot where the ephemeral allowance is
    ///                   stored. Provided to avoid duplicated computation in
    ///                   customized `exec`
    function _exec(address operator, address token, uint256 amount, address payable target, bytes calldata data)
        internal
        returns (bytes memory result, address sender, TSlot allowance)
    {
        // This contract has no special privileges, except for the allowances it
        // holds. In order to prevent abusing those allowances, we prohibit
        // sending arbitrary calldata (doing `target.call(data)`) to any
        // contract that might be an ERC20.
        _rejectIfERC20(target, data);

        sender = _msgSender();
        allowance = _ephemeralAllowance(operator, sender, token);
        _set(allowance, amount);

        // For gas efficiency we're omitting a bunch of checks here. Notably,
        // we're omitting the check that `address(this)` has sufficient value to
        // send (we know it does), and we're omitting the check that `target`
        // contains code (we already checked in `_rejectIfERC20`).
        assembly ("memory-safe") {
            result := mload(0x40)
            calldatacopy(result, data.offset, data.length)
            // ERC-2771 style msgSender forwarding https://eips.ethereum.org/EIPS/eip-2771
            mstore(add(result, data.length), shl(0x60, sender))
            let success := call(gas(), target, callvalue(), result, add(data.length, 0x14), 0x00, 0x00)
            let ptr := add(result, 0x20)
            returndatacopy(ptr, 0x00, returndatasize())
            switch success
            case 0 { revert(ptr, returndatasize()) }
            default {
                mstore(result, returndatasize())
                mstore(0x40, add(ptr, returndatasize()))
            }
        }
    }

    /// @dev This provides the implementation of the function of the same name
    ///      in `IAllowanceHolder`.
    function transferFrom(address token, address owner, address recipient, uint256 amount) internal {
        // msg.sender is the assumed and later validated operator
        TSlot allowance = _ephemeralAllowance(msg.sender, owner, token);
        // validation of the ephemeral allowance for operator, owner, token via
        // uint underflow
        _set(allowance, _get(allowance) - amount);
        // `safeTransferFrom` does not check that `token` actually contains
        // code. It is the responsibility of integrating code to check for that
        // if vacuous success is a security concern.
        IERC20(token).safeTransferFrom(owner, recipient, amount);
    }

    fallback() external payable {
        uint256 selector;
        assembly ("memory-safe") {
            selector := shr(0xe0, calldataload(0x00))
        }
        if (selector == uint256(uint32(IAllowanceHolder.transferFrom.selector))) {
            address token;
            address owner;
            address recipient;
            uint256 amount;
            assembly ("memory-safe") {
                // We do not validate `calldatasize()`. If the calldata is short
                // enough that `amount` is null, this call is a harmless no-op.
                let err := callvalue()
                token := calldataload(0x04)
                err := or(err, shr(0xa0, token))
                owner := calldataload(0x24)
                err := or(err, shr(0xa0, owner))
                recipient := calldataload(0x44)
                err := or(err, shr(0xa0, recipient))
                if err { revert(0x00, 0x00) }
                amount := calldataload(0x64)
            }

            transferFrom(token, owner, recipient, amount);

            // return true;
            assembly ("memory-safe") {
                mstore(0x00, 0x01)
                return(0x00, 0x20)
            }
        } else if (selector == uint256(uint32(IAllowanceHolder.exec.selector))) {
            address operator;
            address token;
            uint256 amount;
            address payable target;
            bytes calldata data;
            assembly ("memory-safe") {
                // We do not validate `calldatasize()`. If the calldata is short
                // enough that `data` is null, it will alias `operator`. This
                // results in either an OOG (because `operator` encodes a
                // too-long `bytes`) or is a harmless no-op (because `operator`
                // encodes a valid length, but not an address capable of making
                // calls). If the calldata is _so_ sort that `target` is null,
                // we will revert because it contains no code.
                operator := calldataload(0x04)
                let err := shr(0xa0, operator)
                token := calldataload(0x24)
                err := or(err, shr(0xa0, token))
                amount := calldataload(0x44)
                target := calldataload(0x64)
                err := or(err, shr(0xa0, target))
                if err { revert(0x00, 0x00) }
                // We perform no validation that `data` is reasonable.
                data.offset := add(0x04, calldataload(0x84))
                data.length := calldataload(data.offset)
                data.offset := add(0x20, data.offset)
            }

            bytes memory result = exec(operator, token, amount, target, data);

            // return result;
            assembly ("memory-safe") {
                let returndata := sub(result, 0x20)
                mstore(returndata, 0x20)
                return(returndata, add(0x40, mload(result)))
            }
        } else if (selector == uint256(uint32(IERC20.balanceOf.selector))) {
            // balanceOf(address) reverts with a single byte of returndata,
            // making it more gas efficient to pass the `_rejectERC20` check
            assembly ("memory-safe") {
                revert(0x00, 0x01)
            }
        } else {
            // emulate standard Solidity behavior
            assembly ("memory-safe") {
                revert(0x00, 0x00)
            }
        }
    }
}

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

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

abstract contract TransientStorage is TransientStorageBase {
    function _get(TSlot s) internal view override returns (uint256 r) {
        assembly ("memory-safe") {
            r := tload(s)
        }
    }

    function _set(TSlot s, uint256 v) internal override {
        assembly ("memory-safe") {
            tstore(s, v)
        }
    }
}

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

interface IAllowanceHolder {
    /// @notice Executes against `target` with the `data` payload. Prior to execution, token permits
    ///         are temporarily stored for the duration of the transaction. These permits can be
    ///         consumed by the `operator` during the execution
    /// @notice `operator` consumes the funds during its operations by calling back into
    ///         `AllowanceHolder` with `transferFrom`, consuming a token permit.
    /// @dev Neither `exec` nor `transferFrom` check that `token` contains code.
    /// @dev msg.sender is forwarded to target appended to the msg data (similar to ERC-2771)
    /// @param operator An address which is allowed to consume the token permits
    /// @param token The ERC20 token the caller has authorised to be consumed
    /// @param amount The quantity of `token` the caller has authorised to be consumed
    /// @param target A contract to execute operations with `data`
    /// @param data The data to forward to `target`
    /// @return result The returndata from calling `target` with `data`
    /// @notice If calling `target` with `data` reverts, the revert is propagated
    function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data)
        external
        payable
        returns (bytes memory result);

    /// @notice The counterpart to `exec` which allows for the consumption of token permits later
    ///         during execution
    /// @dev *DOES NOT* check that `token` contains code. This function vacuously succeeds if
    ///      `token` is empty.
    /// @dev can only be called by the `operator` previously registered in `exec`
    /// @param token The ERC20 token to transfer
    /// @param owner The owner of tokens to transfer
    /// @param recipient The destination/beneficiary of the ERC20 `transferFrom`
    /// @param amount The quantity of `token` to transfer`
    /// @return true
    function transferFrom(address token, address owner, address recipient, uint256 amount) external returns (bool);
}

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

/// @dev Interface of the ERC20 standard as defined in the EIP.
/// @dev This includes the optional name, symbol, and decimals metadata.
interface IERC20 {
    /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).
    event Transfer(address indexed from, address indexed to, uint256 value);

    /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value`
    /// is the new allowance.
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /// @notice Returns the amount of tokens in existence.
    function totalSupply() external view returns (uint256);

    /// @notice Returns the amount of tokens owned by `account`.
    function balanceOf(address account) external view returns (uint256);

    /// @notice Moves `amount` tokens from the caller's account to `to`.
    function transfer(address to, uint256 amount) external returns (bool);

    /// @notice Returns the remaining number of tokens that `spender` is allowed
    /// to spend on behalf of `owner`
    function allowance(address owner, address spender) external view returns (uint256);

    /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens.
    /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    function approve(address spender, uint256 amount) external returns (bool);

    /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism.
    /// `amount` is then deducted from the caller's allowance.
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

    /// @notice Returns the name of the token.
    function name() external view returns (string memory);

    /// @notice Returns the symbol of the token.
    function symbol() external view returns (string memory);

    /// @notice Returns the decimals places of the token.
    function decimals() external view returns (uint8);
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.25;

import {IERC20} from "@forge-std/interfaces/IERC20.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 {
    uint32 private constant _TRANSFER_FROM_FAILED_SELECTOR = 0x7939f424; // bytes4(keccak256("TransferFromFailed()"))
    uint32 private constant _TRANSFER_FAILED_SELECTOR = 0x90b8ec18; // bytes4(keccak256("TransferFailed()"))
    uint32 private constant _APPROVE_FAILED_SELECTOR = 0x3e3f8f73; // bytes4(keccak256("ApproveFailed()"))

    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address payable to, uint256 amount) internal {
        assembly ("memory-safe") {
            // Transfer the ETH and store if it succeeded or not.
            if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {
                let freeMemoryPointer := mload(0x40)
                returndatacopy(freeMemoryPointer, 0, returndatasize())
                revert(freeMemoryPointer, returndatasize())
            }
        }
    }

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

    function safeTransferFrom(IERC20 token, address from, address to, uint256 amount) internal {
        assembly ("memory-safe") {
            // 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.

            // 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.
            if iszero(call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)) {
                returndatacopy(freeMemoryPointer, 0, returndatasize())
                revert(freeMemoryPointer, returndatasize())
            }
            // We check that the call either returned exactly 1 (can't just be non-zero data), or had no
            // return data.
            if iszero(or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize()))) {
                mstore(0, _TRANSFER_FROM_FAILED_SELECTOR)
                revert(0x1c, 0x04)
            }
        }
    }

    function safeTransfer(IERC20 token, address to, uint256 amount) internal {
        assembly ("memory-safe") {
            // 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.

            // 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.
            if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)) {
                returndatacopy(freeMemoryPointer, 0, returndatasize())
                revert(freeMemoryPointer, returndatasize())
            }
            // We check that the call either returned exactly 1 (can't just be non-zero data), or had no
            // return data.
            if iszero(or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize()))) {
                mstore(0, _TRANSFER_FAILED_SELECTOR)
                revert(0x1c, 0x04)
            }
        }
    }

    function safeApprove(IERC20 token, address to, uint256 amount) internal {
        assembly ("memory-safe") {
            // 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.

            // 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.
            if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)) {
                returndatacopy(freeMemoryPointer, 0, returndatasize())
                revert(freeMemoryPointer, returndatasize())
            }
            // We check that the call either returned exactly 1 (can't just be non-zero data), or had no
            // return data.
            if iszero(or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize()))) {
                mstore(0, _APPROVE_FAILED_SELECTOR)
                revert(0x1c, 0x04)
            }
        }
    }

    function safeApproveIfBelow(IERC20 token, address spender, uint256 amount) internal {
        uint256 allowance = token.allowance(address(this), spender);
        if (allowance < amount) {
            if (allowance != 0) {
                safeApprove(token, spender, 0);
            }
            safeApprove(token, spender, type(uint256).max);
        }
    }
}

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

library CheckCall {
    /**
     * @notice `staticcall` another contract. Check the length of the return without reading it.
     * @dev contains protections against EIP-150-induced insufficient gas griefing
     * @dev reverts iff the target is not a contract or we encounter an out-of-gas
     * @return success true iff the call succeeded and returned at least `minReturnBytes` of return
     *                 data
     * @param target the contract (reverts if non-contract) on which to make the `staticcall`
     * @param data the calldata to pass
     * @param minReturnBytes `success` is false if the call doesn't return at least this much return
     *                       data
     */
    function checkCall(address target, bytes memory data, uint256 minReturnBytes)
        internal
        view
        returns (bool success)
    {
        assembly ("memory-safe") {
            let beforeGas
            {
                let offset := add(data, 0x20)
                let length := mload(data)
                beforeGas := gas()
                success := staticcall(gas(), target, offset, length, 0x00, 0x00)
            }

            // `verbatim` can't work in inline assembly. Assignment of a value to a variable costs
            // gas (although how much is unpredictable because it depends on the Yul/IR optimizer),
            // as does the `GAS` opcode itself. Therefore, the `gas()` below returns less than the
            // actual amount of gas available for computation at the end of the call. Also
            // `beforeGas` above is exclusive of the preparing of the stack for `staticcall` as well
            // as the gas costs of the `staticcall` paid by the caller (e.g. cold account
            // access). All this makes the check below slightly too conservative. However, we do not
            // correct this because the correction would become outdated (possibly too permissive)
            // if the opcodes are repriced.
            let afterGas := gas()

            for {} 1 {} {
                if iszero(returndatasize()) {
                    // The absence of returndata means that it's possible that either we called an
                    // address without code or that the call reverted due to out-of-gas. We must
                    // check.
                    switch success
                    case 0 {
                        // Check whether the call reverted due to out-of-gas.
                        // https://eips.ethereum.org/EIPS/eip-150
                        // https://ronan.eth.limo/blog/ethereum-gas-dangers/
                        // We apply the "all but one 64th" rule twice because `target` could
                        // plausibly be a proxy. We apply it only twice because we assume only a
                        // single level of indirection.
                        let remainingGas := shr(6, beforeGas)
                        remainingGas := add(remainingGas, shr(6, sub(beforeGas, remainingGas)))
                        if iszero(lt(remainingGas, afterGas)) {
                            // The call failed due to not enough gas left. We deliberately consume
                            // all remaining gas with `invalid` (instead of `revert`) to make this
                            // failure distinguishable to our caller.
                            invalid()
                        }
                        // `success` is false because the call reverted
                    }
                    default {
                        // Check whether we called an address with no code (gas expensive).
                        if iszero(extcodesize(target)) { revert(0x00, 0x00) }
                        // We called a contract which returned no data; this is only a success if we
                        // were expecting no data.
                        success := iszero(minReturnBytes)
                    }
                    break
                }
                // The presence of returndata indicates that we definitely executed code. It also
                // means that the call didn't revert due to out-of-gas, if it reverted. We can omit
                // a bunch of checks.
                success := gt(success, lt(returndatasize(), minReturnBytes))
                break
            }
        }
    }
}

File 8 of 10 : FreeMemory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

abstract contract FreeMemory {
    modifier DANGEROUS_freeMemory() {
        uint256 freeMemPtr;
        assembly ("memory-safe") {
            freeMemPtr := mload(0x40)
        }
        _;
        assembly ("memory-safe") {
            mstore(0x40, freeMemPtr)
        }
    }
}

File 9 of 10 : TransientStorageLayout.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

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

abstract contract TransientStorageLayout is TransientStorageBase {
    /// @dev The key for this ephemeral allowance is keccak256(abi.encodePacked(operator, owner, token)).
    function _ephemeralAllowance(address operator, address owner, address token) internal pure returns (TSlot r) {
        assembly ("memory-safe") {
            let ptr := mload(0x40)
            mstore(0x28, token)
            mstore(0x14, owner)
            mstore(0x00, operator)
            // allowance slot is keccak256(abi.encodePacked(operator, owner, token))
            r := keccak256(0x0c, 0x3c)
            // restore dirtied free pointer
            mstore(0x40, ptr)
        }
    }
}

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

abstract contract TransientStorageBase {
    type TSlot is bytes32;

    function _get(TSlot s) internal view virtual returns (uint256);

    function _set(TSlot s, uint256 v) internal virtual;
}

Settings
{
  "remappings": [
    "@solmate/=lib/solmate/src/",
    "@permit2/=lib/permit2/src/",
    "@forge-std/=lib/forge-std/src/",
    "@forge-gas-snapshot/=lib/forge-gas-snapshot/src/",
    "@uniswapv4/=lib/v4-core/src/",
    "forge-std/src/=lib/forge-std/src/",
    "solmate/=lib/solmate/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000000,
    "details": {
      "constantOptimizer": true,
      "yul": true
    }
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": false
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ConfusedDeputy","type":"error"},{"stateMutability":"payable","type":"fallback"}]

608080604052346030576d1ff3684f28c67538d4d072c22734301480156034575b156030576103f1908161003f8239f35b5f80fd5b50617a694614602056fe608060408181525f3560e01c6315dacbea81036101245750600435602435604435928360a01c8260a01c8460a01c34171717610120576040805160288590526014849052335f52603c600c2091526064359290805c928484039384116100f3576020955f9560649587945d73ffffffffffffffffffffffffffffffffffffffff80998194519a8b977f23b872dd0000000000000000000000000000000000000000000000000000000089521660048801521660248601526044850152165af1156100eb573d15601f3d1160015f51141617156100de5760015f5260205ff35b637939f4245f526004601cfd5b3d5f823e3d90fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f80fd5b632213bc0b81036103e2575060043560243590606435918260a01c8160a01c8360a01c171761012057608435928360040135935f9260108611610360575b73ffffffffffffffffffffffffffffffffffffffff9361ffff8582161115610357575b8460208a01917f70a082310000000000000000000000000000000000000000000000000000000083521660248a0152602489526060890189811067ffffffffffffffff82111761032a5788528484165f808b515a94845afa905a60203d10933d156102fb57505050115b6102d257602497875233943033146102a4575b9160146102295f959388879690929192604051936028526014525f52603c600c2091604052565b97604435895d808a519b8c940184378760601b81840152019134905af160208601903d5f833e156102a057503d855260203d860101845232911603610297575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082019160208352510190f35b5f905d5f610269565b3d90fd5b367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec013560601c9550610202565b600487517fe758b8d5000000000000000000000000000000000000000000000000000000008152fd5b919350908215610314575050503b15610120575f6101ef565b90919250600681811c809203901c01106101ef57fe5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5061dead610185565b9250846010116101205760348101357fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008082169160147ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08901106103ca575b505060601c92610162565b908092506010886014030160031b1b16165f806103bf565b6370a08231036101205760015ffd

Deployed Bytecode

0x608060408181525f3560e01c6315dacbea81036101245750600435602435604435928360a01c8260a01c8460a01c34171717610120576040805160288590526014849052335f52603c600c2091526064359290805c928484039384116100f3576020955f9560649587945d73ffffffffffffffffffffffffffffffffffffffff80998194519a8b977f23b872dd0000000000000000000000000000000000000000000000000000000089521660048801521660248601526044850152165af1156100eb573d15601f3d1160015f51141617156100de5760015f5260205ff35b637939f4245f526004601cfd5b3d5f823e3d90fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f80fd5b632213bc0b81036103e2575060043560243590606435918260a01c8160a01c8360a01c171761012057608435928360040135935f9260108611610360575b73ffffffffffffffffffffffffffffffffffffffff9361ffff8582161115610357575b8460208a01917f70a082310000000000000000000000000000000000000000000000000000000083521660248a0152602489526060890189811067ffffffffffffffff82111761032a5788528484165f808b515a94845afa905a60203d10933d156102fb57505050115b6102d257602497875233943033146102a4575b9160146102295f959388879690929192604051936028526014525f52603c600c2091604052565b97604435895d808a519b8c940184378760601b81840152019134905af160208601903d5f833e156102a057503d855260203d860101845232911603610297575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082019160208352510190f35b5f905d5f610269565b3d90fd5b367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec013560601c9550610202565b600487517fe758b8d5000000000000000000000000000000000000000000000000000000008152fd5b919350908215610314575050503b15610120575f6101ef565b90919250600681811c809203901c01106101ef57fe5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5061dead610185565b9250846010116101205760348101357fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008082169160147ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08901106103ca575b505060601c92610162565b908092506010886014030160031b1b16165f806103bf565b6370a08231036101205760015ffd

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

OVERVIEW

This is a contract on Arb

Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
0x0000000000001fF3684f28c67538d4D072C22734
Net Worth in USD
$2,243,498,315.39

Net Worth in ETH
758,850.412244

Token Allocations
LUIGI 100.00%
DHN 0.00%
FREYA 0.00%
Others 0.00%
Chain Token Portfolio % Price Amount Value
BSC100.00%$0.0002967,580,669,599,479.208$2,243,490,553.63
BSC<0.01%$5.591,000$5,590
BSC<0.01%$0.99851488.6058$487.88
BSC<0.01%$0.999703155.602$155.56
BSC<0.01%$0.00000813,196,946.7952$103.46
BSC<0.01%$0.000525151,701.6586$79.66
BSC<0.01%$1.9238.77$74.33
BSC<0.01%$0.000034579,253.1036$19.42
BSC<0.01%$0.9994687.3645$7.36
BSC<0.01%$0.009028560.6775$5.06
BSC<0.01%$0.012176306.3535$3.73
BSC<0.01%$0.0545238.771$0.4782
BSC<0.01%$0.01000725$0.2501
BSC<0.01%$0.00065200$0.1299
BASE<0.01%$0.01491870,845.6803$1,056.84
BASE<0.01%$89,3870.00003111$2.78
BASE<0.01%$0.9995240.5$0.4997
BASE<0.01%$0.00002511,641.7011$0.2871
ETH<0.01%$3,292.650.00964142$31.75
ETH<0.01%$0.0000082,500,000$19.6
ETH<0.01%$0.0032765,651.1134$18.52
ETH<0.01%$0.99851213.7014$13.68
ETH<0.01%<$0.000001796,119,990,045,757,570$12.74
ETH<0.01%<$0.0000016,655,290,430.649$11.89
ETH<0.01%$0.9993521$0.9993
ETH<0.01%$0.00904657.0281$0.5158
ETH<0.01%$89,2860.00000319$0.2848
ABSTRACT<0.01%$2,956.780.0156$46.09
LINEA<0.01%$2,956.380.006001$17.74
POL<0.01%<$0.00000133,331,557.9891$0.1266
POL<0.01%$179.430.0006018$0.1079
OPBNB<0.01%$891.070.000000008318$0.000007
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.