HYPE Price: $26.76 (+7.51%)
 

Overview

HYPE Balance

HyperEVM LogoHyperEVM LogoHyperEVM Logo1,310.815982180832832768 HYPE

HYPE Value

$35,072.50 (@ $26.76/HYPE)

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Withdraw OEV237705962026-01-05 17:38:0021 days ago1767634680IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000009070.17409274
Withdraw OEV198132822025-11-21 16:17:0066 days ago1763741820IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000005210.1001
Withdraw OEV185484272025-11-07 6:39:0080 days ago1762497540IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000024840.32222222
Update183767652025-11-05 7:44:5382 days ago1762328693IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000009760.32222222
Set Solver Gas L...182309832025-11-03 15:55:0084 days ago1762185300IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000087112.94422712
Set D App Gas Li...179273412025-10-31 4:56:0088 days ago1761886560IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000010690.36441429
Set Solver Gas L...179273412025-10-31 4:56:0088 days ago1761886560IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000004260.14406655
Set Solver Gas L...179268532025-10-31 4:48:0088 days ago1761886080IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000003030.10245855
Set D App Gas Li...179264872025-10-31 4:42:0088 days ago1761885720IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000009450.32222222
Set Solver Gas L...170942812025-10-21 17:18:0097 days ago1761067080IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000012450.42074201
Set Solver Gas L...163441312025-10-13 4:18:00106 days ago1760329080IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000003370.11387556
Set Solver Gas L...121560962025-08-26 11:54:00153 days ago1756209240IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000002950.1
Set Oev Allocati...117142472025-08-21 10:59:00158 days ago1755773940IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000019810.66637064
Set D App Gas Li...117135152025-08-21 10:47:00158 days ago1755773220IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000002930.1
Set D App Gas Li...117107702025-08-21 10:02:00158 days ago1755770520IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000002930.1
Set Solver Gas L...117107092025-08-21 10:01:00158 days ago1755770460IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000002950.1
Set Authorized U...116289692025-08-20 11:41:00159 days ago1755690060IN
0x96b7F47F...01Ca0b6ac
0 HYPE0.000018080.21988007

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
251557762026-01-21 12:07:155 days ago1768997235
0x96b7F47F...01Ca0b6ac
0.3791464 HYPE
251557362026-01-21 12:06:365 days ago1768997196
0x96b7F47F...01Ca0b6ac
3.77070614 HYPE
251556352026-01-21 12:04:575 days ago1768997097
0x96b7F47F...01Ca0b6ac
1.51324449 HYPE
251556342026-01-21 12:04:565 days ago1768997096
0x96b7F47F...01Ca0b6ac
9.32234254 HYPE
251553982026-01-21 12:01:035 days ago1768996863
0x96b7F47F...01Ca0b6ac
1.20302304 HYPE
251514452026-01-21 10:56:155 days ago1768992975
0x96b7F47F...01Ca0b6ac
1.50163248 HYPE
251514402026-01-21 10:56:105 days ago1768992970
0x96b7F47F...01Ca0b6ac
4.26345681 HYPE
251514382026-01-21 10:56:085 days ago1768992968
0x96b7F47F...01Ca0b6ac
5.25268793 HYPE
251514042026-01-21 10:55:355 days ago1768992935
0x96b7F47F...01Ca0b6ac
1.34241597 HYPE
251508742026-01-21 10:46:545 days ago1768992414
0x96b7F47F...01Ca0b6ac
1.20527267 HYPE
251108802026-01-20 23:51:156 days ago1768953075
0x96b7F47F...01Ca0b6ac
13.64819086 HYPE
251108112026-01-20 23:50:076 days ago1768953007
0x96b7F47F...01Ca0b6ac
6.28785891 HYPE
251107802026-01-20 23:49:376 days ago1768952977
0x96b7F47F...01Ca0b6ac
309.69210019 HYPE
251107662026-01-20 23:49:236 days ago1768952963
0x96b7F47F...01Ca0b6ac
9.62558769 HYPE
251062642026-01-20 22:35:356 days ago1768948535
0x96b7F47F...01Ca0b6ac
24.29794082 HYPE
250880452026-01-20 17:36:556 days ago1768930615
0x96b7F47F...01Ca0b6ac
2.05979359 HYPE
250874862026-01-20 17:27:456 days ago1768930065
0x96b7F47F...01Ca0b6ac
12.61557435 HYPE
250874672026-01-20 17:27:266 days ago1768930046
0x96b7F47F...01Ca0b6ac
12.21483514 HYPE
250872422026-01-20 17:23:456 days ago1768929825
0x96b7F47F...01Ca0b6ac
0.09896075 HYPE
250872312026-01-20 17:23:346 days ago1768929814
0x96b7F47F...01Ca0b6ac
0.0761604 HYPE
250851302026-01-20 16:49:076 days ago1768927747
0x96b7F47F...01Ca0b6ac
9.73983461 HYPE
250742212026-01-20 13:50:176 days ago1768917017
0x96b7F47F...01Ca0b6ac
30.76156336 HYPE
250742192026-01-20 13:50:156 days ago1768917015
0x96b7F47F...01Ca0b6ac
134.36366815 HYPE
250741592026-01-20 13:49:166 days ago1768916956
0x96b7F47F...01Ca0b6ac
2.68348068 HYPE
250741572026-01-20 13:49:146 days ago1768916954
0x96b7F47F...01Ca0b6ac
45.98265364 HYPE
View All Internal Transactions
Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RedstoneOevDAppControl

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 50 runs

Other Settings:
cancun EvmVersion, BSL 1.1 license
File 1 of 22 : RedstoneOevDAppControl.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
import { SafeCastLib } from "solady/utils/SafeCastLib.sol";
import { IAtlas } from "@atlas/interfaces/IAtlas.sol";
import { DAppControl } from "@atlas/dapp/DAppControl.sol";
import { CallConfig } from "@atlas/types/ConfigTypes.sol";
import { UserOperation } from "@atlas/types/UserOperation.sol";
import { SolverOperation } from "@atlas/types/SolverOperation.sol";
import { IRedstoneAdapter } from
    "lib/redstone-oracles-monorepo/packages/on-chain-relayer/contracts/core/IRedstoneAdapter.sol";
import { IMultiFeedAdapter } from
    "lib/redstone-oracles-monorepo/packages/on-chain-relayer/contracts/price-feeds/interfaces/IMultiFeedAdapter.sol";

struct OEVTracker {
    uint120 fastlaneAccumulated; // Total Fastlane OEV, escrowed until withdrawn
    uint120 protocolAccumulated; // Total Protocol OEV, escrowed until withdrawn
    uint16 fastlaneShare; // Fastlane's share of OEV, measured in basis points
}

contract RedstoneOevDAppControl is DAppControl {
    using SafeTransferLib for address;
    using SafeCastLib for uint256;

    error OnlyGovernance();
    error OnlyWhitelistedOracleAllowed();
    error InvalidUserOpDapp();
    error InvalidUserOpFrom();
    error InvalidUserEntryCall();
    error OracleUpdateFailed();
    error InvalidOevShare();
    error InvalidOevAllocationDestination();
    error InvalidExecutionEnv();
    error InvalidSelector();
    error InsufficientBalance();

    event OevAllocated(uint256 totalOev, uint256 oevFastlane, uint256 oevProtocol);
    event OevWithdrawn(
        address indexed destinationFastlane,
        address indexed destinationProtocol,
        uint256 amountFastlane,
        uint256 amountProtocol
    );

    uint256 public constant OEV_SHARE_SCALE = 10_000;

    uint32 internal solverGasLimit = 6_000_000;
    uint32 internal dappGasLimit = 2_000_000;
    uint24 internal bundlerSurchargeRate = 0; // 0% surcharge rate (out of 10_000)

    OEVTracker internal s_oevTracker;

    address public oevAllocationDestinationFastlane;
    address public oevAllocationDestinationProtocol;

    address public authorizedUserOpSigner;
    address public authorizedExecutionEnv;

    uint32 public whitelistedOraclesCount = 0;
    mapping(address oracle => bool isWhitelisted) public oracleWhitelist;

    uint32 public allowedSelectorsCount = 0;
    mapping(bytes4 selector => bool isAllowed) public allowedSelectors;

    constructor(
        address atlas,
        uint256 oevShareFastlane_,
        address oevAllocationDestinationFastlane_,
        address oevAllocationDestinationProtocol_
    )
        DAppControl(
            atlas,
            msg.sender,
            CallConfig({
                userNoncesSequential: false,
                dappNoncesSequential: false,
                requirePreOps: true,
                trackPreOpsReturnData: false,
                trackUserReturnData: false,
                delegateUser: false,
                requirePreSolver: false,
                requirePostSolver: false,
                zeroSolvers: true, // Oracle updates can be made without solvers and no OEV
                reuseUserOp: true,
                userAuctioneer: false,
                solverAuctioneer: false,
                unknownAuctioneer: false,
                verifyCallChainHash: true,
                forwardReturnData: false,
                requireFulfillment: false, // Update oracle even if all solvers fail
                trustedOpHash: false,
                invertBidValue: false,
                exPostBids: false,
                multipleSuccessfulSolvers: false,
                checkMetacallGasLimit: false
            })
        )
    {
        if (oevShareFastlane_ > OEV_SHARE_SCALE) revert InvalidOevShare();
        if (oevAllocationDestinationFastlane_ == address(0)) revert InvalidOevAllocationDestination();
        if (oevAllocationDestinationProtocol_ == address(0)) revert InvalidOevAllocationDestination();

        s_oevTracker.fastlaneShare = oevShareFastlane_.toUint16();
        oevAllocationDestinationFastlane = oevAllocationDestinationFastlane_;
        oevAllocationDestinationProtocol = oevAllocationDestinationProtocol_;

        allowedSelectors[IRedstoneAdapter.updateDataFeedsValues.selector] = true;
        allowedSelectors[IMultiFeedAdapter.updateDataFeedsValuesPartial.selector] = true;
        allowedSelectorsCount = 2;
    }

    // ---------------------------------------------------- //
    //                   Custom Functions                   //
    // ---------------------------------------------------- //

    modifier onlyGov() {
        if (msg.sender != governance) revert OnlyGovernance();
        _;
    }

    function setOevShareFastlane(uint256 oevShareFastlane_) external onlyGov {
        if (oevShareFastlane_ > OEV_SHARE_SCALE) revert InvalidOevShare();
        s_oevTracker.fastlaneShare = oevShareFastlane_.toUint16();
    }

    function setOevAllocationDestinationFastlane(address oevAllocationDestinationFastlane_) external onlyGov {
        if (oevAllocationDestinationFastlane_ == address(0)) revert InvalidOevAllocationDestination();
        oevAllocationDestinationFastlane = oevAllocationDestinationFastlane_;
    }

    function setOevAllocationDestinationProtocol(address oevAllocationDestinationProtocol_) external onlyGov {
        if (oevAllocationDestinationProtocol_ == address(0)) revert InvalidOevAllocationDestination();
        oevAllocationDestinationProtocol = oevAllocationDestinationProtocol_;
    }

    function withdrawOEV() external onlyGov {
        OEVTracker memory _oevTracker = s_oevTracker;
        uint256 amountFastlane = _oevTracker.fastlaneAccumulated;
        uint256 amountProtocol = _oevTracker.protocolAccumulated;
        uint256 totalToWithdraw = amountFastlane + amountProtocol;

        // Early exit if nothing to withdraw
        if (totalToWithdraw == 0) return;

        // Verify contract has sufficient balance before proceeding
        if (address(this).balance < totalToWithdraw) revert InsufficientBalance();

        // Effects: Clear both states atomically before any external interactions
        _oevTracker.fastlaneAccumulated = 0;
        _oevTracker.protocolAccumulated = 0;
        s_oevTracker = _oevTracker;

        // Interactions: Transfer to destinations
        if (amountFastlane > 0) oevAllocationDestinationFastlane.safeTransferETH(amountFastlane);
        if (amountProtocol > 0) oevAllocationDestinationProtocol.safeTransferETH(amountProtocol);

        // Always emit event for complete audit trail
        emit OevWithdrawn(
            oevAllocationDestinationFastlane, oevAllocationDestinationProtocol, amountFastlane, amountProtocol
        );
    }

    function setSolverGasLimit(uint32 solverGasLimit_) external onlyGov {
        solverGasLimit = solverGasLimit_;
    }

    function setDAppGasLimit(uint32 dappGasLimit_) external onlyGov {
        dappGasLimit = dappGasLimit_;
    }

    function setBundlerSurchargeRate(uint24 bundlerSurchargeRate_) external onlyGov {
        bundlerSurchargeRate = bundlerSurchargeRate_;
    }

    // ---------------------------------------------------- //
    //             UserOp Signer Auth Functions             //
    // ---------------------------------------------------- //

    // NOTE: This function must be called immediately after deployment to initialize the authorizedExecutionEnv
    function setAuthorizedUserOpSigner(address authorizedUserOpSigner_) external onlyGov {
        authorizedUserOpSigner = authorizedUserOpSigner_;
        _updateAuthorizedExecutionEnv(authorizedUserOpSigner_);
    }

    function _userOpSignerIsAuthorized(address userOpSigner) internal view {
        if (userOpSigner != authorizedUserOpSigner) revert InvalidUserOpFrom();
    }

    // ---------------------------------------------------- //
    //           Allowed Selector Related Functions         //
    // ---------------------------------------------------- //

    // NOTE: Whitelisting is enforced only if the whitelist is not empty
    function verifyAllowedSelector(bytes4 selector) external view {
        _verifyAllowedSelector(selector);
    }

    function _verifyAllowedSelector(bytes4 selector) internal view {
        if (allowedSelectorsCount > 0 && !allowedSelectors[selector]) revert InvalidSelector();
    }

    function addAllowedSelector(bytes4 selector) external onlyGov {
        if (!allowedSelectors[selector]) {
            allowedSelectors[selector] = true;
            allowedSelectorsCount++;
        }
    }

    function removeAllowedSelector(bytes4 selector) external onlyGov {
        if (allowedSelectors[selector]) {
            allowedSelectors[selector] = false;
            allowedSelectorsCount--;
        }
    }

    // ---------------------------------------------------- //
    //               Oracle Related Functions               //
    // ---------------------------------------------------- //

    // NOTE: Whitelisting is enforced only if the whitelist is not empty
    function verifyOracleWhitelist(address oracle) external view {
        _verifyOracleWhitelist(oracle);
    }

    function _verifyOracleWhitelist(address oracle) internal view {
        if (whitelistedOraclesCount > 0 && !oracleWhitelist[oracle]) revert OnlyWhitelistedOracleAllowed();
    }

    function addOracleToWhitelist(address oracle) external onlyGov {
        if (!oracleWhitelist[oracle]) {
            oracleWhitelist[oracle] = true;
            whitelistedOraclesCount++;
        }
    }

    function removeOracleFromWhitelist(address oracle) external onlyGov {
        if (oracleWhitelist[oracle]) {
            oracleWhitelist[oracle] = false;
            whitelistedOraclesCount--;
        }
    }

    // Combination for gas efficiency

    function verifyUserOpSignerAndOracleAndSelector(
        address userOpSigner,
        address oracle,
        bytes4 selector
    )
        external
        view
    {
        _userOpSignerIsAuthorized(userOpSigner);
        _verifyOracleWhitelist(oracle);
        _verifyAllowedSelector(selector);
    }

    // ---------------------------------------------------- //
    //                  Atlas Hook Overrides                //
    // ---------------------------------------------------- //

    /**
     * @notice Checks if the bundler is whitelisted and if the user is calling the update function
     * @param userOp The user operation to check
     * @return An empty bytes array
     * @dev This function is delegatcalled
     */
    function _preOpsCall(UserOperation calldata userOp) internal view virtual override returns (bytes memory) {
        // The userOp dapp must be this control
        if (userOp.dapp != CONTROL) revert InvalidUserOpDapp();

        // The user must be calling the update function
        if (bytes4(userOp.data) != bytes4(RedstoneOevDAppControl.update.selector)) {
            revert InvalidUserEntryCall();
        }

        (address _oracle, bytes memory _updateCallData) = abi.decode(userOp.data[4:], (address, bytes));

        // The user must be the authorized user op signer
        // The called oracle must be whitelisted
        // The update call data must be a valid function call
        RedstoneOevDAppControl(CONTROL).verifyUserOpSignerAndOracleAndSelector(
            userOp.from, _oracle, bytes4(_updateCallData)
        );

        // return empty bytes
        return "";
    }

    /**
     * @notice Allocates the bid amount to the relevant parties
     * @param bidAmount The bid amount to be allocated
     * @dev This function is delegatecalled
     */
    function _allocateValueCall(bool, address, uint256 bidAmount, bytes calldata) internal virtual override {
        if (bidAmount == 0) return;

        // Single atomic call that transfers ETH and updates accounting
        // This is delegatecalled, so msg.value will be bidAmount and sender will be ExecutionEnvironment
        RedstoneOevDAppControl(CONTROL).creditOEV{ value: bidAmount }();
    }

    // ---------------------------------------------------- //
    //                    UserOp Function                   //
    // ---------------------------------------------------- //

    /**
     * @notice Updates the oracle with the new values
     * @param oracle The oracle to update
     * @param callData The call data to update the oracle with
     */
    function update(address oracle, bytes calldata callData) external {
        if (msg.sender != authorizedExecutionEnv) revert InvalidExecutionEnv();

        // Parameters have already been validated in _preOpsCall
        (bool success,) = oracle.call(callData);
        if (!success) revert OracleUpdateFailed();
    }

    // ---------------------------------------------------- //
    //                    View Functions                    //
    // ---------------------------------------------------- //

    function getBidFormat(UserOperation calldata) public pure override returns (address bidToken) {
        return address(0); // ETH is bid token
    }

    function getBidValue(SolverOperation calldata solverOp) public pure override returns (uint256) {
        return solverOp.bidAmount;
    }

    function getSolverGasLimit() public view override returns (uint32) {
        return solverGasLimit;
    }

    function getDAppGasLimit() public view override returns (uint32) {
        return dappGasLimit;
    }

    function getBundlerSurchargeRate() public view override returns (uint24) {
        return bundlerSurchargeRate;
    }

    function getSharesAndDestinations()
        external
        view
        returns (
            uint256 oevShareFastlane_,
            address oevAllocationDestinationFastlane_,
            address oevAllocationDestinationProtocol_
        )
    {
        return (s_oevTracker.fastlaneShare, oevAllocationDestinationFastlane, oevAllocationDestinationProtocol);
    }

    /**
     * @notice Returns the fastlane share of OEV in basis points
     * @return The fastlane share (1 = 0.01%, 100 = 1%, 10_000 = 100%)
     */
    function oevShareFastlane() external view returns (uint256) {
        return s_oevTracker.fastlaneShare;
    }

    /**
     * @notice Returns the accumulated OEV for fastlane
     * @return The accumulated OEV amount for fastlane
     */
    function accumulatedOevFastlane() external view returns (uint256) {
        return s_oevTracker.fastlaneAccumulated;
    }

    /**
     * @notice Returns the accumulated OEV for protocol
     * @return The accumulated OEV amount for protocol
     */
    function accumulatedOevProtocol() external view returns (uint256) {
        return s_oevTracker.protocolAccumulated;
    }

    // ---------------------------------------------------- //
    //                  Internal Functions                  //
    // ---------------------------------------------------- //

    // Called whenever authorizedUserOpSigner is updated
    function _updateAuthorizedExecutionEnv(address newAuthedUserOpSigner) internal {
        (authorizedExecutionEnv,,) = IAtlas(ATLAS).getExecutionEnvironment(newAuthedUserOpSigner, address(this));
    }

    // Called by _allocateValueCall to atomically receive ETH and update accounting
    function creditOEV() external payable {
        if (msg.sender != authorizedExecutionEnv) revert InvalidExecutionEnv();

        OEVTracker memory _oevTracker = s_oevTracker;

        // Calculate shares based on received ETH
        uint256 fastlaneAmount = (msg.value * _oevTracker.fastlaneShare) / OEV_SHARE_SCALE;
        uint256 protocolAmount = msg.value - fastlaneAmount;

        // Attribute each share of OEV to the correct destination
        _oevTracker.fastlaneAccumulated += fastlaneAmount.toUint120();
        _oevTracker.protocolAccumulated += protocolAmount.toUint120();

        // Persist OEVTracker changes to storage
        s_oevTracker = _oevTracker;

        // Emit event for monitoring
        emit OevAllocated(msg.value, fastlaneAmount, protocolAmount);
    }
}

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

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @author Permit2 operations from (https://github.com/Uniswap/permit2/blob/main/src/libraries/Permit2Lib.sol)
///
/// @dev Note:
/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.
/// - For ERC20s, this implementation won't check that a token has code,
///   responsibility is delegated to the caller.
library SafeTransferLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /// @dev The Permit2 operation has failed.
    error Permit2Failed();

    /// @dev The Permit2 amount must be less than `2**160 - 1`.
    error Permit2AmountOverflow();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.
    uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;

    /// @dev Suggested gas stipend for contract receiving ETH to perform a few
    /// storage reads and writes, but low enough to prevent griefing.
    uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;

    /// @dev The unique EIP-712 domain domain separator for the DAI token contract.
    bytes32 internal constant DAI_DOMAIN_SEPARATOR =
        0xdbb8cf42e1ecb028be3f3dbc922e1d878b963f411dc388ced501601c60f7c6f7;

    /// @dev The address for the WETH9 contract on Ethereum mainnet.
    address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

    /// @dev The canonical Permit2 address.
    /// [Github](https://github.com/Uniswap/permit2)
    /// [Etherscan](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3)
    address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ETH OPERATIONS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
    //
    // The regular variants:
    // - Forwards all remaining gas to the target.
    // - Reverts if the target reverts.
    // - Reverts if the current contract has insufficient balance.
    //
    // The force variants:
    // - Forwards with an optional gas stipend
    //   (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
    // - If the target reverts, or if the gas stipend is exhausted,
    //   creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
    //   Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
    // - Reverts if the current contract has insufficient balance.
    //
    // The try variants:
    // - Forwards with a mandatory gas stipend.
    // - Instead of reverting, returns whether the transfer succeeded.

    /// @dev Sends `amount` (in wei) ETH to `to`.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`.
    function safeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer all the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // forgefmt: disable-next-item
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function trySafeTransferAllETH(address to, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC20 OPERATIONS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    ///
    /// The `from` account must have at least `amount` approved for the current contract to manage.
    function trySafeTransferFrom(address token, address from, address to, uint256 amount)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            success :=
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends all of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have their entire balance approved for the current contract to manage.
    function safeTransferAllFrom(address token, address from, address to)
        internal
        returns (uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
            amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sends all of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransferAll(address token, address to) internal returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, address()) // Store the address of the current contract.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x14, to) // Store the `to` argument.
            amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
    /// then retries the approval again (some tokens, e.g. USDT, requires this).
    /// Reverts upon failure.
    function safeApproveWithRetry(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, retrying upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x34, 0) // Store 0 for the `amount`.
                mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
                pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.
                mstore(0x34, amount) // Store back the original `amount`.
                // Retry the approval, reverting upon failure.
                if iszero(
                    and(
                        or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                        call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                    )
                ) {
                    mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Returns the amount of ERC20 `token` owned by `account`.
    /// Returns zero if the `token` does not exist.
    function balanceOf(address token, address account) internal view returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, account) // Store the `account` argument.
            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            amount :=
                mul( // The arguments of `mul` are evaluated from right to left.
                    mload(0x20),
                    and( // The arguments of `and` are evaluated from right to left.
                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
                    )
                )
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// If the initial attempt fails, try to use Permit2 to transfer the token.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for the current contract to manage.
    function safeTransferFrom2(address token, address from, address to, uint256 amount) internal {
        if (!trySafeTransferFrom(token, from, to, amount)) {
            permit2TransferFrom(token, from, to, amount);
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to` via Permit2.
    /// Reverts upon failure.
    function permit2TransferFrom(address token, address from, address to, uint256 amount)
        internal
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(add(m, 0x74), shr(96, shl(96, token)))
            mstore(add(m, 0x54), amount)
            mstore(add(m, 0x34), to)
            mstore(add(m, 0x20), shl(96, from))
            // `transferFrom(address,address,uint160,address)`.
            mstore(m, 0x36c78516000000000000000000000000)
            let p := PERMIT2
            let exists := eq(chainid(), 1)
            if iszero(exists) { exists := iszero(iszero(extcodesize(p))) }
            if iszero(and(call(gas(), p, 0, add(m, 0x10), 0x84, codesize(), 0x00), exists)) {
                mstore(0x00, 0x7939f4248757f0fd) // `TransferFromFailed()` or `Permit2AmountOverflow()`.
                revert(add(0x18, shl(2, iszero(iszero(shr(160, amount))))), 0x04)
            }
        }
    }

    /// @dev Permit a user to spend a given amount of
    /// another user's tokens via native EIP-2612 permit if possible, falling
    /// back to Permit2 if native permit fails or is not implemented on the token.
    function permit2(
        address token,
        address owner,
        address spender,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        bool success;
        /// @solidity memory-safe-assembly
        assembly {
            for {} shl(96, xor(token, WETH9)) {} {
                mstore(0x00, 0x3644e515) // `DOMAIN_SEPARATOR()`.
                if iszero(
                    and( // The arguments of `and` are evaluated from right to left.
                        lt(iszero(mload(0x00)), eq(returndatasize(), 0x20)), // Returns 1 non-zero word.
                        // Gas stipend to limit gas burn for tokens that don't refund gas when
                        // an non-existing function is called. 5K should be enough for a SLOAD.
                        staticcall(5000, token, 0x1c, 0x04, 0x00, 0x20)
                    )
                ) { break }
                // After here, we can be sure that token is a contract.
                let m := mload(0x40)
                mstore(add(m, 0x34), spender)
                mstore(add(m, 0x20), shl(96, owner))
                mstore(add(m, 0x74), deadline)
                if eq(mload(0x00), DAI_DOMAIN_SEPARATOR) {
                    mstore(0x14, owner)
                    mstore(0x00, 0x7ecebe00000000000000000000000000) // `nonces(address)`.
                    mstore(add(m, 0x94), staticcall(gas(), token, 0x10, 0x24, add(m, 0x54), 0x20))
                    mstore(m, 0x8fcbaf0c000000000000000000000000) // `IDAIPermit.permit`.
                    // `nonces` is already at `add(m, 0x54)`.
                    // `1` is already stored at `add(m, 0x94)`.
                    mstore(add(m, 0xb4), and(0xff, v))
                    mstore(add(m, 0xd4), r)
                    mstore(add(m, 0xf4), s)
                    success := call(gas(), token, 0, add(m, 0x10), 0x104, codesize(), 0x00)
                    break
                }
                mstore(m, 0xd505accf000000000000000000000000) // `IERC20Permit.permit`.
                mstore(add(m, 0x54), amount)
                mstore(add(m, 0x94), and(0xff, v))
                mstore(add(m, 0xb4), r)
                mstore(add(m, 0xd4), s)
                success := call(gas(), token, 0, add(m, 0x10), 0xe4, codesize(), 0x00)
                break
            }
        }
        if (!success) simplePermit2(token, owner, spender, amount, deadline, v, r, s);
    }

    /// @dev Simple permit on the Permit2 contract.
    function simplePermit2(
        address token,
        address owner,
        address spender,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, 0x927da105) // `allowance(address,address,address)`.
            {
                let addressMask := shr(96, not(0))
                mstore(add(m, 0x20), and(addressMask, owner))
                mstore(add(m, 0x40), and(addressMask, token))
                mstore(add(m, 0x60), and(addressMask, spender))
                mstore(add(m, 0xc0), and(addressMask, spender))
            }
            let p := mul(PERMIT2, iszero(shr(160, amount)))
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x5f), // Returns 3 words: `amount`, `expiration`, `nonce`.
                    staticcall(gas(), p, add(m, 0x1c), 0x64, add(m, 0x60), 0x60)
                )
            ) {
                mstore(0x00, 0x6b836e6b8757f0fd) // `Permit2Failed()` or `Permit2AmountOverflow()`.
                revert(add(0x18, shl(2, iszero(p))), 0x04)
            }
            mstore(m, 0x2b67b570) // `Permit2.permit` (PermitSingle variant).
            // `owner` is already `add(m, 0x20)`.
            // `token` is already at `add(m, 0x40)`.
            mstore(add(m, 0x60), amount)
            mstore(add(m, 0x80), 0xffffffffffff) // `expiration = type(uint48).max`.
            // `nonce` is already at `add(m, 0xa0)`.
            // `spender` is already at `add(m, 0xc0)`.
            mstore(add(m, 0xe0), deadline)
            mstore(add(m, 0x100), 0x100) // `signature` offset.
            mstore(add(m, 0x120), 0x41) // `signature` length.
            mstore(add(m, 0x140), r)
            mstore(add(m, 0x160), s)
            mstore(add(m, 0x180), shl(248, v))
            if iszero(call(gas(), p, 0, add(m, 0x1c), 0x184, codesize(), 0x00)) {
                mstore(0x00, 0x6b836e6b) // `Permit2Failed()`.
                revert(0x1c, 0x04)
            }
        }
    }
}

File 3 of 22 : SafeCastLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Safe integer casting library that reverts on overflow.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeCastLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol)
/// @dev Optimized for runtime gas for very high number of optimizer runs (i.e. >= 1000000).
library SafeCastLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    error Overflow();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*          UNSIGNED INTEGER SAFE CASTING OPERATIONS          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    function toUint8(uint256 x) internal pure returns (uint8) {
        if (x >= 1 << 8) _revertOverflow();
        return uint8(x);
    }

    function toUint16(uint256 x) internal pure returns (uint16) {
        if (x >= 1 << 16) _revertOverflow();
        return uint16(x);
    }

    function toUint24(uint256 x) internal pure returns (uint24) {
        if (x >= 1 << 24) _revertOverflow();
        return uint24(x);
    }

    function toUint32(uint256 x) internal pure returns (uint32) {
        if (x >= 1 << 32) _revertOverflow();
        return uint32(x);
    }

    function toUint40(uint256 x) internal pure returns (uint40) {
        if (x >= 1 << 40) _revertOverflow();
        return uint40(x);
    }

    function toUint48(uint256 x) internal pure returns (uint48) {
        if (x >= 1 << 48) _revertOverflow();
        return uint48(x);
    }

    function toUint56(uint256 x) internal pure returns (uint56) {
        if (x >= 1 << 56) _revertOverflow();
        return uint56(x);
    }

    function toUint64(uint256 x) internal pure returns (uint64) {
        if (x >= 1 << 64) _revertOverflow();
        return uint64(x);
    }

    function toUint72(uint256 x) internal pure returns (uint72) {
        if (x >= 1 << 72) _revertOverflow();
        return uint72(x);
    }

    function toUint80(uint256 x) internal pure returns (uint80) {
        if (x >= 1 << 80) _revertOverflow();
        return uint80(x);
    }

    function toUint88(uint256 x) internal pure returns (uint88) {
        if (x >= 1 << 88) _revertOverflow();
        return uint88(x);
    }

    function toUint96(uint256 x) internal pure returns (uint96) {
        if (x >= 1 << 96) _revertOverflow();
        return uint96(x);
    }

    function toUint104(uint256 x) internal pure returns (uint104) {
        if (x >= 1 << 104) _revertOverflow();
        return uint104(x);
    }

    function toUint112(uint256 x) internal pure returns (uint112) {
        if (x >= 1 << 112) _revertOverflow();
        return uint112(x);
    }

    function toUint120(uint256 x) internal pure returns (uint120) {
        if (x >= 1 << 120) _revertOverflow();
        return uint120(x);
    }

    function toUint128(uint256 x) internal pure returns (uint128) {
        if (x >= 1 << 128) _revertOverflow();
        return uint128(x);
    }

    function toUint136(uint256 x) internal pure returns (uint136) {
        if (x >= 1 << 136) _revertOverflow();
        return uint136(x);
    }

    function toUint144(uint256 x) internal pure returns (uint144) {
        if (x >= 1 << 144) _revertOverflow();
        return uint144(x);
    }

    function toUint152(uint256 x) internal pure returns (uint152) {
        if (x >= 1 << 152) _revertOverflow();
        return uint152(x);
    }

    function toUint160(uint256 x) internal pure returns (uint160) {
        if (x >= 1 << 160) _revertOverflow();
        return uint160(x);
    }

    function toUint168(uint256 x) internal pure returns (uint168) {
        if (x >= 1 << 168) _revertOverflow();
        return uint168(x);
    }

    function toUint176(uint256 x) internal pure returns (uint176) {
        if (x >= 1 << 176) _revertOverflow();
        return uint176(x);
    }

    function toUint184(uint256 x) internal pure returns (uint184) {
        if (x >= 1 << 184) _revertOverflow();
        return uint184(x);
    }

    function toUint192(uint256 x) internal pure returns (uint192) {
        if (x >= 1 << 192) _revertOverflow();
        return uint192(x);
    }

    function toUint200(uint256 x) internal pure returns (uint200) {
        if (x >= 1 << 200) _revertOverflow();
        return uint200(x);
    }

    function toUint208(uint256 x) internal pure returns (uint208) {
        if (x >= 1 << 208) _revertOverflow();
        return uint208(x);
    }

    function toUint216(uint256 x) internal pure returns (uint216) {
        if (x >= 1 << 216) _revertOverflow();
        return uint216(x);
    }

    function toUint224(uint256 x) internal pure returns (uint224) {
        if (x >= 1 << 224) _revertOverflow();
        return uint224(x);
    }

    function toUint232(uint256 x) internal pure returns (uint232) {
        if (x >= 1 << 232) _revertOverflow();
        return uint232(x);
    }

    function toUint240(uint256 x) internal pure returns (uint240) {
        if (x >= 1 << 240) _revertOverflow();
        return uint240(x);
    }

    function toUint248(uint256 x) internal pure returns (uint248) {
        if (x >= 1 << 248) _revertOverflow();
        return uint248(x);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*           SIGNED INTEGER SAFE CASTING OPERATIONS           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    function toInt8(int256 x) internal pure returns (int8) {
        unchecked {
            if (((1 << 7) + uint256(x)) >> 8 == uint256(0)) return int8(x);
            _revertOverflow();
        }
    }

    function toInt16(int256 x) internal pure returns (int16) {
        unchecked {
            if (((1 << 15) + uint256(x)) >> 16 == uint256(0)) return int16(x);
            _revertOverflow();
        }
    }

    function toInt24(int256 x) internal pure returns (int24) {
        unchecked {
            if (((1 << 23) + uint256(x)) >> 24 == uint256(0)) return int24(x);
            _revertOverflow();
        }
    }

    function toInt32(int256 x) internal pure returns (int32) {
        unchecked {
            if (((1 << 31) + uint256(x)) >> 32 == uint256(0)) return int32(x);
            _revertOverflow();
        }
    }

    function toInt40(int256 x) internal pure returns (int40) {
        unchecked {
            if (((1 << 39) + uint256(x)) >> 40 == uint256(0)) return int40(x);
            _revertOverflow();
        }
    }

    function toInt48(int256 x) internal pure returns (int48) {
        unchecked {
            if (((1 << 47) + uint256(x)) >> 48 == uint256(0)) return int48(x);
            _revertOverflow();
        }
    }

    function toInt56(int256 x) internal pure returns (int56) {
        unchecked {
            if (((1 << 55) + uint256(x)) >> 56 == uint256(0)) return int56(x);
            _revertOverflow();
        }
    }

    function toInt64(int256 x) internal pure returns (int64) {
        unchecked {
            if (((1 << 63) + uint256(x)) >> 64 == uint256(0)) return int64(x);
            _revertOverflow();
        }
    }

    function toInt72(int256 x) internal pure returns (int72) {
        unchecked {
            if (((1 << 71) + uint256(x)) >> 72 == uint256(0)) return int72(x);
            _revertOverflow();
        }
    }

    function toInt80(int256 x) internal pure returns (int80) {
        unchecked {
            if (((1 << 79) + uint256(x)) >> 80 == uint256(0)) return int80(x);
            _revertOverflow();
        }
    }

    function toInt88(int256 x) internal pure returns (int88) {
        unchecked {
            if (((1 << 87) + uint256(x)) >> 88 == uint256(0)) return int88(x);
            _revertOverflow();
        }
    }

    function toInt96(int256 x) internal pure returns (int96) {
        unchecked {
            if (((1 << 95) + uint256(x)) >> 96 == uint256(0)) return int96(x);
            _revertOverflow();
        }
    }

    function toInt104(int256 x) internal pure returns (int104) {
        unchecked {
            if (((1 << 103) + uint256(x)) >> 104 == uint256(0)) return int104(x);
            _revertOverflow();
        }
    }

    function toInt112(int256 x) internal pure returns (int112) {
        unchecked {
            if (((1 << 111) + uint256(x)) >> 112 == uint256(0)) return int112(x);
            _revertOverflow();
        }
    }

    function toInt120(int256 x) internal pure returns (int120) {
        unchecked {
            if (((1 << 119) + uint256(x)) >> 120 == uint256(0)) return int120(x);
            _revertOverflow();
        }
    }

    function toInt128(int256 x) internal pure returns (int128) {
        unchecked {
            if (((1 << 127) + uint256(x)) >> 128 == uint256(0)) return int128(x);
            _revertOverflow();
        }
    }

    function toInt136(int256 x) internal pure returns (int136) {
        unchecked {
            if (((1 << 135) + uint256(x)) >> 136 == uint256(0)) return int136(x);
            _revertOverflow();
        }
    }

    function toInt144(int256 x) internal pure returns (int144) {
        unchecked {
            if (((1 << 143) + uint256(x)) >> 144 == uint256(0)) return int144(x);
            _revertOverflow();
        }
    }

    function toInt152(int256 x) internal pure returns (int152) {
        unchecked {
            if (((1 << 151) + uint256(x)) >> 152 == uint256(0)) return int152(x);
            _revertOverflow();
        }
    }

    function toInt160(int256 x) internal pure returns (int160) {
        unchecked {
            if (((1 << 159) + uint256(x)) >> 160 == uint256(0)) return int160(x);
            _revertOverflow();
        }
    }

    function toInt168(int256 x) internal pure returns (int168) {
        unchecked {
            if (((1 << 167) + uint256(x)) >> 168 == uint256(0)) return int168(x);
            _revertOverflow();
        }
    }

    function toInt176(int256 x) internal pure returns (int176) {
        unchecked {
            if (((1 << 175) + uint256(x)) >> 176 == uint256(0)) return int176(x);
            _revertOverflow();
        }
    }

    function toInt184(int256 x) internal pure returns (int184) {
        unchecked {
            if (((1 << 183) + uint256(x)) >> 184 == uint256(0)) return int184(x);
            _revertOverflow();
        }
    }

    function toInt192(int256 x) internal pure returns (int192) {
        unchecked {
            if (((1 << 191) + uint256(x)) >> 192 == uint256(0)) return int192(x);
            _revertOverflow();
        }
    }

    function toInt200(int256 x) internal pure returns (int200) {
        unchecked {
            if (((1 << 199) + uint256(x)) >> 200 == uint256(0)) return int200(x);
            _revertOverflow();
        }
    }

    function toInt208(int256 x) internal pure returns (int208) {
        unchecked {
            if (((1 << 207) + uint256(x)) >> 208 == uint256(0)) return int208(x);
            _revertOverflow();
        }
    }

    function toInt216(int256 x) internal pure returns (int216) {
        unchecked {
            if (((1 << 215) + uint256(x)) >> 216 == uint256(0)) return int216(x);
            _revertOverflow();
        }
    }

    function toInt224(int256 x) internal pure returns (int224) {
        unchecked {
            if (((1 << 223) + uint256(x)) >> 224 == uint256(0)) return int224(x);
            _revertOverflow();
        }
    }

    function toInt232(int256 x) internal pure returns (int232) {
        unchecked {
            if (((1 << 231) + uint256(x)) >> 232 == uint256(0)) return int232(x);
            _revertOverflow();
        }
    }

    function toInt240(int256 x) internal pure returns (int240) {
        unchecked {
            if (((1 << 239) + uint256(x)) >> 240 == uint256(0)) return int240(x);
            _revertOverflow();
        }
    }

    function toInt248(int256 x) internal pure returns (int248) {
        unchecked {
            if (((1 << 247) + uint256(x)) >> 248 == uint256(0)) return int248(x);
            _revertOverflow();
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*               OTHER SAFE CASTING OPERATIONS                */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    function toInt8(uint256 x) internal pure returns (int8) {
        if (x >= 1 << 7) _revertOverflow();
        return int8(int256(x));
    }

    function toInt16(uint256 x) internal pure returns (int16) {
        if (x >= 1 << 15) _revertOverflow();
        return int16(int256(x));
    }

    function toInt24(uint256 x) internal pure returns (int24) {
        if (x >= 1 << 23) _revertOverflow();
        return int24(int256(x));
    }

    function toInt32(uint256 x) internal pure returns (int32) {
        if (x >= 1 << 31) _revertOverflow();
        return int32(int256(x));
    }

    function toInt40(uint256 x) internal pure returns (int40) {
        if (x >= 1 << 39) _revertOverflow();
        return int40(int256(x));
    }

    function toInt48(uint256 x) internal pure returns (int48) {
        if (x >= 1 << 47) _revertOverflow();
        return int48(int256(x));
    }

    function toInt56(uint256 x) internal pure returns (int56) {
        if (x >= 1 << 55) _revertOverflow();
        return int56(int256(x));
    }

    function toInt64(uint256 x) internal pure returns (int64) {
        if (x >= 1 << 63) _revertOverflow();
        return int64(int256(x));
    }

    function toInt72(uint256 x) internal pure returns (int72) {
        if (x >= 1 << 71) _revertOverflow();
        return int72(int256(x));
    }

    function toInt80(uint256 x) internal pure returns (int80) {
        if (x >= 1 << 79) _revertOverflow();
        return int80(int256(x));
    }

    function toInt88(uint256 x) internal pure returns (int88) {
        if (x >= 1 << 87) _revertOverflow();
        return int88(int256(x));
    }

    function toInt96(uint256 x) internal pure returns (int96) {
        if (x >= 1 << 95) _revertOverflow();
        return int96(int256(x));
    }

    function toInt104(uint256 x) internal pure returns (int104) {
        if (x >= 1 << 103) _revertOverflow();
        return int104(int256(x));
    }

    function toInt112(uint256 x) internal pure returns (int112) {
        if (x >= 1 << 111) _revertOverflow();
        return int112(int256(x));
    }

    function toInt120(uint256 x) internal pure returns (int120) {
        if (x >= 1 << 119) _revertOverflow();
        return int120(int256(x));
    }

    function toInt128(uint256 x) internal pure returns (int128) {
        if (x >= 1 << 127) _revertOverflow();
        return int128(int256(x));
    }

    function toInt136(uint256 x) internal pure returns (int136) {
        if (x >= 1 << 135) _revertOverflow();
        return int136(int256(x));
    }

    function toInt144(uint256 x) internal pure returns (int144) {
        if (x >= 1 << 143) _revertOverflow();
        return int144(int256(x));
    }

    function toInt152(uint256 x) internal pure returns (int152) {
        if (x >= 1 << 151) _revertOverflow();
        return int152(int256(x));
    }

    function toInt160(uint256 x) internal pure returns (int160) {
        if (x >= 1 << 159) _revertOverflow();
        return int160(int256(x));
    }

    function toInt168(uint256 x) internal pure returns (int168) {
        if (x >= 1 << 167) _revertOverflow();
        return int168(int256(x));
    }

    function toInt176(uint256 x) internal pure returns (int176) {
        if (x >= 1 << 175) _revertOverflow();
        return int176(int256(x));
    }

    function toInt184(uint256 x) internal pure returns (int184) {
        if (x >= 1 << 183) _revertOverflow();
        return int184(int256(x));
    }

    function toInt192(uint256 x) internal pure returns (int192) {
        if (x >= 1 << 191) _revertOverflow();
        return int192(int256(x));
    }

    function toInt200(uint256 x) internal pure returns (int200) {
        if (x >= 1 << 199) _revertOverflow();
        return int200(int256(x));
    }

    function toInt208(uint256 x) internal pure returns (int208) {
        if (x >= 1 << 207) _revertOverflow();
        return int208(int256(x));
    }

    function toInt216(uint256 x) internal pure returns (int216) {
        if (x >= 1 << 215) _revertOverflow();
        return int216(int256(x));
    }

    function toInt224(uint256 x) internal pure returns (int224) {
        if (x >= 1 << 223) _revertOverflow();
        return int224(int256(x));
    }

    function toInt232(uint256 x) internal pure returns (int232) {
        if (x >= 1 << 231) _revertOverflow();
        return int232(int256(x));
    }

    function toInt240(uint256 x) internal pure returns (int240) {
        if (x >= 1 << 239) _revertOverflow();
        return int240(int256(x));
    }

    function toInt248(uint256 x) internal pure returns (int248) {
        if (x >= 1 << 247) _revertOverflow();
        return int248(int256(x));
    }

    function toInt256(uint256 x) internal pure returns (int256) {
        if (int256(x) >= 0) return int256(x);
        _revertOverflow();
    }

    function toUint256(int256 x) internal pure returns (uint256) {
        if (x >= 0) return uint256(x);
        _revertOverflow();
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      PRIVATE HELPERS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    function _revertOverflow() private pure {
        /// @solidity memory-safe-assembly
        assembly {
            // Store the function selector of `Overflow()`.
            mstore(0x00, 0x35278d12)
            // Revert with (offset, size).
            revert(0x1c, 0x04)
        }
    }
}

File 4 of 22 : IAtlas.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "../types/SolverOperation.sol";
import "../types/UserOperation.sol";
import "../types/DAppOperation.sol";

interface IAtlas {
    // Atlas.sol
    function metacall(
        UserOperation calldata userOp,
        SolverOperation[] calldata solverOps,
        DAppOperation calldata dAppOp,
        address gasRefundBeneficiary
    )
        external
        payable
        returns (bool auctionWon);

    // Factory.sol
    function createExecutionEnvironment(
        address user,
        address control
    )
        external
        returns (address executionEnvironment);
    function getExecutionEnvironment(
        address user,
        address control
    )
        external
        view
        returns (address executionEnvironment, uint32 callConfig, bool exists);

    // AtlETH.sol
    function balanceOf(address account) external view returns (uint256);
    function balanceOfBonded(address account) external view returns (uint256);
    function balanceOfUnbonding(address account) external view returns (uint256);
    function accountLastActiveBlock(address account) external view returns (uint256);
    function unbondingCompleteBlock(address account) external view returns (uint256);
    function deposit() external payable;
    function withdraw(uint256 amount) external;
    function bond(uint256 amount) external;
    function depositAndBond(uint256 amountToBond) external payable;
    function unbond(uint256 amount) external;
    function redeem(uint256 amount) external;

    function withdrawSurcharge() external;
    function transferSurchargeRecipient(address newRecipient) external;
    function becomeSurchargeRecipient() external;
    function setSurchargeRates(uint128 newAtlasRate, uint128 newBundlerRate) external;

    // Permit69.sol
    function transferUserERC20(
        address token,
        address destination,
        uint256 amount,
        address user,
        address control
    )
        external;
    function transferDAppERC20(
        address token,
        address destination,
        uint256 amount,
        address user,
        address control
    )
        external;

    // GasAccounting.sol
    function contribute() external payable;
    function borrow(uint256 amount) external payable;
    function shortfall() external view returns (uint256 gasLiability, uint256 borrowLiability);
    function reconcile(uint256 maxApprovedGasSpend) external payable returns (uint256 owed);

    // SafetyLocks.sol
    function isUnlocked() external view returns (bool);

    // Storage.sol
    function VERIFICATION() external view returns (address);
    function SIMULATOR() external view returns (address);
    function L2_GAS_CALCULATOR() external view returns (address);
    function ESCROW_DURATION() external view returns (uint256);

    function solverLockData() external view returns (address currentSolver, bool calledBack, bool fulfilled);
    function totalSupply() external view returns (uint256);
    function bondedTotalSupply() external view returns (uint256);
    function accessData(address account)
        external
        view
        returns (
            uint112 bonded,
            uint32 lastAccessedBlock,
            uint24 auctionWins,
            uint24 auctionFails,
            uint64 totalGasValueUsed
        );
    function solverOpHashes(bytes32 opHash) external view returns (bool);
    function lock() external view returns (address activeEnvironment, uint32 callConfig, uint8 phase);
    function solverLock() external view returns (uint256);
    function cumulativeSurcharge() external view returns (uint256);
    function surchargeRecipient() external view returns (address);
    function pendingSurchargeRecipient() external view returns (address);
    function getAtlasSurchargeRate() external view returns (uint256);
}

//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import { DAppControlTemplate } from "./ControlTemplate.sol";
import { ExecutionBase } from "../common/ExecutionBase.sol";
import { ExecutionPhase } from "../types/LockTypes.sol";
import { CallBits } from "../libraries/CallBits.sol";
import "../types/SolverOperation.sol";
import "../types/UserOperation.sol";
import "../types/ConfigTypes.sol";
import { AtlasErrors } from "../types/AtlasErrors.sol";
import { AtlasEvents } from "../types/AtlasEvents.sol";
import { IAtlas } from "../interfaces/IAtlas.sol";
import { ValidCallsResult } from "../types/ValidCalls.sol";
import { IAtlasVerification } from "../interfaces/IAtlasVerification.sol";

/// @title DAppControl
/// @author FastLane Labs
/// @notice DAppControl is the base contract which should be inherited by any Atlas dApps.
/// @notice Storage variables (except immutable) will be defaulted if accessed by delegatecalls.
/// @notice If an extension DAppControl uses storage variables, those should not be accessed by delegatecalls.
abstract contract DAppControl is DAppControlTemplate, ExecutionBase {
    using CallBits for uint32;

    uint32 public immutable CALL_CONFIG;
    address public immutable CONTROL;
    address public immutable ATLAS_VERIFICATION;

    address public governance;
    address public pendingGovernance;

    constructor(address atlas, address initialGovernance, CallConfig memory callConfig) ExecutionBase(atlas) {
        ATLAS_VERIFICATION = IAtlas(atlas).VERIFICATION();
        CALL_CONFIG = CallBits.encodeCallConfig(callConfig);
        _validateCallConfig(CALL_CONFIG);
        CONTROL = address(this);

        governance = initialGovernance;
    }

    // Safety and support functions and modifiers that make the relationship between dApp
    // and FastLane's backend trustless.

    // Modifiers
    modifier validControl() {
        if (CONTROL != _control()) revert AtlasErrors.InvalidControl();
        _;
    }

    // Reverts if phase in Atlas is not the specified phase.
    // This is required to prevent reentrancy in hooks from other hooks in different phases.
    modifier onlyPhase(ExecutionPhase phase) {
        (,, uint8 atlasPhase) = IAtlas(ATLAS).lock();
        if (atlasPhase != uint8(phase)) revert AtlasErrors.WrongPhase();
        _;
    }

    modifier mustBeCalled() {
        if (address(this) != CONTROL) revert AtlasErrors.NoDelegatecall();
        _;
    }

    /// @notice The preOpsCall hook which may be called before the UserOperation is executed.
    /// @param userOp The UserOperation struct.
    /// @return data Data to be passed to the next call phase.
    function preOpsCall(UserOperation calldata userOp)
        external
        payable
        validControl
        onlyAtlasEnvironment
        onlyPhase(ExecutionPhase.PreOps)
        returns (bytes memory)
    {
        // check if dapps using this DApontrol can handle the userOp
        _checkUserOperation(userOp);

        return _preOpsCall(userOp);
    }

    /// @notice The preSolverCall hook which may be called before the SolverOperation is executed.
    /// @dev Should revert if any DApp-specific checks fail to indicate non-fulfillment.
    /// @param solverOp The SolverOperation to be executed after this hook has been called.
    /// @param returnData Data returned from the previous call phase.
    function preSolverCall(
        SolverOperation calldata solverOp,
        bytes calldata returnData
    )
        external
        payable
        validControl
        validSolver(solverOp)
        onlyAtlasEnvironment
        onlyPhase(ExecutionPhase.PreSolver)
    {
        _preSolverCall(solverOp, returnData);
    }

    /// @notice The postSolverCall hook which may be called after the SolverOperation has been executed.
    /// @dev Should revert if any DApp-specific checks fail to indicate non-fulfillment.
    /// @param solverOp The SolverOperation struct that was executed just before this hook was called.
    /// @param returnData Data returned from the previous call phase.
    function postSolverCall(
        SolverOperation calldata solverOp,
        bytes calldata returnData
    )
        external
        payable
        validControl
        validSolver(solverOp)
        onlyAtlasEnvironment
        onlyPhase(ExecutionPhase.PostSolver)
    {
        _postSolverCall(solverOp, returnData);
    }

    /// @notice The allocateValueCall hook which is called after a successful SolverOperation.
    /// @param bidToken The address of the token used for the winning SolverOperation's bid.
    /// @param bidAmount The winning bid amount.
    /// @param data Data returned from the previous call phase.
    function allocateValueCall(
        bool solved,
        address bidToken,
        uint256 bidAmount,
        bytes calldata data
    )
        external
        validControl
        onlyAtlasEnvironment
        onlyPhase(ExecutionPhase.AllocateValue)
    {
        _allocateValueCall(solved, bidToken, bidAmount, data);
    }

    function userDelegated() external view returns (bool delegated) {
        delegated = CALL_CONFIG.needsDelegateUser();
    }

    function requireSequentialUserNonces() external view returns (bool isSequential) {
        isSequential = CALL_CONFIG.needsSequentialUserNonces();
    }

    function requireSequentialDAppNonces() external view returns (bool isSequential) {
        isSequential = CALL_CONFIG.needsSequentialDAppNonces();
    }

    /// @notice Returns the DAppConfig struct of this DAppControl contract.
    /// @param userOp The UserOperation struct.
    /// @return dConfig The DAppConfig struct of this DAppControl contract.
    function getDAppConfig(UserOperation calldata userOp)
        external
        view
        mustBeCalled
        returns (DAppConfig memory dConfig)
    {
        dConfig = DAppConfig({
            to: address(this),
            callConfig: CALL_CONFIG,
            bidToken: getBidFormat(userOp),
            solverGasLimit: getSolverGasLimit(),
            dappGasLimit: getDAppGasLimit(),
            bundlerSurchargeRate: getBundlerSurchargeRate()
        });
    }

    /// @notice Returns the CallConfig struct of this DAppControl contract.
    /// @return The CallConfig struct of this DAppControl contract.
    function getCallConfig() external view returns (CallConfig memory) {
        return _getCallConfig();
    }

    function _getCallConfig() internal view returns (CallConfig memory) {
        return CALL_CONFIG.decodeCallConfig();
    }

    /// @notice Returns the current governance address of this DAppControl contract.
    /// @return The address of the current governance account of this DAppControl contract.
    function getDAppSignatory() external view mustBeCalled returns (address) {
        return governance;
    }

    function _validateCallConfig(uint32 callConfig) internal view {
        ValidCallsResult result = IAtlasVerification(ATLAS_VERIFICATION).verifyCallConfig(callConfig);

        if (result == ValidCallsResult.InvalidCallConfig) {
            revert AtlasErrors.BothPreOpsAndUserReturnDataCannotBeTracked();
        }
        if (result == ValidCallsResult.BothUserAndDAppNoncesCannotBeSequential) {
            revert AtlasErrors.BothUserAndDAppNoncesCannotBeSequential();
        }
        if (result == ValidCallsResult.InvertBidValueCannotBeExPostBids) {
            revert AtlasErrors.InvertBidValueCannotBeExPostBids();
        }
    }

    /// @notice Starts the transfer of governance to a new address. Only callable by the current governance address.
    /// @param newGovernance The address of the new governance.
    function transferGovernance(address newGovernance) external mustBeCalled {
        if (msg.sender != governance) {
            revert AtlasErrors.OnlyGovernance();
        }
        pendingGovernance = newGovernance;
        emit AtlasEvents.GovernanceTransferStarted(governance, newGovernance);
    }

    /// @notice Accepts the transfer of governance to a new address. Only callable by the new governance address.
    function acceptGovernance() external mustBeCalled {
        address newGovernance = pendingGovernance;
        if (msg.sender != newGovernance) {
            revert AtlasErrors.Unauthorized();
        }

        address prevGovernance = governance;
        governance = newGovernance;
        delete pendingGovernance;

        IAtlasVerification(ATLAS_VERIFICATION).changeDAppGovernance(prevGovernance, newGovernance);

        emit AtlasEvents.GovernanceTransferred(prevGovernance, newGovernance);
    }
}

File 6 of 22 : ConfigTypes.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

struct DAppConfig {
    address to; // Address of the DAppControl contract
    uint32 callConfig; // Configuration
    address bidToken; // address(0) for ETH
    uint32 solverGasLimit; // Max gas limit for solverOp (including preSolver and postSolver) execution
    uint32 dappGasLimit; // Max shared gas limit for preOps and allocateValue hook execution
    uint128 bundlerSurchargeRate; // Bundler surcharge rate
}

struct CallConfig {
    // userNoncesSequential: The userOp nonce must be the next sequential nonce for that user’s address in Atlas’
    // nonce system. If false, the userOp nonces are allowed to be non-sequential (unordered), as long as they are
    // unique.
    bool userNoncesSequential;
    // dappNoncesSequential: The dappOp nonce must be the next sequential nonce for that dApp signer’s address in
    // Atlas’ nonce system. If false, the dappOp nonce is not checked, as the dAppOp is tied to its userOp's nonce via
    // the callChainHash.
    bool dappNoncesSequential;
    // requirePreOps: The preOps hook is executed before the userOp is executed. If false, the preOps hook is skipped.
    // the dapp control should check the validity of the user operation (whether its dapps can support userOp.dapp and
    // userOp.data) in the preOps hook.
    bool requirePreOps;
    // trackPreOpsReturnData: The return data from the preOps hook is passed to the next call phase. If false preOps
    // return data is discarded. If both trackPreOpsReturnData and trackUserReturnData are true, they are concatenated.
    bool trackPreOpsReturnData;
    // trackUserReturnData: The return data from the userOp call is passed to the next call phase. If false userOp
    // return data is discarded. If both trackPreOpsReturnData and trackUserReturnData are true, they are concatenated.
    bool trackUserReturnData;
    // delegateUser: The userOp call is made using delegatecall from the Execution Environment. If false, userOp is
    // called using call.
    bool delegateUser;
    // requirePreSolver: The preSolver hook is executed before the solverOp is executed. If false, the preSolver hook is
    // skipped.
    bool requirePreSolver;
    // requirePostSolver: The postSolver hook is executed after the solverOp is executed. If false, the postSolver hook
    // is skipped.
    bool requirePostSolver;
    // zeroSolvers: Allow the metacall to proceed even if there are no solverOps. The solverOps do not necessarily need
    // to be successful, but at least 1 must exist.
    bool zeroSolvers;
    // reuseUserOp: If true, the metacall will revert if unsuccessful so as not to store nonce data, so the userOp can
    // be reused.
    bool reuseUserOp;
    // userAuctioneer: The user is allowed to be the auctioneer (the signer of the dAppOp). More than one auctioneer
    // option can be set to true for the same DAppControl.
    bool userAuctioneer;
    // solverAuctioneer: The solver is allowed to be the auctioneer (the signer of the dAppOp). If the solver is the
    // auctioneer then their solverOp must be the only one. More than one auctioneer option can be set to true for the
    // same DAppControl.
    bool solverAuctioneer;
    // unknownAuctioneer: Anyone is allowed to be the auctioneer - dAppOp.from must be the signer of the dAppOp, but the
    // usual signatory[] checks are skipped. More than one auctioneer option can be set to true for the same
    // DAppControl.
    bool unknownAuctioneer;
    // verifyCallChainHash: Check that the dAppOp callChainHash matches the actual callChainHash as calculated in
    // AtlasVerification.
    bool verifyCallChainHash;
    // forwardReturnData: The return data from previous steps is included as calldata in the call from the Execution
    // Environment to the solver contract. If false, return data is not passed to the solver contract.
    bool forwardReturnData;
    // requireFulfillment: If true, a winning solver must be found, otherwise the metacall will fail.
    bool requireFulfillment;
    // trustedOpHash: If true, the userOpHash excludes some userOp inputs such as `value`, `gas`, `maxFeePerGas`,
    // `nonce`, `deadline`, and `data`, implying solvers trust changes made to these parts of the userOp after signing
    // their associated solverOps.
    bool trustedOpHash;
    // invertBidValue: If true, the solver with the lowest successful bid wins.
    bool invertBidValue;
    // exPostBids: Bids are found on-chain using `_getBidAmount` in Atlas, and solverOp.bidAmount is used as the max
    // bid. If solverOp.bidAmount is 0, then there is no max bid limit for that solver.
    bool exPostBids;
    // multipleSolvers: If true, the metacall will proceed even if a solver successfully pays their bid, and will be
    // charged in gas as if it was reverted. If false, the auction ends after the first successful solver.
    bool multipleSuccessfulSolvers;
    // checkMetacallGasLimit: If true, the execution gas measured by `gasleft()` at the start of the metacall is
    // verified to be in line with the expected gas limit, based on the userOp, solverOps, and dAppOp.
    bool checkMetacallGasLimit;
}

enum CallConfigIndex {
    UserNoncesSequential,
    DAppNoncesSequential,
    RequirePreOps,
    TrackPreOpsReturnData,
    TrackUserReturnData,
    DelegateUser,
    RequirePreSolver,
    RequirePostSolver,
    ZeroSolvers,
    ReuseUserOp,
    UserAuctioneer,
    SolverAuctioneer,
    UnknownAuctioneer,
    // Default = DAppAuctioneer
    VerifyCallChainHash,
    ForwardReturnData,
    RequireFulfillment,
    TrustedOpHash,
    InvertBidValue,
    ExPostBids,
    MultipleSuccessfulSolvers,
    CheckMetacallGasLimit
}

File 7 of 22 : UserOperation.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

// Default UserOperation typehash
bytes32 constant USER_TYPEHASH_DEFAULT = keccak256(
    "UserOperation(address from,address to,uint256 value,uint256 gas,uint256 maxFeePerGas,uint256 nonce,uint256 deadline,address dapp,address control,uint32 callConfig,uint32 dappGasLimit,uint32 solverGasLimit,uint24 bundlerSurchargeRate,address sessionKey,bytes data)"
);

// Trusted UserOperation typehash
// NOTE: This is explicitly for the 'trustedOpHash' configuration option meant so that solvers can submit
// SolverOperations
// prior to seeing the UserOperation or its hash. In this scenario, the Solvers should trust the signer of the
// UserOperation.
bytes32 constant USER_TYPEHASH_TRUSTED = keccak256(
    "UserOperation(address from,address to,address dapp,address control,uint32 callConfig,uint32 dappGasLimit,uint32 solverGasLimit,uint24 bundlerSurchargeRate,address sessionKey)"
);

// Length of UserOperation in hex chars, assuming empty signature field, excluding the dynamic userOp.data field.
uint256 constant USER_OP_STATIC_LENGTH = 608;

struct UserOperation {
    address from; // User address
    address to; // Atlas address
    uint256 value; // Amount of ETH required for the user operation (used in `value` field of the user call)
    uint256 gas; // Gas limit for the user operation
    uint256 maxFeePerGas; // Max fee per gas for the user operation
    uint256 nonce; // Atlas nonce of the user operation available in the AtlasVerification contract
    uint256 deadline; // block.number deadline for the user operation
    address dapp; // Nested "to" for user's call (used in `to` field of the user call)
    address control; // Address of the DAppControl contract
    uint32 callConfig; // Call configuration expected by user, refer to `src/contracts/types/ConfigTypes.sol`
    uint32 dappGasLimit; // Gas limit set by the DAppControl for preOps and allocateValue hook execution
    uint32 solverGasLimit; // Gas limit set by the DAppControl for solverOp execution
    uint24 bundlerSurchargeRate; // Bundler surcharge rate, set by the DAppControl
    address sessionKey; // Address of the temporary session key which is used to sign the DappOperation
    bytes data; // User operation calldata (used in `data` field of the user call)
    bytes signature; // User operation signature signed by UserOperation.from
}

File 8 of 22 : SolverOperation.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

bytes32 constant SOLVER_TYPEHASH = keccak256(
    "SolverOperation(address from,address to,uint256 value,uint256 gas,uint256 maxFeePerGas,uint256 deadline,address solver,address control,bytes32 userOpHash,address bidToken,uint256 bidAmount,bytes data)"
);

// NOTE: The calldata length of this SolverOperation struct is 608 bytes when the `data` field is excluded. This value
// is stored in the `_SOLVER_OP_STATIC_LENGTH` constant in AtlasConstants.sol and must be kept up-to-date with any
// changes to this struct.
struct SolverOperation {
    address from; // Solver address
    address to; // Atlas address
    uint256 value; // Amount of ETH required for the solver operation (used in `value` field of the solver call)
    uint256 gas; // Gas limit for the solver operation
    uint256 maxFeePerGas; // maxFeePerGas solver is willing to pay.  This goes to validator, not dApp or user
    uint256 deadline; // block.number deadline for the solver operation
    address solver; // Nested "to" address (used in `to` field of the solver call)
    address control; // DAppControl address
    bytes32 userOpHash; // hash of User's Operation, for verification of user's tx (if not matched, solver wont be
        // charged for gas)
    address bidToken; // address(0) for ETH
    uint256 bidAmount; // Amount of bidToken that the solver bids
    bytes data; // Solver op calldata (used in `data` field of the solver call)
    bytes signature; // Solver operation signature signed by SolverOperation.from
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.14;

/**
 * @title Interface of RedStone adapter
 * @author The Redstone Oracles team
 */
interface IRedstoneAdapter {

  /**
   * @notice Updates values of all data feeds supported by the Adapter contract
   * @dev This function requires an attached redstone payload to the transaction calldata.
   * It also requires each data package to have exactly the same timestamp
   * @param dataPackagesTimestamp Timestamp of each signed data package in the redstone payload
   */
  function updateDataFeedsValues(uint256 dataPackagesTimestamp) external;


  /**
   * @notice Returns the latest properly reported value of the data feed
   * @param dataFeedId The identifier of the requested data feed
   * @return value The latest value of the given data feed
   */
  function getValueForDataFeed(bytes32 dataFeedId) external view returns (uint256);

  /**
   * @notice Returns the latest properly reported values for several data feeds
   * @param requestedDataFeedIds The array of identifiers for the requested feeds
   * @return values Values of the requested data feeds in the corresponding order
   */
  function getValuesForDataFeeds(bytes32[] memory requestedDataFeedIds) external view returns (uint256[] memory);

  /**
   * @notice Returns data timestamp from the latest update
   * @dev It's virtual, because its implementation can sometimes be different
   * (e.g. SinglePriceFeedAdapterWithClearing)
   * @return lastDataTimestamp Timestamp of the latest reported data packages
   */
  function getDataTimestampFromLatestUpdate() external view returns (uint256 lastDataTimestamp);

  /**
   * @notice Returns block timestamp of the latest successful update
   * @return blockTimestamp The block timestamp of the latest successful update
   */
  function getBlockTimestampFromLatestUpdate() external view returns (uint256 blockTimestamp);


  /**
   * @notice Returns timestamps of the latest successful update
   * @return dataTimestamp timestamp (usually in milliseconds) from the signed data packages
   * @return blockTimestamp timestamp of the block when the update has happened
   */
  function getTimestampsFromLatestUpdate() external view returns (uint128 dataTimestamp, uint128 blockTimestamp);

  /**
   * @notice Returns identifiers of all data feeds supported by the Adapter contract
   * @return An array of data feed identifiers
   */
  function getDataFeedIds() external view returns (bytes32[] memory);

  /**
   * @notice Returns the unique index of the given data feed
   * @param dataFeedId The data feed identifier
   * @return index The index of the data feed
   */
  function getDataFeedIndex(bytes32 dataFeedId) external view returns (uint256);

  /**
   * @notice Returns minimal required interval (usually in seconds) between subsequent updates
   * @return interval The required interval between updates
   */
  function getMinIntervalBetweenUpdates() external view returns (uint256);

  /**
   * @notice Reverts if the proposed timestamp of data packages it too old or too new
   * comparing to the block.timestamp. It also ensures that the proposed timestamp is newer
   * Then the one from the previous update
   * @param dataPackagesTimestamp The proposed timestamp (usually in milliseconds)
   */
  function validateProposedDataPackagesTimestamp(uint256 dataPackagesTimestamp) external view;

  /**
   * @notice Reverts if the updater is not authorised
   * @dev This function should revert if msg.sender is not allowed to update data feed values
   * @param updater The address of the proposed updater
   */
  function requireAuthorisedUpdater(address updater) external view;
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.14;

interface IMultiFeedAdapter {
  function updateDataFeedsValuesPartial(bytes32[] memory dataFeedsIds) external;

  function getLastUpdateDetails(bytes32 dataFeedId) external view returns (uint256 lastDataTimestamp, uint256 lastBlockTimestamp, uint256 lastValue);

  function getLastUpdateDetailsUnsafe(bytes32 dataFeedId) external view returns (uint256 lastDataTimestamp, uint256 lastBlockTimestamp, uint256 lastValue);

  function getValuesForDataFeeds(bytes32[] memory requestedDataFeedIds) external view returns (uint256[] memory values);

  function getValueForDataFeed(bytes32 dataFeedId) external view returns (uint256 dataFeedValue);

  function getDataTimestampFromLatestUpdate(bytes32 dataFeedId) external view returns (uint256 lastDataTimestamp);

  function getBlockTimestampFromLatestUpdate(bytes32 dataFeedId) external view returns (uint256 blockTimestamp);
}

File 11 of 22 : DAppOperation.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

bytes32 constant DAPP_TYPEHASH = keccak256(
    "DAppOperation(address from,address to,uint256 nonce,uint256 deadline,address control,address bundler,bytes32 userOpHash,bytes32 callChainHash)"
);

// Length of DAppOperation in hex chars, assuming empty signature field
uint256 constant DAPP_OP_LENGTH = 352;

struct DAppOperation {
    address from; // signer of the DAppOperation
    address to; // Atlas address
    uint256 nonce; // Atlas nonce of the DAppOperation available in the AtlasVerification contract
    uint256 deadline; // block.number deadline for the DAppOperation
    address control; // DAppControl address
    address bundler; // Signer of the atlas tx (msg.sender)
    bytes32 userOpHash; // keccak256 of userOp.to, userOp.data
    bytes32 callChainHash; // keccak256 of the solvers' txs
    bytes signature; // DAppOperation signed by DAppOperation.from
}

//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "../types/SolverOperation.sol";
import "../types/UserOperation.sol";
import { AtlasErrors } from "../types/AtlasErrors.sol";

abstract contract DAppControlTemplate {
    uint32 internal constant DEFAULT_SOLVER_GAS_LIMIT = 1_000_000;
    uint32 internal constant DEFAULT_DAPP_GAS_LIMIT = 2_000_000;
    uint24 internal constant DEFAULT_BUNDLER_SURCHARGE_RATE = 1000; // out of 10_000 = 10%

    constructor() { }

    // Virtual functions to be overridden by participating dApp governance
    // (not FastLane) prior to deploying contract. Note that dApp governance
    // will "own" this contract but that it should be immutable.

    /////////////////////////////////////////////////////////
    //                  PRE OPS                            //
    /////////////////////////////////////////////////////////
    //
    // PreOps:
    // Data should be decoded as:
    //
    //     bytes calldata userOpData
    //

    // _preOpsCall
    // Details:
    //  preOps/delegate =
    //      Inputs: User's calldata
    //      Function: Executing the function set by DAppControl
    //      Container: Inside of the FastLane ExecutionEnvironment
    //      Access: With storage access (read + write) only to the ExecutionEnvironment
    //
    // DApp exposure: Trustless
    // User exposure: Trustless
    function _preOpsCall(UserOperation calldata) internal virtual returns (bytes memory) {
        revert AtlasErrors.NotImplemented();
    }

    /////////////////////////////////////////////////////////
    //         CHECK USER OPERATION                        //
    /////////////////////////////////////////////////////////
    //
    // PreOps:
    // Data should be decoded as:
    //
    //     bytes memory userOpData
    //

    // _checkUserOperation
    // Details:
    //  preOps/delegate =
    //      Inputs: User's calldata
    //      Function: Executing the function set by DAppControl
    //      Container: Inside of the FastLane ExecutionEnvironment
    //      Access: With storage access (read + write) only to the ExecutionEnvironment
    //
    // DApp exposure: Trustless
    // User exposure: Trustless
    function _checkUserOperation(UserOperation memory) internal virtual { }

    /////////////////////////////////////////////////////////
    //                MEV ALLOCATION                       //
    /////////////////////////////////////////////////////////
    //
    // _allocateValueCall
    // Details:
    //  allocate/delegate =
    //      Inputs: MEV Profits (ERC20 balances)
    //      Function: Executing the function set by DAppControl / MEVAllocator
    //      Container: Inside of the FastLane ExecutionEnvironment
    //      Access: With storage access (read + write) only to the ExecutionEnvironment
    //
    // DApp exposure: Trustless
    // User exposure: Trustless
    function _allocateValueCall(
        bool solved,
        address bidToken,
        uint256 bidAmount,
        bytes calldata data
    )
        internal
        virtual;

    /////////////////////////////////////////////////////////
    //              INTENT FULFILLMENT                     //
    /////////////////////////////////////////////////////////
    //

    // _preSolverCall
    //
    // Details:
    //  Data should be decoded as:
    //
    //    address solverTo, bytes memory returnData
    //
    //  fulfillment(preOps)/delegatecall =
    //      Inputs: preOps call's returnData, winning solver to address
    //      Function: Executing the function set by DAppControl
    //      Container: Inside of the FastLane ExecutionEnvironment
    //      Access: Storage access (read+write) to the ExecutionEnvironment contract
    //      NOTE: This happens *inside* of the solver's try/catch wrapper
    //      and is designed to give the solver everything they need to fulfill
    //      the user's 'intent.'
    //      NOTE: If using invertsBid mode, the inventory being invert-bidded on should be in the ExecutionEnvironment
    //      before the PreSolver phase - it should be moved in during the PreOps or UserOperation phases.
    //      NOTE: If using invertsBid mode, the dapp should either transfer the inventory to the solver in this
    //      PreSolver phase, or set an allowance so the solver can pull the tokens during their SolverOperation.

    function _preSolverCall(SolverOperation calldata, bytes calldata) internal virtual {
        revert AtlasErrors.NotImplemented();
    }

    // _postSolverCall
    //
    // Details:
    //
    //  Data should be decoded as:
    //
    //    address solverTo, bytes memory returnData
    //

    //  fulfillment(verification)/delegatecall =
    //      Inputs: preOps call's returnData, winning solver to address
    //      Function: Executing the function set by DAppControl
    //      Container: Inside of the FastLane ExecutionEnvironment
    //      Access: Storage access (read+write) to the ExecutionEnvironment contract
    //      NOTE: This happens *inside* of the solver's try/catch wrapper
    //      and is designed to make sure that the solver is fulfilling
    //      the user's 'intent.'

    function _postSolverCall(SolverOperation calldata, bytes calldata) internal virtual {
        revert AtlasErrors.NotImplemented();
    }

    /////////////////////////////////////////////////////////
    //                 GETTERS & HELPERS                   //
    /////////////////////////////////////////////////////////
    //
    // View functions used by the backend to verify bid format
    // and by the factory and DAppVerification to verify the
    // backend.
    function getBidFormat(UserOperation calldata userOp) public view virtual returns (address bidToken);

    function getBidValue(SolverOperation calldata solverOp) public view virtual returns (uint256);

    function getSolverGasLimit() public view virtual returns (uint32) {
        return DEFAULT_SOLVER_GAS_LIMIT;
    }

    function getDAppGasLimit() public view virtual returns (uint32) {
        return DEFAULT_DAPP_GAS_LIMIT;
    }

    function getBundlerSurchargeRate() public view virtual returns (uint24) {
        return DEFAULT_BUNDLER_SURCHARGE_RATE;
    }
}

//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
import { IERC20 } from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";

import { IAtlas } from "../interfaces/IAtlas.sol";

import { ExecutionPhase } from "../types/LockTypes.sol";
import { SAFE_USER_TRANSFER, SAFE_DAPP_TRANSFER } from "../libraries/SafetyBits.sol";
import { AtlasErrors } from "../types/AtlasErrors.sol";
import "../types/SolverOperation.sol";

contract Base {
    address public immutable ATLAS;
    address public immutable SOURCE;

    constructor(address atlas) {
        ATLAS = atlas;
        SOURCE = address(this);
    }

    // These functions only work inside of the ExecutionEnvironment (mimic)
    // via delegatecall, but can be added to DAppControl as funcs that
    // can be used during DAppControl's delegated funcs

    modifier onlyAtlasEnvironment() {
        _onlyAtlasEnvironment();
        _;
    }

    modifier validSolver(SolverOperation calldata solverOp) {
        address solverContract = solverOp.solver;
        if (solverContract == ATLAS || solverContract == _control() || solverContract == address(this)) {
            revert AtlasErrors.InvalidSolver();
        }
        // Verify that the dAppControl contract matches the solver's expectations
        if (solverOp.control != _control()) {
            revert AtlasErrors.AlteredControl();
        }
        _;
    }

    function _onlyAtlasEnvironment() internal view {
        if (address(this) == SOURCE) {
            revert AtlasErrors.MustBeDelegatecalled();
        }
        if (msg.sender != ATLAS) {
            revert AtlasErrors.OnlyAtlas();
        }
    }

    function _forward(bytes memory data) internal pure returns (bytes memory) {
        return bytes.concat(data, _firstSet(), _secondSet());
    }

    function _firstSet() internal pure returns (bytes memory data) {
        data = abi.encodePacked(
            _bundler(),
            _solverSuccessful(),
            _solverIndex(),
            _solverCount(),
            _phase(),
            _solverOutcome(),
            _bidFind(),
            _simulation(),
            _depth() + 1
        );
    }

    function _secondSet() internal pure returns (bytes memory data) {
        data = abi.encodePacked(_user(), _control(), _config());
    }

    /// @notice Extracts and returns the CallConfig of the current DAppControl contract, from calldata.
    /// @return config The CallConfig of the current DAppControl contract, in uint32 form.
    function _config() internal pure returns (uint32 config) {
        assembly {
            config := shr(224, calldataload(sub(calldatasize(), 4)))
        }
    }

    /// @notice Extracts and returns the address of the current DAppControl contract, from calldata.
    /// @return control The address of the current DAppControl contract.
    function _control() internal pure returns (address control) {
        assembly {
            control := shr(96, calldataload(sub(calldatasize(), 24)))
        }
    }

    /// @notice Extracts and returns the address of the user of the current metacall tx, from calldata.
    /// @return user The address of the user of the current metacall tx.
    function _user() internal pure returns (address user) {
        assembly {
            user := shr(96, calldataload(sub(calldatasize(), 44)))
        }
    }

    /// @notice Extracts and returns the call depth within the current metacall tx, from calldata.
    /// @dev The call depth starts at 1 with the first call of each step in the metacall, from Atlas to the Execution
    /// Environment, and is incremented with each call/delegatecall within that step.
    /// @return callDepth The call depth of the current step in the current metacall tx.
    function _depth() internal pure returns (uint8 callDepth) {
        assembly {
            callDepth := shr(248, calldataload(sub(calldatasize(), 45)))
        }
    }

    /// @notice Extracts and returns the boolean indicating whether the current metacall tx is a simulation or not, from
    /// calldata.
    /// @return simulation The boolean indicating whether the current metacall tx is a simulation or not.
    function _simulation() internal pure returns (bool simulation) {
        assembly {
            simulation := shr(248, calldataload(sub(calldatasize(), 46)))
        }
    }

    /// @notice Extracts and returns the boolean indicating whether the current metacall tx uses on-chain bid-finding,
    /// or not, from calldata.
    /// @return bidFind The boolean indicating whether the current metacall tx uses on-chain bid-finding, or not.
    function _bidFind() internal pure returns (bool bidFind) {
        assembly {
            bidFind := shr(248, calldataload(sub(calldatasize(), 47)))
        }
    }

    /// @notice Extracts and returns the solver outcome bitmap in its current status during a metacall tx, from
    /// calldata.
    /// @return solverOutcome The solver outcome bitmap in its current status, in uint24 form.
    function _solverOutcome() internal pure returns (uint24 solverOutcome) {
        assembly {
            solverOutcome := shr(232, calldataload(sub(calldatasize(), 50)))
        }
    }

    /// @notice Extracts and returns the lock state bitmap of the current metacall tx, from calldata.
    /// @return phase The lock state bitmap of the current metacall tx, in uint8 form.
    function _phase() internal pure returns (uint8 phase) {
        assembly {
            phase := shr(248, calldataload(sub(calldatasize(), 51)))
        }
    }

    /// @notice Extracts and returns the number of solverOps in the current metacall tx, from calldata.
    /// @return solverCount The number of solverOps in the current metacall tx.
    function _solverCount() internal pure returns (uint8 solverCount) {
        assembly {
            solverCount := shr(248, calldataload(sub(calldatasize(), 52)))
        }
    }

    /// @notice Extracts and returns the number of executed solverOps in the current metacall tx, from calldata.
    /// @dev Solver index is incremented as Atlas iterates through the solverOps array during execution.
    /// @return solverIndex The count of executed solverOps in the current metacall tx.
    function _solverIndex() internal pure returns (uint8 solverIndex) {
        assembly {
            solverIndex := shr(248, calldataload(sub(calldatasize(), 53)))
        }
    }

    /// @notice Extracts and returns the boolean indicating whether the winning solverOp was executed successfully in
    /// the current metacall tx, from calldata.
    /// @return solverSuccessful The boolean indicating whether the winning solverOp was executed successfully in the
    /// current metacall tx.
    function _solverSuccessful() internal pure returns (bool solverSuccessful) {
        assembly {
            solverSuccessful := shr(248, calldataload(sub(calldatasize(), 54)))
        }
    }

    /// @notice Extracts and returns the current value of the bundler of the current metacall tx, from calldata.
    /// @dev The bundler is either the address of the current DAppControl contract (in preOps and userOp steps),
    /// the current solverOp.solver address (during solverOps steps), or the winning solverOp.from address (during
    /// allocateValue step).
    /// @return bundler The current value of the bundler of the current metacall tx.
    function _bundler() internal pure returns (address bundler) {
        assembly {
            bundler := shr(96, calldataload(sub(calldatasize(), 74)))
        }
    }

    /// @notice Returns the address of the currently active Execution Environment, if any.
    /// @return activeEnvironment The address of the currently active Execution Environment.
    function _activeEnvironment() internal view returns (address activeEnvironment) {
        (activeEnvironment,,) = IAtlas(ATLAS).lock();
    }
}

// ExecutionBase is inherited by DAppControl. It inherits Base to as a common root contract shared between
// ExecutionEnvironment and DAppControl. ExecutionBase then adds utility functions which make it easier for custom
// DAppControls to interact with Atlas.
contract ExecutionBase is Base {
    constructor(address atlas) Base(atlas) { }

    /// @notice Deposits local funds from this Execution Environment, to the transient Atlas balance. These funds go
    /// towards the bundler, with any surplus going to the Solver.
    /// @param amt The amount of funds to deposit.
    function _contributeToAtlas(uint256 amt) internal {
        if (amt > address(this).balance) revert AtlasErrors.InsufficientLocalFunds();

        IAtlas(ATLAS).contribute{ value: amt }();
    }

    /// @notice Borrows funds from the transient Atlas balance that will be repaid by the Solver or this Execution
    /// Environment via `_contributeToAtlas()`
    /// @param amt The amount of funds to borrow.
    function _borrowFromAtlas(uint256 amt) internal {
        IAtlas(ATLAS).borrow(amt);
    }

    /// @notice Transfers ERC20 tokens from the user of the current metacall tx, via Atlas, to a specified destination.
    /// @dev This will only succeed if Atlas is in a phase included in `SAFE_USER_TRANSFER`. See SafetyBits.sol.
    /// @param token The address of the ERC20 token contract.
    /// @param destination The address to which the tokens will be transferred.
    /// @param amount The amount of tokens to transfer.
    function _transferUserERC20(address token, address destination, uint256 amount) internal {
        IAtlas(ATLAS).transferUserERC20(token, destination, amount, _user(), _control());
    }

    /// @notice Transfers ERC20 tokens from the DApp of the current metacall tx, via Atlas, to a specified destination.
    /// @dev This will only succeed if Atlas is in a phase included in `SAFE_DAPP_TRANSFER`. See SafetyBits.sol.
    /// @param token The address of the ERC20 token contract.
    /// @param destination The address to which the tokens will be transferred.
    /// @param amount The amount of tokens to transfer.
    function _transferDAppERC20(address token, address destination, uint256 amount) internal {
        IAtlas(ATLAS).transferDAppERC20(token, destination, amount, _user(), _control());
    }

    /// @notice Returns a bool indicating whether a source address has approved the Atlas contract to transfer a certain
    /// amount of a certain token, and whether Atlas is in the correct phase to transfer the token. Note: this is just
    /// for convenience - transfers via `_transferDAppERC20()` and `_transferUserERC20()` will independently ensure all
    /// necessary checks are made.
    /// @param token The address of the ERC20 token contract.
    /// @param source The address of the source of the tokens.
    /// @param amount The amount of tokens to transfer.
    /// @param phase The phase of the current metacall tx.
    /// @return available A bool indicating whether a transfer from the source, via Atlas, of the specified amount of
    /// the specified token, will succeed.
    function _availableFundsERC20(
        address token,
        address source,
        uint256 amount,
        ExecutionPhase phase
    )
        internal
        view
        returns (bool available)
    {
        uint256 _balance = IERC20(token).balanceOf(source);
        if (_balance < amount) {
            return false;
        }

        uint8 _phase_bitwise = uint8(1 << uint8(phase));
        address _user = _user();
        address _dapp = _control();

        if (source == _user) {
            if (_phase_bitwise & SAFE_USER_TRANSFER == 0) {
                return false;
            }
            if (IERC20(token).allowance(_user, ATLAS) < amount) {
                return false;
            }
            return true;
        }

        if (source == _dapp) {
            if (_phase_bitwise & SAFE_DAPP_TRANSFER == 0) {
                return false;
            }
            if (IERC20(token).allowance(_dapp, ATLAS) < amount) {
                return false;
            }
            return true;
        }

        return false;
    }

    /// @notice Transfers ERC20 tokens from the user of the current metacall tx, via Atlas, to the current
    /// ExecutionEnvironment, and approves the destination address to spend the tokens from the ExecutionEnvironment.
    /// @param token The address of the ERC20 token contract.
    /// @param amount The amount of tokens to transfer and approve.
    /// @param destination The address approved to spend the tokens from the ExecutionEnvironment.
    function _getAndApproveUserERC20(address token, uint256 amount, address destination) internal {
        if (token == address(0) || amount == 0) return;

        // Pull tokens from user to ExecutionEnvironment
        _transferUserERC20(token, address(this), amount);

        // Approve destination to spend the tokens from ExecutionEnvironment
        SafeTransferLib.safeApprove(token, destination, amount);
    }
}

File 14 of 22 : LockTypes.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

struct Context {
    bytes32 userOpHash; // not packed
    address executionEnvironment; // not packed
    uint24 solverOutcome;
    uint8 solverIndex;
    uint8 solverCount;
    uint8 callDepth;
    uint8 phase;
    bool solverSuccessful;
    bool bidFind;
    bool isSimulation;
    address bundler;
    uint32 dappGasLeft; // Gas used on preOps and allocateValue hooks
}

enum ExecutionPhase {
    Uninitialized,
    PreOps,
    UserOperation,
    PreSolver,
    SolverOperation,
    PostSolver,
    AllocateValue,
    FullyLocked
}

//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import { IDAppControl } from "../interfaces/IDAppControl.sol";

import "../types/ConfigTypes.sol";

library CallBits {
    uint32 internal constant _ONE = uint32(1);

    function buildCallConfig(address control) internal view returns (uint32 callConfig) {
        callConfig = IDAppControl(control).CALL_CONFIG();
    }

    function encodeCallConfig(CallConfig memory callConfig) internal pure returns (uint32 encodedCallConfig) {
        if (callConfig.userNoncesSequential) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.UserNoncesSequential);
        }
        if (callConfig.dappNoncesSequential) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.DAppNoncesSequential);
        }
        if (callConfig.requirePreOps) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.RequirePreOps);
        }
        if (callConfig.trackPreOpsReturnData) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.TrackPreOpsReturnData);
        }
        if (callConfig.trackUserReturnData) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.TrackUserReturnData);
        }
        if (callConfig.delegateUser) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.DelegateUser);
        }
        if (callConfig.requirePreSolver) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.RequirePreSolver);
        }
        if (callConfig.requirePostSolver) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.RequirePostSolver);
        }
        if (callConfig.zeroSolvers) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.ZeroSolvers);
        }
        if (callConfig.reuseUserOp) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.ReuseUserOp);
        }
        if (callConfig.userAuctioneer) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.UserAuctioneer);
        }
        if (callConfig.solverAuctioneer) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.SolverAuctioneer);
        }
        if (callConfig.unknownAuctioneer) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.UnknownAuctioneer);
        }
        if (callConfig.verifyCallChainHash) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.VerifyCallChainHash);
        }
        if (callConfig.forwardReturnData) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.ForwardReturnData);
        }
        if (callConfig.requireFulfillment) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.RequireFulfillment);
        }
        if (callConfig.trustedOpHash) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.TrustedOpHash);
        }
        if (callConfig.invertBidValue) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.InvertBidValue);
        }
        if (callConfig.exPostBids) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.ExPostBids);
        }
        if (callConfig.multipleSuccessfulSolvers) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.MultipleSuccessfulSolvers);
        }
        if (callConfig.checkMetacallGasLimit) {
            encodedCallConfig ^= _ONE << uint32(CallConfigIndex.CheckMetacallGasLimit);
        }
    }

    function decodeCallConfig(uint32 encodedCallConfig) internal pure returns (CallConfig memory callConfig) {
        callConfig.userNoncesSequential = needsSequentialUserNonces(encodedCallConfig);
        callConfig.dappNoncesSequential = needsSequentialDAppNonces(encodedCallConfig);
        callConfig.requirePreOps = needsPreOpsCall(encodedCallConfig);
        callConfig.trackPreOpsReturnData = needsPreOpsReturnData(encodedCallConfig);
        callConfig.trackUserReturnData = needsUserReturnData(encodedCallConfig);
        callConfig.delegateUser = needsDelegateUser(encodedCallConfig);
        callConfig.requirePreSolver = needsPreSolverCall(encodedCallConfig);
        callConfig.requirePostSolver = needsPostSolverCall(encodedCallConfig);
        callConfig.zeroSolvers = allowsZeroSolvers(encodedCallConfig);
        callConfig.reuseUserOp = allowsReuseUserOps(encodedCallConfig);
        callConfig.userAuctioneer = allowsUserAuctioneer(encodedCallConfig);
        callConfig.solverAuctioneer = allowsSolverAuctioneer(encodedCallConfig);
        callConfig.unknownAuctioneer = allowsUnknownAuctioneer(encodedCallConfig);
        callConfig.verifyCallChainHash = verifyCallChainHash(encodedCallConfig);
        callConfig.forwardReturnData = forwardReturnData(encodedCallConfig);
        callConfig.requireFulfillment = needsFulfillment(encodedCallConfig);
        callConfig.trustedOpHash = allowsTrustedOpHash(encodedCallConfig);
        callConfig.invertBidValue = invertsBidValue(encodedCallConfig);
        callConfig.exPostBids = exPostBids(encodedCallConfig);
        callConfig.multipleSuccessfulSolvers = multipleSuccessfulSolvers(encodedCallConfig);
        callConfig.checkMetacallGasLimit = checkMetacallGasLimit(encodedCallConfig);
    }

    function needsSequentialUserNonces(uint32 callConfig) internal pure returns (bool sequential) {
        sequential = callConfig & (1 << uint32(CallConfigIndex.UserNoncesSequential)) != 0;
    }

    function needsSequentialDAppNonces(uint32 callConfig) internal pure returns (bool sequential) {
        sequential = callConfig & (1 << uint32(CallConfigIndex.DAppNoncesSequential)) != 0;
    }

    function needsPreOpsCall(uint32 callConfig) internal pure returns (bool needsPreOps) {
        needsPreOps = callConfig & (1 << uint32(CallConfigIndex.RequirePreOps)) != 0;
    }

    function needsPreOpsReturnData(uint32 callConfig) internal pure returns (bool needsReturnData) {
        needsReturnData = callConfig & (1 << uint32(CallConfigIndex.TrackPreOpsReturnData)) != 0;
    }

    function needsUserReturnData(uint32 callConfig) internal pure returns (bool needsReturnData) {
        needsReturnData = callConfig & (1 << uint32(CallConfigIndex.TrackUserReturnData)) != 0;
    }

    function needsDelegateUser(uint32 callConfig) internal pure returns (bool delegateUser) {
        delegateUser = callConfig & (1 << uint32(CallConfigIndex.DelegateUser)) != 0;
    }

    function needsPreSolverCall(uint32 callConfig) internal pure returns (bool needsPreSolver) {
        needsPreSolver = callConfig & (1 << uint32(CallConfigIndex.RequirePreSolver)) != 0;
    }

    function needsPostSolverCall(uint32 callConfig) internal pure returns (bool needsPostSolver) {
        needsPostSolver = callConfig & (1 << uint32(CallConfigIndex.RequirePostSolver)) != 0;
    }

    function allowsZeroSolvers(uint32 callConfig) internal pure returns (bool zeroSolvers) {
        zeroSolvers = callConfig & (1 << uint32(CallConfigIndex.ZeroSolvers)) != 0;
    }

    function allowsReuseUserOps(uint32 callConfig) internal pure returns (bool reuseUserOp) {
        reuseUserOp = callConfig & (1 << uint32(CallConfigIndex.ReuseUserOp)) != 0;
    }

    function allowsUserAuctioneer(uint32 callConfig) internal pure returns (bool userAuctioneer) {
        userAuctioneer = callConfig & (1 << uint32(CallConfigIndex.UserAuctioneer)) != 0;
    }

    function allowsSolverAuctioneer(uint32 callConfig) internal pure returns (bool userAuctioneer) {
        userAuctioneer = callConfig & (1 << uint32(CallConfigIndex.SolverAuctioneer)) != 0;
    }

    function allowsUnknownAuctioneer(uint32 callConfig) internal pure returns (bool unknownAuctioneer) {
        unknownAuctioneer = callConfig & (1 << uint32(CallConfigIndex.UnknownAuctioneer)) != 0;
    }

    function verifyCallChainHash(uint32 callConfig) internal pure returns (bool verify) {
        verify = callConfig & (1 << uint32(CallConfigIndex.VerifyCallChainHash)) != 0;
    }

    function forwardReturnData(uint32 callConfig) internal pure returns (bool) {
        return callConfig & (1 << uint32(CallConfigIndex.ForwardReturnData)) != 0;
    }

    function needsFulfillment(uint32 callConfig) internal pure returns (bool) {
        return callConfig & (1 << uint32(CallConfigIndex.RequireFulfillment)) != 0;
    }

    function allowsTrustedOpHash(uint32 callConfig) internal pure returns (bool) {
        return callConfig & (1 << uint32(CallConfigIndex.TrustedOpHash)) != 0;
    }

    function invertsBidValue(uint32 callConfig) internal pure returns (bool) {
        return callConfig & (1 << uint32(CallConfigIndex.InvertBidValue)) != 0;
    }

    function exPostBids(uint32 callConfig) internal pure returns (bool) {
        return callConfig & (1 << uint32(CallConfigIndex.ExPostBids)) != 0;
    }

    function multipleSuccessfulSolvers(uint32 callConfig) internal pure returns (bool) {
        return (callConfig & (1 << uint32(CallConfigIndex.MultipleSuccessfulSolvers))) != 0;
    }

    function checkMetacallGasLimit(uint32 callConfig) internal pure returns (bool) {
        return (callConfig & (1 << uint32(CallConfigIndex.CheckMetacallGasLimit))) != 0;
    }
}

File 16 of 22 : AtlasErrors.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

// aderyn-fp-next-line(unused-import)
import { ValidCallsResult } from "./ValidCalls.sol";

contract AtlasErrors {
    // Simulator
    error SimulatorBalanceTooLow();
    error Unauthorized();
    error Unreachable();
    error NoAuctionWinner();
    error InvalidEntryFunction();
    error SimulationPassed();

    error UserNotFulfilled();

    error BidFindSuccessful(uint256 bidAmount);

    error InvalidSolver();
    error BidNotPaid();
    error InvertedBidExceedsCeiling();
    error BalanceNotReconciled();
    error SolverOpReverted();
    error AlteredControl();
    error InvalidEntry();
    error CallbackNotCalled();
    error PreSolverFailed();
    error PostSolverFailed();
    error InsufficientEscrow();

    error VerificationSimFail(ValidCallsResult);
    error PreOpsSimFail();
    error UserOpSimFail();
    error SolverSimFail(uint256 solverOutcomeResult); // uint param is result returned in `verifySolverOp`
    error AllocateValueSimFail();
    error ValidCalls(ValidCallsResult);
    error InsufficientGasForMetacallSimulation(uint256 gasLeft, uint256 estimatedMetacallGas, uint256 suggestedSimGas);

    // Execution Environment
    error InvalidTo();
    error PreOpsDelegatecallFail();
    error UserOpValueExceedsBalance();
    error UserWrapperDelegatecallFail();
    error UserWrapperCallFail();
    error AllocateValueDelegatecallFail();
    error NotEnvironmentOwner();
    error ExecutionEnvironmentBalanceTooLow();

    // Atlas
    error PreOpsFail();
    error UserOpFail();
    error AllocateValueFail();
    error InvalidAccess();

    // Escrow
    error InvalidEscrowDuration();
    error DAppGasLimitReached();

    // AtlETH
    error EscrowLockActive();
    error InsufficientBalanceForDeduction(uint256 balance, uint256 requested);

    // DAppIntegration
    error OnlyGovernance();
    error SignatoryActive();
    error InvalidCaller();
    error DAppNotEnabled();
    error AtlasLockActive();

    // Permit69
    error InvalidEnvironment();
    error EnvironmentMismatch();
    error InvalidLockState();

    // GasAccounting
    error InvalidExecutionEnvironment(address correctEnvironment);
    error InsufficientAtlETHBalance(uint256 actual, uint256 needed);
    error BorrowsNotRepaid(uint256 borrows, uint256 repays);
    error AssignDeficitTooLarge(uint256 deficit, uint256 bundlerRefund);

    // SafetyLocks
    error AlreadyInitialized();

    // Storage
    error SurchargeRateTooHigh();

    // DAppControl
    error BothUserAndDAppNoncesCannotBeSequential();
    error BothPreOpsAndUserReturnDataCannotBeTracked();
    error InvalidControl();
    error NoDelegatecall();
    error MustBeDelegatecalled();
    error OnlyAtlas();
    error WrongPhase();
    error InsufficientLocalFunds();
    error NotImplemented();
    error InvertBidValueCannotBeExPostBids();
}

File 17 of 22 : AtlasEvents.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

contract AtlasEvents {
    // Metacall
    event MetacallResult(
        address indexed bundler,
        address indexed user,
        bool solverSuccessful,
        uint256 ethPaidToBundler,
        uint256 netGasSurcharge
    );

    // AtlETH
    event Bond(address indexed owner, uint256 amount);
    event Unbond(address indexed owner, uint256 amount, uint256 earliestAvailable);
    event Redeem(address indexed owner, uint256 amount);
    event Mint(address indexed to, uint256 amount);
    event Burn(address indexed from, uint256 amount);

    // Escrow events
    event SolverTxResult(
        address indexed solverTo,
        address indexed solverFrom,
        address indexed dAppControl,
        address bidToken,
        uint256 bidAmount,
        bool executed,
        bool success,
        uint256 result
    );

    // Factory events
    event ExecutionEnvironmentCreated(address indexed user, address indexed executionEnvironment);

    // Surcharge events
    event SurchargeWithdrawn(address indexed to, uint256 amount);
    event SurchargeRecipientTransferStarted(address indexed currentRecipient, address indexed newRecipient);
    event SurchargeRecipientTransferred(address indexed newRecipient);

    // DAppControl events
    event GovernanceTransferStarted(address indexed previousGovernance, address indexed newGovernance);
    event GovernanceTransferred(address indexed previousGovernance, address indexed newGovernance);

    // DAppIntegration events
    event NewDAppSignatory(
        address indexed control, address indexed governance, address indexed signatory, uint32 callConfig
    );
    event RemovedDAppSignatory(
        address indexed control, address indexed governance, address indexed signatory, uint32 callConfig
    );
    event DAppGovernanceChanged(
        address indexed control, address indexed oldGovernance, address indexed newGovernance, uint32 callConfig
    );
    event DAppDisabled(address indexed control, address indexed governance, uint32 callConfig);
}

File 18 of 22 : ValidCalls.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

/// @title ValidCallsResult
/// @notice Enum for ValidCallsResult
/// @dev A single ValidCallsResult is returned by `validateCalls` in AtlasVerification
enum ValidCallsResult {
    Valid,
    // Results below this line will cause metacall to revert
    UserFromInvalid,
    UserSignatureInvalid,
    DAppSignatureInvalid,
    UserNonceInvalid,
    InvalidDAppNonce,
    UnknownAuctioneerNotAllowed,
    InvalidAuctioneer,
    InvalidBundler,
    // Results above this line will cause metacall to revert
    InvertBidValueCannotBeExPostBids, // Threshold value (included in the revert range), any new reverting values should
        // be included above this line
    // Results below this line will cause metacall to gracefully return
    GasPriceHigherThanMax,
    TxValueLowerThanCallValue,
    TooManySolverOps,
    UserDeadlineReached,
    DAppDeadlineReached,
    ExecutionEnvEmpty,
    NoSolverOp,
    InvalidSequence,
    OpHashMismatch,
    DeadlineMismatch,
    InvalidControl,
    InvalidSolverGasLimit,
    InvalidCallConfig,
    CallConfigMismatch,
    DAppToInvalid,
    UserToInvalid,
    ControlMismatch,
    InvalidCallChainHash,
    DAppNotEnabled,
    BothUserAndDAppNoncesCannotBeSequential,
    MetacallGasLimitTooLow,
    MetacallGasLimitTooHigh,
    DAppGasLimitMismatch,
    SolverGasLimitMismatch,
    BundlerSurchargeRateMismatch,
    ExPostBidsAndMultipleSuccessfulSolversNotSupportedTogether,
    InvertsBidValueAndMultipleSuccessfulSolversNotSupportedTogether,
    NeedSolversForMultipleSuccessfulSolvers,
    SolverCannotBeAuctioneerForMultipleSuccessfulSolvers,
    CannotRequireFulfillmentForMultipleSuccessfulSolvers
}

//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "../types/UserOperation.sol";
import "../types/ConfigTypes.sol";
import "../types/DAppOperation.sol";
import "../types/SolverOperation.sol";
import "../types/ValidCalls.sol";

interface IAtlasVerification {
    // AtlasVerification.sol
    function validateCalls(
        DAppConfig calldata dConfig,
        UserOperation calldata userOp,
        SolverOperation[] calldata solverOps,
        DAppOperation calldata dAppOp,
        uint256 metacallGasLeft,
        uint256 msgValue,
        address msgSender,
        bool isSimulation
    )
        external
        returns (
            uint256 allSolversGasLimit,
            uint256 allSolversCalldataGas,
            uint256 bidFindOverhead,
            ValidCallsResult verifyCallsResult
        );
    function verifySolverOp(
        SolverOperation calldata solverOp,
        bytes32 userOpHash,
        uint256 userMaxFeePerGas,
        address bundler,
        bool allowsTrustedOpHash
    )
        external
        view
        returns (uint256 result);
    function verifyCallConfig(uint32 callConfig) external view returns (ValidCallsResult);
    function getUserOperationHash(UserOperation calldata userOp) external view returns (bytes32 hash);
    function getUserOperationPayload(UserOperation calldata userOp) external view returns (bytes32 payload);
    function getSolverPayload(SolverOperation calldata solverOp) external view returns (bytes32 payload);
    function getDAppOperationPayload(DAppOperation calldata dAppOp) external view returns (bytes32 payload);
    function getDomainSeparator() external view returns (bytes32 domainSeparator);

    // NonceManager.sol
    function getUserNextNonce(address user, bool sequential) external view returns (uint256 nextNonce);
    function getUserNextNonSeqNonceAfter(address user, uint256 refNonce) external view returns (uint256);
    function getDAppNextNonce(address dApp) external view returns (uint256 nextNonce);
    function userSequentialNonceTrackers(address account) external view returns (uint256 lastUsedSeqNonce);
    function dAppSequentialNonceTrackers(address account) external view returns (uint256 lastUsedSeqNonce);
    function userNonSequentialNonceTrackers(
        address account,
        uint248 wordIndex
    )
        external
        view
        returns (uint256 bitmap);

    // DAppIntegration.sol
    function initializeGovernance(address control) external;
    function addSignatory(address control, address signatory) external;
    function removeSignatory(address control, address signatory) external;
    function changeDAppGovernance(address oldGovernance, address newGovernance) external;
    function disableDApp(address control) external;
    function getGovFromControl(address control) external view returns (address);
    function isDAppSignatory(address control, address signatory) external view returns (bool);
    function signatories(bytes32 key) external view returns (bool);
    function dAppSignatories(address control) external view returns (address[] memory);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "../types/LockTypes.sol";

// NOTE: No user transfers allowed during AllocateValue
uint8 constant SAFE_USER_TRANSFER = uint8(
    1 << (uint8(ExecutionPhase.PreOps)) | 1 << (uint8(ExecutionPhase.UserOperation))
        | 1 << (uint8(ExecutionPhase.PreSolver)) | 1 << (uint8(ExecutionPhase.PostSolver))
);

// NOTE: No Dapp transfers allowed during UserOperation
uint8 constant SAFE_DAPP_TRANSFER = uint8(
    1 << (uint8(ExecutionPhase.PreOps)) | 1 << (uint8(ExecutionPhase.PreSolver))
        | 1 << (uint8(ExecutionPhase.PostSolver)) | 1 << (uint8(ExecutionPhase.AllocateValue))
);

library SafetyBits {
    function setAndPack(Context memory self, ExecutionPhase phase) internal pure returns (bytes memory packedCtx) {
        self.phase = uint8(phase);
        packedCtx = abi.encodePacked(
            self.bundler,
            self.solverSuccessful,
            self.solverIndex,
            self.solverCount,
            uint8(phase),
            self.solverOutcome,
            self.bidFind,
            self.isSimulation,
            uint8(1) // callDepth
        );
    }
}

//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "../types/UserOperation.sol";
import "../types/SolverOperation.sol";
import "../types/ConfigTypes.sol";

interface IDAppControl {
    function preOpsCall(UserOperation calldata userOp) external payable returns (bytes memory);

    function preSolverCall(SolverOperation calldata solverOp, bytes calldata returnData) external payable;

    function postSolverCall(SolverOperation calldata solverOp, bytes calldata returnData) external payable;

    function allocateValueCall(bool solved, address bidToken, uint256 bidAmount, bytes calldata data) external;

    function getDAppConfig(UserOperation calldata userOp) external view returns (DAppConfig memory dConfig);

    function getCallConfig() external view returns (CallConfig memory callConfig);

    function CALL_CONFIG() external view returns (uint32);

    function getSolverGasLimit() external view returns (uint32);

    function getDAppGasLimit() external view returns (uint32);

    function getBundlerSurchargeRate() external view returns (uint24);

    function getBidFormat(UserOperation calldata userOp) external view returns (address bidToken);

    function getBidValue(SolverOperation calldata solverOp) external view returns (uint256);

    function getDAppSignatory() external view returns (address governanceAddress);

    function requireSequentialUserNonces() external view returns (bool isSequential);

    function requireSequentialDAppNonces() external view returns (bool isSequential);

    function userDelegated() external view returns (bool delegated);

    function transferGovernance(address newGovernance) external;

    function acceptGovernance() external;
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/",
    "@atlas/=lib/atlas/src/contracts/",
    "@atlas-test/=lib/atlas/test/",
    "@atlas-scripts/=lib/atlas/script/",
    "@redstone-finance/evm-connector/contracts/=lib/redstone-oracles-monorepo/packages/evm-connector/contracts/",
    "@chainlink/contracts/src/v0.8/=lib/chainlink/contracts/src/v0.8/shared/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
    "atlas/=lib/atlas/",
    "chainlink/=lib/chainlink/",
    "ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "eth-gas-reporter/=lib/atlas/node_modules/eth-gas-reporter/",
    "hardhat/=lib/atlas/node_modules/hardhat/",
    "nitro-contracts/=lib/atlas/lib/nitro-contracts/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/",
    "redstone-oracles-monorepo/=lib/redstone-oracles-monorepo/",
    "solady/=lib/atlas/lib/solady/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 50
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": true
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"atlas","type":"address"},{"internalType":"uint256","name":"oevShareFastlane_","type":"uint256"},{"internalType":"address","name":"oevAllocationDestinationFastlane_","type":"address"},{"internalType":"address","name":"oevAllocationDestinationProtocol_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlteredControl","type":"error"},{"inputs":[],"name":"BothPreOpsAndUserReturnDataCannotBeTracked","type":"error"},{"inputs":[],"name":"BothUserAndDAppNoncesCannotBeSequential","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidControl","type":"error"},{"inputs":[],"name":"InvalidExecutionEnv","type":"error"},{"inputs":[],"name":"InvalidOevAllocationDestination","type":"error"},{"inputs":[],"name":"InvalidOevShare","type":"error"},{"inputs":[],"name":"InvalidSelector","type":"error"},{"inputs":[],"name":"InvalidSolver","type":"error"},{"inputs":[],"name":"InvalidUserEntryCall","type":"error"},{"inputs":[],"name":"InvalidUserOpDapp","type":"error"},{"inputs":[],"name":"InvalidUserOpFrom","type":"error"},{"inputs":[],"name":"InvertBidValueCannotBeExPostBids","type":"error"},{"inputs":[],"name":"MustBeDelegatecalled","type":"error"},{"inputs":[],"name":"NoDelegatecall","type":"error"},{"inputs":[],"name":"NotImplemented","type":"error"},{"inputs":[],"name":"OnlyAtlas","type":"error"},{"inputs":[],"name":"OnlyGovernance","type":"error"},{"inputs":[],"name":"OnlyGovernance","type":"error"},{"inputs":[],"name":"OnlyWhitelistedOracleAllowed","type":"error"},{"inputs":[],"name":"OracleUpdateFailed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"WrongPhase","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernance","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernance","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalOev","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oevFastlane","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oevProtocol","type":"uint256"}],"name":"OevAllocated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"destinationFastlane","type":"address"},{"indexed":true,"internalType":"address","name":"destinationProtocol","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountFastlane","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountProtocol","type":"uint256"}],"name":"OevWithdrawn","type":"event"},{"inputs":[],"name":"ATLAS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ATLAS_VERIFICATION","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CALL_CONFIG","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONTROL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OEV_SHARE_SCALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SOURCE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"accumulatedOevFastlane","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accumulatedOevProtocol","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"addAllowedSelector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oracle","type":"address"}],"name":"addOracleToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"solved","type":"bool"},{"internalType":"address","name":"bidToken","type":"address"},{"internalType":"uint256","name":"bidAmount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"allocateValueCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"allowedSelectors","outputs":[{"internalType":"bool","name":"isAllowed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowedSelectorsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authorizedExecutionEnv","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authorizedUserOpSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creditOEV","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"dapp","type":"address"},{"internalType":"address","name":"control","type":"address"},{"internalType":"uint32","name":"callConfig","type":"uint32"},{"internalType":"uint32","name":"dappGasLimit","type":"uint32"},{"internalType":"uint32","name":"solverGasLimit","type":"uint32"},{"internalType":"uint24","name":"bundlerSurchargeRate","type":"uint24"},{"internalType":"address","name":"sessionKey","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"","type":"tuple"}],"name":"getBidFormat","outputs":[{"internalType":"address","name":"bidToken","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"solver","type":"address"},{"internalType":"address","name":"control","type":"address"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"address","name":"bidToken","type":"address"},{"internalType":"uint256","name":"bidAmount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct SolverOperation","name":"solverOp","type":"tuple"}],"name":"getBidValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getBundlerSurchargeRate","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCallConfig","outputs":[{"components":[{"internalType":"bool","name":"userNoncesSequential","type":"bool"},{"internalType":"bool","name":"dappNoncesSequential","type":"bool"},{"internalType":"bool","name":"requirePreOps","type":"bool"},{"internalType":"bool","name":"trackPreOpsReturnData","type":"bool"},{"internalType":"bool","name":"trackUserReturnData","type":"bool"},{"internalType":"bool","name":"delegateUser","type":"bool"},{"internalType":"bool","name":"requirePreSolver","type":"bool"},{"internalType":"bool","name":"requirePostSolver","type":"bool"},{"internalType":"bool","name":"zeroSolvers","type":"bool"},{"internalType":"bool","name":"reuseUserOp","type":"bool"},{"internalType":"bool","name":"userAuctioneer","type":"bool"},{"internalType":"bool","name":"solverAuctioneer","type":"bool"},{"internalType":"bool","name":"unknownAuctioneer","type":"bool"},{"internalType":"bool","name":"verifyCallChainHash","type":"bool"},{"internalType":"bool","name":"forwardReturnData","type":"bool"},{"internalType":"bool","name":"requireFulfillment","type":"bool"},{"internalType":"bool","name":"trustedOpHash","type":"bool"},{"internalType":"bool","name":"invertBidValue","type":"bool"},{"internalType":"bool","name":"exPostBids","type":"bool"},{"internalType":"bool","name":"multipleSuccessfulSolvers","type":"bool"},{"internalType":"bool","name":"checkMetacallGasLimit","type":"bool"}],"internalType":"struct CallConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"dapp","type":"address"},{"internalType":"address","name":"control","type":"address"},{"internalType":"uint32","name":"callConfig","type":"uint32"},{"internalType":"uint32","name":"dappGasLimit","type":"uint32"},{"internalType":"uint32","name":"solverGasLimit","type":"uint32"},{"internalType":"uint24","name":"bundlerSurchargeRate","type":"uint24"},{"internalType":"address","name":"sessionKey","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"}],"name":"getDAppConfig","outputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint32","name":"callConfig","type":"uint32"},{"internalType":"address","name":"bidToken","type":"address"},{"internalType":"uint32","name":"solverGasLimit","type":"uint32"},{"internalType":"uint32","name":"dappGasLimit","type":"uint32"},{"internalType":"uint128","name":"bundlerSurchargeRate","type":"uint128"}],"internalType":"struct DAppConfig","name":"dConfig","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDAppGasLimit","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDAppSignatory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSharesAndDestinations","outputs":[{"internalType":"uint256","name":"oevShareFastlane_","type":"uint256"},{"internalType":"address","name":"oevAllocationDestinationFastlane_","type":"address"},{"internalType":"address","name":"oevAllocationDestinationProtocol_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSolverGasLimit","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oevAllocationDestinationFastlane","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oevAllocationDestinationProtocol","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oevShareFastlane","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oracle","type":"address"}],"name":"oracleWhitelist","outputs":[{"internalType":"bool","name":"isWhitelisted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"solver","type":"address"},{"internalType":"address","name":"control","type":"address"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"address","name":"bidToken","type":"address"},{"internalType":"uint256","name":"bidAmount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct SolverOperation","name":"solverOp","type":"tuple"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"postSolverCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"dapp","type":"address"},{"internalType":"address","name":"control","type":"address"},{"internalType":"uint32","name":"callConfig","type":"uint32"},{"internalType":"uint32","name":"dappGasLimit","type":"uint32"},{"internalType":"uint32","name":"solverGasLimit","type":"uint32"},{"internalType":"uint24","name":"bundlerSurchargeRate","type":"uint24"},{"internalType":"address","name":"sessionKey","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"}],"name":"preOpsCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"solver","type":"address"},{"internalType":"address","name":"control","type":"address"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"address","name":"bidToken","type":"address"},{"internalType":"uint256","name":"bidAmount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct SolverOperation","name":"solverOp","type":"tuple"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"preSolverCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"removeAllowedSelector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oracle","type":"address"}],"name":"removeOracleFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requireSequentialDAppNonces","outputs":[{"internalType":"bool","name":"isSequential","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requireSequentialUserNonces","outputs":[{"internalType":"bool","name":"isSequential","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"authorizedUserOpSigner_","type":"address"}],"name":"setAuthorizedUserOpSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"bundlerSurchargeRate_","type":"uint24"}],"name":"setBundlerSurchargeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"dappGasLimit_","type":"uint32"}],"name":"setDAppGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oevAllocationDestinationFastlane_","type":"address"}],"name":"setOevAllocationDestinationFastlane","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oevAllocationDestinationProtocol_","type":"address"}],"name":"setOevAllocationDestinationProtocol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"oevShareFastlane_","type":"uint256"}],"name":"setOevShareFastlane","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"solverGasLimit_","type":"uint32"}],"name":"setSolverGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newGovernance","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oracle","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"userDelegated","outputs":[{"internalType":"bool","name":"delegated","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"verifyAllowedSelector","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oracle","type":"address"}],"name":"verifyOracleWhitelist","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userOpSigner","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"verifyUserOpSignerAndOracleAndSelector","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistedOraclesCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawOEV","outputs":[],"stateMutability":"nonpayable","type":"function"}]

61012080604052346105c057608081612ebd80380380916100208285610713565b8339810103126105c05761003381610736565b602082015191610051606061004a60408401610736565b9201610736565b6040519092906102a081016001600160401b038111828210176106ff576004926020916040525f83525f82840152600160408401525f60608401525f60808401525f60a08401525f60c08401525f60e0840152600161010084015260016101208401525f6101408401525f6101608401525f61018084015260016101a08401525f6101c08401525f6101e08401525f6102008401525f6102208401525f6102408401525f6102608401525f610280840152806080523060a05260405193848092630f235ce960e31b825260018060a01b03165afa9182156105cc575f926106b8575b5063ffffffff602460209284610100525f9080516106af575b848101516106a5575b604081015161069b575b6060810151610691575b6080810151610687575b60a081015161067e575b60c0810151610674575b60e081015161066a575b61010081015161065f575b610120810151610654575b610140810151610649575b61016081015161063e575b610180810151610633575b6101a0810151610628575b6101c081015161061d575b6101e0810151610612575b610200810151610606575b6102208101516105fa575b6102408101516105ee575b6102608101516105e1575b61028001516105d7575b60c081905260405163548ef41d60e11b815292166004830152909283919082906001600160a01b03165afa9081156105cc575f9161058d575b506028811015610579576016811461056a57601d811461055b5760091461054c573060e0525f80546001600160a01b0319163317905560018054600160a01b600160f81b031916653d090000b71b60a71b1790556006805463ffffffff60a01b191690556008805463ffffffff19169055612710831161053d576001600160a01b031690811561052e576001600160a01b031691821561052e576201000081101561052157600280546001600160f01b031660f09290921b6001600160f01b031916919091178155600380546001600160a01b03199081169390931790556004805490921692909217905560096020527f64c02997cc8b67c8ed717dd7bd7cbfeaf899397da0623af4080a4b54bab20073805460ff19908116600190811790925563b7a1625160e01b5f527f8f9a51381b0d773fd660decf530ef8894bcb7dd01e335c463d080f7c486d36e5805490911690911790556008805463ffffffff19169091179055604051612772908161074b82396080518181816103d5015281816104b9015281816107210152818161193201528181611c4e01528181611f0001526125a2015260a0518181816102b10152612573015260c05181818161059f015281816106440152818161127c015281816113c30152818161142101528181611449015281816114740152818161149f015281816114ca015281816114f6015281816115210152818161154c01528181611578015281816115a5015281816115d2015281816115ff0152818161162c0152818161165901528181611686015281816116b3015281816116e10152818161170f0152818161173d0152818161176b015281816117990152611fa7015260e05181818161031401528181610556015281816106cb01528181610c21015281816118ed01528181611b0201528181611c0901528181611d1501528181611eb601526125f8015261010051818181610d340152611d800152f35b6335278d125f526004601cfd5b632da4d62560e21b5f5260045ffd5b63150708ef60e21b5f5260045ffd5b6371e1eba160e11b5f5260045ffd5b630af36e8d60e41b5f5260045ffd5b632b9ecaaf60e01b5f5260045ffd5b634e487b7160e01b5f52602160045260245ffd5b90506020813d6020116105c4575b816105a860209383610713565b810103126105c0575160288110156105c0575f610258565b5f80fd5b3d915061059b565b6040513d5f823e3d90fd5b621000001861021f565b6208000090911890610215565b9062040000189061020a565b906202000018906101ff565b906201000018906101f4565b9061800018906101e9565b9061400018906101de565b9061200018906101d3565b9061100018906101c8565b9061080018906101bd565b9061040018906101b2565b9061020018906101a7565b90610100189061019c565b9060801890610191565b9060401890610187565b9084189061017d565b9060101890610173565b9060081890610169565b906004189061015f565b9060021890610155565b6001915061014c565b9091506020813d6020116106f7575b816106d460209383610713565b810103126105c05763ffffffff60246106ee602093610736565b93925050610133565b3d91506106c7565b634e487b7160e01b5f52604160045260245ffd5b601f909101601f19168101906001600160401b038211908210176106ff57604052565b51906001600160a01b03821682036105c05756fe6080806040526004361015610012575f80fd5b5f905f3560e01c90816302a688ed14612021575080630a8acefb14611ff9578063140f34a114611fd15780631e15116714611f925780631e61c25014611e65578063228ed68a14611e40578063238efcbc14611d02578063283ee1cf14611bf25780632c30e21a14611b7b57806331a6df9214611b4e57806332322bda14611b315780634953ecc714611aec5780635aa6e67514611ac55780636036ba5314611a845780636d25fc9a14611a425780636d4d6b2e146118d65780636e1ccfc4146113ed57806372d91684146113ab5780637470bb1d1461135a57806377cc05d4146112dd57806385f168eb146112a05780638d2129781461125f5780638ed3bec4146110ef5780638ed54772146110d45780638ff91c5b1461109b57806399218be51461107457806399f7c90214610ff75780639df86b2514610f60578063a14a719114610eec578063a465ff1214610ead578063ab07101814610e2a578063b2213bd214610e01578063b76ea2c314610db0578063b7750d7a14610d87578063bf18633114610d63578063bf230cfb14610d1e578063cf41777814610cc8578063d38bfff414610c05578063d3ff697a14610be0578063d45611f914610bb9578063d736a95e14610b59578063db934b1414610b3c578063de25244e14610b15578063dfb90761146106bf578063e2c04d0f1461066e578063e2c0c30f1461062c578063e514a79d14610511578063e91d443e146104e8578063e982ae92146104a3578063ed51475a14610367578063ee41848814610301578063ef079ff3146102e0578063f230b4c21461029b5763f39c38a014610270575f80fd5b346102985780600319360112610298576001546040516001600160a01b039091168152602090f35b80fd5b50346102985780600319360112610298576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610298578060031936011261029857602060025460f01c604051908152f35b50346102985780600319360112610298577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316300361035857546040516001600160a01b039091168152602090f35b63acbcffa760e01b8152600490fd5b5034610298576020366003190112610298576103816120d5565b81546001600160a01b0316330361049457600580546001600160a01b0319166001600160a01b038316179055604051632288948360e11b815290606090829081906103d1903090600484016122c7565b03817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610489578291610431575b50600680546001600160a01b0319166001600160a01b039290921691909117905580f35b90506060813d606011610481575b8161044c60609383612233565b8101031261047d57604061045f8261226f565b9161046c60208201612283565b5001518015150361047d575f61040d565b5080fd5b3d915061043f565b6040513d84823e3d90fd5b6354348f0360e01b8252600482fd5b50346102985780600319360112610298576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346102985780600319360112610298576003546040516001600160a01b039091168152602090f35b503461029857610520366121ac565b508060a060405161053081612204565b828152826020820152826040820152826060820152826080820152015260018060a01b037f00000000000000000000000000000000000000000000000000000000000000001630036103585760c09060015463ffffffff60405161059381612204565b308152816020820194817f0000000000000000000000000000000000000000000000000000000000000000168652604083019081526060830190828660a01c16825262ffffff60a0608086019585898c1c168752019660e01c16865282604051973089525116602088015260018060a01b039051166040870152511660608501525116608083015260018060801b0390511660a0820152f35b503461029857806003193601126102985750602060017f0000000000000000000000000000000000000000000000000000000000000000161515604051908152f35b5034610298576020366003190112610298576106886121e0565b81546001600160a01b03163303610494576001805463ffffffff60a01b191660a09290921b63ffffffff60a01b1691909117905580f35b506106c9366121ac565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316919036601719013560601c8303610b065761070c612570565b604051637c1e845d60e11b81526060816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610afb5760019160ff918591610ac9575b501603610aba576102008136031261047d576040519261020084018481106001600160401b03821117610aa65760405261079882612101565b84526107a660208301612101565b602085015260408201356040850152606082013560608501526080820135608085015260a082013560a085015260c082013560c085015260e082016107ea81612101565b60e08601526107fc6101008401612101565b61010086015261080f61012084016121f3565b61012086015261082261014084016121f3565b61014086015261083561016084016121f3565b61016086015261018083013562ffffff81168103610a3c576101808601526108606101a08401612101565b6101a08601526101c083019485356001600160401b038111610a6457610889903690860161252a565b6101c08201526101e08401356001600160401b038111610a6457906101e06108b68594933690880161252a565b9101526001600160a01b03906108cb906122e1565b1603610a97576108db8483612733565b6001600160e01b031991359182169160048210610a77575b50506001600160e01b03191663fd59771360e01b01610a6857610917839483612733565b80600411610a3c5781019060408183036003190112610a3c5760048101356001600160a01b0381169290839003610a64576024820135906001600160401b038211610a6057600461096d9261097394010161252a565b936122e1565b91602084519401519363ffffffff60e01b85169460048210610a40575b5050803b15610a3c5760405163a14a719160e01b81526001600160a01b03909316600484015260248301919091526001600160e01b03199092166044820152908290829060649082905afa801561048957610a27575b5050604080516109f7602082612233565b8281526020825193849282845280519283918282870152018585015e828201840152601f01601f19168101030190f35b81610a3191612233565b61029857805f6109e6565b8480fd5b6001600160e01b031960049290920360031b82901b161693505f80610990565b8680fd5b8580fd5b631b7c276360e11b8352600483fd5b6001600160e01b031960049290920360031b82901b161690505f806108f3565b6377b7067560e11b8352600483fd5b634e487b7160e01b84526041600452602484fd5b6338961af360e21b8252600482fd5b610aeb915060603d606011610af4575b610ae38183612233565b810190612294565b9150505f61075f565b503d610ad9565b6040513d85823e3d90fd5b6329d0bf2f60e21b8252600482fd5b5034610298578060031936011261029857602063ffffffff60015460c01c16604051908152f35b503461029857806003193601126102985760206040516127108152f35b503461029857602036600319011261029857610b736120d5565b81546001600160a01b03163303610494576001600160a01b03168015610baa57600380546001600160a01b03191691909117905580f35b632da4d62560e21b8252600482fd5b5034610298578060031936011261029857602063ffffffff60065460a01c16604051908152f35b503461029857602036600319011261029857610c02610bfd6120d5565b6126e6565b80f35b503461029857602036600319011261029857610c1f6120d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163003610cb95781546001600160a01b03169033829003610caa57600180546001600160a01b0319166001600160a01b03929092169182179055907f1c4bb4e3cab7b72da7eb9f0ae62554dda85dc7fb907c946ad2776095b95ac1ad8380a380f35b6354348f0360e01b8352600483fd5b63acbcffa760e01b8252600482fd5b50346102985760203660031901126102985760043562ffffff8116810361047d5781546001600160a01b03163303610494576001805462ffffff60e01b191660e09290921b62ffffff60e01b1691909117905580f35b50346102985780600319360112610298576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610298578060031936011261029857602063ffffffff60085416604051908152f35b50346102985780600319360112610298576002546040516001600160781b039091168152602090f35b503461029857602036600319011261029857610dca6121e0565b81546001600160a01b03163303610494576001805463ffffffff60c01b191660c09290921b63ffffffff60c01b1691909117905580f35b50346102985780600319360112610298576006546040516001600160a01b039091168152602090f35b503461029857602036600319011261029857610e44612195565b81546001600160a01b03163303610494576001600160e01b0319168082526009602052604082205460ff16610e77575080f35b8152600960205260408120805460ff1916905560085463ffffffff610e9d818316612518565b169063ffffffff19161760085580f35b50346102985760203660031901126102985760209060ff906040906001600160a01b03610ed86120d5565b168152600784522054166040519015158152f35b503461029857606036600319011261029857610f066120d5565b610f0e6120eb565b604435916001600160e01b031983168303610f5c576005546001600160a01b03908116911603610f4a5790610f45610c02926126e6565b61265a565b60016251280360e11b03198352600483fd5b8380fd5b503461029857602036600319011261029857610f7a6120d5565b81546001600160a01b03163303610494576001600160a01b03168082526007602052604082205460ff1615610fad575080f35b8152600760205260408120805460ff1916600117905560065463ffffffff60a01b610fe160a083901c63ffffffff166122f5565b60a01b169063ffffffff60a01b19161760065580f35b5034610298576020366003190112610298576110116120d5565b81546001600160a01b03163303610494576001600160a01b03168082526007602052604082205460ff16611043575080f35b8152600760205260408120805460ff1916905560065463ffffffff60a01b610fe160a083901c63ffffffff16612518565b5034610298578060031936011261029857602063ffffffff60015460a01c16604051908152f35b503461029857806003193601126102985780546001600160a01b031633036110c557610c02612424565b6354348f0360e01b8152600490fd5b5034610298576020906110e6366121ac565b50604051908152f35b5080600319360112610298576006546001600160a01b03163303611250576111156123c8565b604081019061ffff82511680340290348204143415171561123c5761271090049182340391348311611228579161121361ffff7fcec9ea470581c081f0c0c932e4d215072682660693822f01e1078485bb56ee70959360609560018060781b03611191611181886126a5565b83516001600160781b031661240b565b16815261119d856126a5565b6020820180519092916111b8916001600160781b031661240b565b6001600160781b0380821690935290516002805494516001600160f01b0360f088811b90971616929094169190911760789290921b600160781b600160f01b0316919091179190931690911b6001600160f01b031916179055565b6040519134835260208301526040820152a180f35b634e487b7160e01b85526011600452602485fd5b634e487b7160e01b84526011600452602484fd5b63b243097360e01b8152600490fd5b5034610298578060031936011261029857602060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346102985760203660031901126102985760ff604060209263ffffffff60e01b6112c9612195565b168152600984522054166040519015158152f35b5034610298576020366003190112610298578054600435906001600160a01b0316330361049457612710811161134b576201000081101561133e57600280546001600160f01b031660f09290921b6001600160f01b03191691909117905580f35b6335278d1282526004601cfd5b63150708ef60e21b8252600482fd5b5034610298576020366003190112610298576113746120d5565b81546001600160a01b03163303610494576001600160a01b03168015610baa57600480546001600160a01b03191691909117905580f35b503461029857806003193601126102985750602060027f0000000000000000000000000000000000000000000000000000000000000000161515604051908152f35b50346102985780600319360112610298576102a09061140a612320565b50611413612320565b5061141c612320565b9060017f0000000000000000000000000000000000000000000000000000000000000000161515825260027f0000000000000000000000000000000000000000000000000000000000000000161515602083015260047f0000000000000000000000000000000000000000000000000000000000000000161515604083015260087f0000000000000000000000000000000000000000000000000000000000000000161515606083015260107f000000000000000000000000000000000000000000000000000000000000000016151560808301525060207f000000000000000000000000000000000000000000000000000000000000000016151560a082015260407f000000000000000000000000000000000000000000000000000000000000000016151560c082015260807f000000000000000000000000000000000000000000000000000000000000000016151560e08201526101007f00000000000000000000000000000000000000000000000000000000000000001615156101008201526102007f00000000000000000000000000000000000000000000000000000000000000001615156101208201526104007f00000000000000000000000000000000000000000000000000000000000000001615156101408201526108007f00000000000000000000000000000000000000000000000000000000000000001615156101608201526110007f00000000000000000000000000000000000000000000000000000000000000001615156101808201526120007f00000000000000000000000000000000000000000000000000000000000000001615156101a08201526140007f00000000000000000000000000000000000000000000000000000000000000001615156101c08201526180007f00000000000000000000000000000000000000000000000000000000000000001615156101e0820152620100007f0000000000000000000000000000000000000000000000000000000000000000161515610200820152620200007f0000000000000000000000000000000000000000000000000000000000000000161515610220820152620400007f0000000000000000000000000000000000000000000000000000000000000000161515610240820152620800007f0000000000000000000000000000000000000000000000000000000000000000161515610260820152621000007f00000000000000000000000000000000000000000000000000000000000000001615156102808201526102806040519180511515835260208101511515602084015260408101511515604084015260608101511515606084015260808101511515608084015260a0810151151560a084015260c0810151151560c084015260e0810151151560e0840152610100810151151561010084015261012081015115156101208401526101408101511515610140840152610160810151151561016084015261018081015115156101808401526101a081015115156101a08401526101c081015115156101c08401526101e081015115156101e0840152610200810151151561020084015261022081015115156102208401526102408101511515610240840152610260810151151561026084015201511515610280820152f35b506118e036612142565b505036601719013560601c7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316819003611a335761192860c083016122e1565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116939116808414908115611a29575b8115611a1f575b50611a10576001600160a01b03906119829060e0016122e1565b1603611a01576060600491611995612570565b604051637c1e845d60e11b815292839182905afa9081156104895760ff8392600592600495916119df575b5016036119d35763d623472560e01b8152fd5b6338961af360e21b8152fd5b6119f8915060603d606011610af457610ae38183612233565b9150505f6119c0565b632cf9711760e11b8252600482fd5b63af24067760e01b8452600484fd5b905030145f611968565b8381149150611961565b6329d0bf2f60e21b8352600483fd5b5034610298576020366003190112610298576004356001600160401b03811161047d576101a0600319823603011261047d576020906101446040519101358152f35b50346102985780600319360112610298576002546003546004546040805160f09490941c84526001600160a01b039283166020850152911690820152606090f35b5034610298578060031936011261029857546040516001600160a01b039091168152602090f35b50346102985780600319360112610298576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461029857602036600319011261029857610c02610f45612195565b503461029857806003193601126102985760025460405160789190911c6001600160781b03168152602090f35b503461029857602036600319011261029857611b95612195565b81546001600160a01b03163303610494576001600160e01b0319168082526009602052604082205460ff1615611bc9575080f35b8152600960205260408120805460ff1916600117905560085463ffffffff610e9d8183166122f5565b50611bfc36612142565b505036601719013560601c7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316819003611a3357611c4460c083016122e1565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116939116808414908115611cf8575b8115611cee575b50611a10576001600160a01b0390611c9e9060e0016122e1565b1603611a01576060600491611cb1612570565b604051637c1e845d60e11b815292839182905afa9081156104895760ff8392600392600495916119df575016036119d35763d623472560e01b8152fd5b905030145f611c84565b8381149150611c7d565b5034611e1f575f366003190112611e1f577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163003611e31576001546001600160a01b0381169033829003611e23575f80546001600160a01b0319808216851790925591166001556001600160a01b03908116907f000000000000000000000000000000000000000000000000000000000000000016803b15611e1f575f60405180926309b20a3f60e11b8252818381611dc88989600484016122c7565b03925af18015611e1457611dff575b507f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce808380a380f35b611e0c9193505f90612233565b5f915f611dd7565b6040513d5f823e3d90fd5b5f80fd5b6282b42960e81b5f5260045ffd5b63acbcffa760e01b5f5260045ffd5b34611e1f575f366003190112611e1f57602062ffffff60015460e01c16604051908152f35b34611e1f576080366003190112611e1f5760043580151503611e1f57611e896120eb565b506064356001600160401b038111611e1f57611ea9903690600401612115565b505036601719013560601c7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031603611f8357611eeb612570565b604051637c1e845d60e11b81526060816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611e145760069160ff915f91611f61575b501603611f5257611f506044356125f0565b005b6338961af360e21b5f5260045ffd5b611f7a915060603d606011610af457610ae38183612233565b91505083611f3e565b6329d0bf2f60e21b5f5260045ffd5b34611e1f575f366003190112611e1f576020807f0000000000000000000000000000000000000000000000000000000000000000161515604051908152f35b34611e1f575f366003190112611e1f576005546040516001600160a01b039091168152602090f35b34611e1f575f366003190112611e1f576004546040516001600160a01b039091168152602090f35b34611e1f576040366003190112611e1f5761203a6120d5565b906024356001600160401b038111611e1f5761205a903690600401612115565b60065490939192906001600160a01b031633036120c6575f8185829683968337810182815203925af13d156120c1573d61209381612254565b906120a16040519283612233565b81525f60203d92013e5b156120b257005b635516a7db60e11b5f5260045ffd5b6120ab565b63b243097360e01b5f5260045ffd5b600435906001600160a01b0382168203611e1f57565b602435906001600160a01b0382168203611e1f57565b35906001600160a01b0382168203611e1f57565b9181601f84011215611e1f578235916001600160401b038311611e1f5760208381860195010111611e1f57565b906040600319830112611e1f576004356001600160401b038111611e1f576101a08184036003190112611e1f5760040191602435906001600160401b038211611e1f5761219191600401612115565b9091565b600435906001600160e01b031982168203611e1f57565b6020600319820112611e1f57600435906001600160401b038211611e1f57610200908290036003190112611e1f5760040190565b6004359063ffffffff82168203611e1f57565b359063ffffffff82168203611e1f57565b60c081019081106001600160401b0382111761221f57604052565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b0382111761221f57604052565b6001600160401b03811161221f57601f01601f191660200190565b51906001600160a01b0382168203611e1f57565b519063ffffffff82168203611e1f57565b90816060910312611e1f576122a88161226f565b9160406122b760208401612283565b92015160ff81168103611e1f5790565b6001600160a01b0391821681529116602082015260400190565b356001600160a01b0381168103611e1f5790565b63ffffffff1663ffffffff811461230c5760010190565b634e487b7160e01b5f52601160045260245ffd5b604051906102a082018281106001600160401b0382111761221f576040525f610280838281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e0820152826102008201528261022082015282610240820152826102608201520152565b60405190606082018281106001600160401b0382111761221f5760409081526002546001600160781b038082168552607882901c16602085015260f01c90830152565b6001600160781b03918216908216019190821161230c57565b61242c6123c8565b80516020820180516001600160781b039081169392169183830180841161230c578015612511574710612502575f8082529091526040015160f01b6001600160f01b031916600255806124e6575b816124ca575b6003546004546040805193845260208401949094526001600160a01b03908116939116917f44de810e3933b974846d126fd6ff43301b1f1cb07041215fc5ae58bae08661e49190a3565b6004546124e19083906001600160a01b03166126ca565b612480565b6003546124fd9082906001600160a01b03166126ca565b61247a565b631e9acf1760e31b5f5260045ffd5b5050505050565b63ffffffff16801561230c575f190190565b81601f82011215611e1f5780359061254182612254565b9261254f6040519485612233565b82845260208383010111611e1f57815f926020809301838601378301015290565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146125e1577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036125d257565b630ff3d34d60e41b5f5260045ffd5b63188e60cd60e11b5f5260045ffd5b8015612657577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316803b15611e1f575f906004604051809481936323b4efb160e21b83525af18015611e145761264b5750565b5f61265591612233565b565b50565b63ffffffff6008541615159081612682575b5061267357565b631cd4b64760e21b5f5260045ffd5b6001600160e01b0319165f9081526009602052604081205460ff1615915061266c565b600160781b8110156126bd576001600160781b031690565b6335278d125f526004601cfd5b5f80809338935af1156126d957565b63b12d13eb5f526004601cfd5b63ffffffff60065460a01c1615159081612711575b5061270257565b63651c592360e11b5f5260045ffd5b6001600160a01b03165f9081526007602052604081205460ff161591506126fb565b903590601e1981360301821215611e1f57018035906001600160401b038211611e1f57602001918136038313611e1f5756fea164736f6c634300081c000a000000000000000000000000d72d821da82964c0546a5501347a3959808e072f00000000000000000000000000000000000000000000000000000000000003e800000000000000000000000078c5d8df575098a97a3bd1f8dcceb22d71f3a47400000000000000000000000078c5d8df575098a97a3bd1f8dcceb22d71f3a474

Deployed Bytecode

0x6080806040526004361015610012575f80fd5b5f905f3560e01c90816302a688ed14612021575080630a8acefb14611ff9578063140f34a114611fd15780631e15116714611f925780631e61c25014611e65578063228ed68a14611e40578063238efcbc14611d02578063283ee1cf14611bf25780632c30e21a14611b7b57806331a6df9214611b4e57806332322bda14611b315780634953ecc714611aec5780635aa6e67514611ac55780636036ba5314611a845780636d25fc9a14611a425780636d4d6b2e146118d65780636e1ccfc4146113ed57806372d91684146113ab5780637470bb1d1461135a57806377cc05d4146112dd57806385f168eb146112a05780638d2129781461125f5780638ed3bec4146110ef5780638ed54772146110d45780638ff91c5b1461109b57806399218be51461107457806399f7c90214610ff75780639df86b2514610f60578063a14a719114610eec578063a465ff1214610ead578063ab07101814610e2a578063b2213bd214610e01578063b76ea2c314610db0578063b7750d7a14610d87578063bf18633114610d63578063bf230cfb14610d1e578063cf41777814610cc8578063d38bfff414610c05578063d3ff697a14610be0578063d45611f914610bb9578063d736a95e14610b59578063db934b1414610b3c578063de25244e14610b15578063dfb90761146106bf578063e2c04d0f1461066e578063e2c0c30f1461062c578063e514a79d14610511578063e91d443e146104e8578063e982ae92146104a3578063ed51475a14610367578063ee41848814610301578063ef079ff3146102e0578063f230b4c21461029b5763f39c38a014610270575f80fd5b346102985780600319360112610298576001546040516001600160a01b039091168152602090f35b80fd5b50346102985780600319360112610298576040517f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b03168152602090f35b5034610298578060031936011261029857602060025460f01c604051908152f35b50346102985780600319360112610298577f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b0316300361035857546040516001600160a01b039091168152602090f35b63acbcffa760e01b8152600490fd5b5034610298576020366003190112610298576103816120d5565b81546001600160a01b0316330361049457600580546001600160a01b0319166001600160a01b038316179055604051632288948360e11b815290606090829081906103d1903090600484016122c7565b03817f000000000000000000000000d72d821da82964c0546a5501347a3959808e072f6001600160a01b03165afa908115610489578291610431575b50600680546001600160a01b0319166001600160a01b039290921691909117905580f35b90506060813d606011610481575b8161044c60609383612233565b8101031261047d57604061045f8261226f565b9161046c60208201612283565b5001518015150361047d575f61040d565b5080fd5b3d915061043f565b6040513d84823e3d90fd5b6354348f0360e01b8252600482fd5b50346102985780600319360112610298576040517f000000000000000000000000d72d821da82964c0546a5501347a3959808e072f6001600160a01b03168152602090f35b50346102985780600319360112610298576003546040516001600160a01b039091168152602090f35b503461029857610520366121ac565b508060a060405161053081612204565b828152826020820152826040820152826060820152826080820152015260018060a01b037f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac1630036103585760c09060015463ffffffff60405161059381612204565b308152816020820194817f0000000000000000000000000000000000000000000000000000000000002304168652604083019081526060830190828660a01c16825262ffffff60a0608086019585898c1c168752019660e01c16865282604051973089525116602088015260018060a01b039051166040870152511660608501525116608083015260018060801b0390511660a0820152f35b503461029857806003193601126102985750602060017f0000000000000000000000000000000000000000000000000000000000002304161515604051908152f35b5034610298576020366003190112610298576106886121e0565b81546001600160a01b03163303610494576001805463ffffffff60a01b191660a09290921b63ffffffff60a01b1691909117905580f35b506106c9366121ac565b7f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b0316919036601719013560601c8303610b065761070c612570565b604051637c1e845d60e11b81526060816004817f000000000000000000000000d72d821da82964c0546a5501347a3959808e072f6001600160a01b03165afa908115610afb5760019160ff918591610ac9575b501603610aba576102008136031261047d576040519261020084018481106001600160401b03821117610aa65760405261079882612101565b84526107a660208301612101565b602085015260408201356040850152606082013560608501526080820135608085015260a082013560a085015260c082013560c085015260e082016107ea81612101565b60e08601526107fc6101008401612101565b61010086015261080f61012084016121f3565b61012086015261082261014084016121f3565b61014086015261083561016084016121f3565b61016086015261018083013562ffffff81168103610a3c576101808601526108606101a08401612101565b6101a08601526101c083019485356001600160401b038111610a6457610889903690860161252a565b6101c08201526101e08401356001600160401b038111610a6457906101e06108b68594933690880161252a565b9101526001600160a01b03906108cb906122e1565b1603610a97576108db8483612733565b6001600160e01b031991359182169160048210610a77575b50506001600160e01b03191663fd59771360e01b01610a6857610917839483612733565b80600411610a3c5781019060408183036003190112610a3c5760048101356001600160a01b0381169290839003610a64576024820135906001600160401b038211610a6057600461096d9261097394010161252a565b936122e1565b91602084519401519363ffffffff60e01b85169460048210610a40575b5050803b15610a3c5760405163a14a719160e01b81526001600160a01b03909316600484015260248301919091526001600160e01b03199092166044820152908290829060649082905afa801561048957610a27575b5050604080516109f7602082612233565b8281526020825193849282845280519283918282870152018585015e828201840152601f01601f19168101030190f35b81610a3191612233565b61029857805f6109e6565b8480fd5b6001600160e01b031960049290920360031b82901b161693505f80610990565b8680fd5b8580fd5b631b7c276360e11b8352600483fd5b6001600160e01b031960049290920360031b82901b161690505f806108f3565b6377b7067560e11b8352600483fd5b634e487b7160e01b84526041600452602484fd5b6338961af360e21b8252600482fd5b610aeb915060603d606011610af4575b610ae38183612233565b810190612294565b9150505f61075f565b503d610ad9565b6040513d85823e3d90fd5b6329d0bf2f60e21b8252600482fd5b5034610298578060031936011261029857602063ffffffff60015460c01c16604051908152f35b503461029857806003193601126102985760206040516127108152f35b503461029857602036600319011261029857610b736120d5565b81546001600160a01b03163303610494576001600160a01b03168015610baa57600380546001600160a01b03191691909117905580f35b632da4d62560e21b8252600482fd5b5034610298578060031936011261029857602063ffffffff60065460a01c16604051908152f35b503461029857602036600319011261029857610c02610bfd6120d5565b6126e6565b80f35b503461029857602036600319011261029857610c1f6120d5565b7f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b03163003610cb95781546001600160a01b03169033829003610caa57600180546001600160a01b0319166001600160a01b03929092169182179055907f1c4bb4e3cab7b72da7eb9f0ae62554dda85dc7fb907c946ad2776095b95ac1ad8380a380f35b6354348f0360e01b8352600483fd5b63acbcffa760e01b8252600482fd5b50346102985760203660031901126102985760043562ffffff8116810361047d5781546001600160a01b03163303610494576001805462ffffff60e01b191660e09290921b62ffffff60e01b1691909117905580f35b50346102985780600319360112610298576040517f000000000000000000000000ae631acdc436b9dfd75c5629f825330d914594456001600160a01b03168152602090f35b5034610298578060031936011261029857602063ffffffff60085416604051908152f35b50346102985780600319360112610298576002546040516001600160781b039091168152602090f35b503461029857602036600319011261029857610dca6121e0565b81546001600160a01b03163303610494576001805463ffffffff60c01b191660c09290921b63ffffffff60c01b1691909117905580f35b50346102985780600319360112610298576006546040516001600160a01b039091168152602090f35b503461029857602036600319011261029857610e44612195565b81546001600160a01b03163303610494576001600160e01b0319168082526009602052604082205460ff16610e77575080f35b8152600960205260408120805460ff1916905560085463ffffffff610e9d818316612518565b169063ffffffff19161760085580f35b50346102985760203660031901126102985760209060ff906040906001600160a01b03610ed86120d5565b168152600784522054166040519015158152f35b503461029857606036600319011261029857610f066120d5565b610f0e6120eb565b604435916001600160e01b031983168303610f5c576005546001600160a01b03908116911603610f4a5790610f45610c02926126e6565b61265a565b60016251280360e11b03198352600483fd5b8380fd5b503461029857602036600319011261029857610f7a6120d5565b81546001600160a01b03163303610494576001600160a01b03168082526007602052604082205460ff1615610fad575080f35b8152600760205260408120805460ff1916600117905560065463ffffffff60a01b610fe160a083901c63ffffffff166122f5565b60a01b169063ffffffff60a01b19161760065580f35b5034610298576020366003190112610298576110116120d5565b81546001600160a01b03163303610494576001600160a01b03168082526007602052604082205460ff16611043575080f35b8152600760205260408120805460ff1916905560065463ffffffff60a01b610fe160a083901c63ffffffff16612518565b5034610298578060031936011261029857602063ffffffff60015460a01c16604051908152f35b503461029857806003193601126102985780546001600160a01b031633036110c557610c02612424565b6354348f0360e01b8152600490fd5b5034610298576020906110e6366121ac565b50604051908152f35b5080600319360112610298576006546001600160a01b03163303611250576111156123c8565b604081019061ffff82511680340290348204143415171561123c5761271090049182340391348311611228579161121361ffff7fcec9ea470581c081f0c0c932e4d215072682660693822f01e1078485bb56ee70959360609560018060781b03611191611181886126a5565b83516001600160781b031661240b565b16815261119d856126a5565b6020820180519092916111b8916001600160781b031661240b565b6001600160781b0380821690935290516002805494516001600160f01b0360f088811b90971616929094169190911760789290921b600160781b600160f01b0316919091179190931690911b6001600160f01b031916179055565b6040519134835260208301526040820152a180f35b634e487b7160e01b85526011600452602485fd5b634e487b7160e01b84526011600452602484fd5b63b243097360e01b8152600490fd5b5034610298578060031936011261029857602060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000002304168152f35b50346102985760203660031901126102985760ff604060209263ffffffff60e01b6112c9612195565b168152600984522054166040519015158152f35b5034610298576020366003190112610298578054600435906001600160a01b0316330361049457612710811161134b576201000081101561133e57600280546001600160f01b031660f09290921b6001600160f01b03191691909117905580f35b6335278d1282526004601cfd5b63150708ef60e21b8252600482fd5b5034610298576020366003190112610298576113746120d5565b81546001600160a01b03163303610494576001600160a01b03168015610baa57600480546001600160a01b03191691909117905580f35b503461029857806003193601126102985750602060027f0000000000000000000000000000000000000000000000000000000000002304161515604051908152f35b50346102985780600319360112610298576102a09061140a612320565b50611413612320565b5061141c612320565b9060017f0000000000000000000000000000000000000000000000000000000000002304161515825260027f0000000000000000000000000000000000000000000000000000000000002304161515602083015260047f0000000000000000000000000000000000000000000000000000000000002304161515604083015260087f0000000000000000000000000000000000000000000000000000000000002304161515606083015260107f000000000000000000000000000000000000000000000000000000000000230416151560808301525060207f000000000000000000000000000000000000000000000000000000000000230416151560a082015260407f000000000000000000000000000000000000000000000000000000000000230416151560c082015260807f000000000000000000000000000000000000000000000000000000000000230416151560e08201526101007f00000000000000000000000000000000000000000000000000000000000023041615156101008201526102007f00000000000000000000000000000000000000000000000000000000000023041615156101208201526104007f00000000000000000000000000000000000000000000000000000000000023041615156101408201526108007f00000000000000000000000000000000000000000000000000000000000023041615156101608201526110007f00000000000000000000000000000000000000000000000000000000000023041615156101808201526120007f00000000000000000000000000000000000000000000000000000000000023041615156101a08201526140007f00000000000000000000000000000000000000000000000000000000000023041615156101c08201526180007f00000000000000000000000000000000000000000000000000000000000023041615156101e0820152620100007f0000000000000000000000000000000000000000000000000000000000002304161515610200820152620200007f0000000000000000000000000000000000000000000000000000000000002304161515610220820152620400007f0000000000000000000000000000000000000000000000000000000000002304161515610240820152620800007f0000000000000000000000000000000000000000000000000000000000002304161515610260820152621000007f00000000000000000000000000000000000000000000000000000000000023041615156102808201526102806040519180511515835260208101511515602084015260408101511515604084015260608101511515606084015260808101511515608084015260a0810151151560a084015260c0810151151560c084015260e0810151151560e0840152610100810151151561010084015261012081015115156101208401526101408101511515610140840152610160810151151561016084015261018081015115156101808401526101a081015115156101a08401526101c081015115156101c08401526101e081015115156101e0840152610200810151151561020084015261022081015115156102208401526102408101511515610240840152610260810151151561026084015201511515610280820152f35b506118e036612142565b505036601719013560601c7f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b0316819003611a335761192860c083016122e1565b6001600160a01b037f000000000000000000000000d72d821da82964c0546a5501347a3959808e072f8116939116808414908115611a29575b8115611a1f575b50611a10576001600160a01b03906119829060e0016122e1565b1603611a01576060600491611995612570565b604051637c1e845d60e11b815292839182905afa9081156104895760ff8392600592600495916119df575b5016036119d35763d623472560e01b8152fd5b6338961af360e21b8152fd5b6119f8915060603d606011610af457610ae38183612233565b9150505f6119c0565b632cf9711760e11b8252600482fd5b63af24067760e01b8452600484fd5b905030145f611968565b8381149150611961565b6329d0bf2f60e21b8352600483fd5b5034610298576020366003190112610298576004356001600160401b03811161047d576101a0600319823603011261047d576020906101446040519101358152f35b50346102985780600319360112610298576002546003546004546040805160f09490941c84526001600160a01b039283166020850152911690820152606090f35b5034610298578060031936011261029857546040516001600160a01b039091168152602090f35b50346102985780600319360112610298576040517f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b03168152602090f35b503461029857602036600319011261029857610c02610f45612195565b503461029857806003193601126102985760025460405160789190911c6001600160781b03168152602090f35b503461029857602036600319011261029857611b95612195565b81546001600160a01b03163303610494576001600160e01b0319168082526009602052604082205460ff1615611bc9575080f35b8152600960205260408120805460ff1916600117905560085463ffffffff610e9d8183166122f5565b50611bfc36612142565b505036601719013560601c7f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b0316819003611a3357611c4460c083016122e1565b6001600160a01b037f000000000000000000000000d72d821da82964c0546a5501347a3959808e072f8116939116808414908115611cf8575b8115611cee575b50611a10576001600160a01b0390611c9e9060e0016122e1565b1603611a01576060600491611cb1612570565b604051637c1e845d60e11b815292839182905afa9081156104895760ff8392600392600495916119df575016036119d35763d623472560e01b8152fd5b905030145f611c84565b8381149150611c7d565b5034611e1f575f366003190112611e1f577f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b03163003611e31576001546001600160a01b0381169033829003611e23575f80546001600160a01b0319808216851790925591166001556001600160a01b03908116907f000000000000000000000000ae631acdc436b9dfd75c5629f825330d9145944516803b15611e1f575f60405180926309b20a3f60e11b8252818381611dc88989600484016122c7565b03925af18015611e1457611dff575b507f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce808380a380f35b611e0c9193505f90612233565b5f915f611dd7565b6040513d5f823e3d90fd5b5f80fd5b6282b42960e81b5f5260045ffd5b63acbcffa760e01b5f5260045ffd5b34611e1f575f366003190112611e1f57602062ffffff60015460e01c16604051908152f35b34611e1f576080366003190112611e1f5760043580151503611e1f57611e896120eb565b506064356001600160401b038111611e1f57611ea9903690600401612115565b505036601719013560601c7f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b031603611f8357611eeb612570565b604051637c1e845d60e11b81526060816004817f000000000000000000000000d72d821da82964c0546a5501347a3959808e072f6001600160a01b03165afa908115611e145760069160ff915f91611f61575b501603611f5257611f506044356125f0565b005b6338961af360e21b5f5260045ffd5b611f7a915060603d606011610af457610ae38183612233565b91505083611f3e565b6329d0bf2f60e21b5f5260045ffd5b34611e1f575f366003190112611e1f576020807f0000000000000000000000000000000000000000000000000000000000002304161515604051908152f35b34611e1f575f366003190112611e1f576005546040516001600160a01b039091168152602090f35b34611e1f575f366003190112611e1f576004546040516001600160a01b039091168152602090f35b34611e1f576040366003190112611e1f5761203a6120d5565b906024356001600160401b038111611e1f5761205a903690600401612115565b60065490939192906001600160a01b031633036120c6575f8185829683968337810182815203925af13d156120c1573d61209381612254565b906120a16040519283612233565b81525f60203d92013e5b156120b257005b635516a7db60e11b5f5260045ffd5b6120ab565b63b243097360e01b5f5260045ffd5b600435906001600160a01b0382168203611e1f57565b602435906001600160a01b0382168203611e1f57565b35906001600160a01b0382168203611e1f57565b9181601f84011215611e1f578235916001600160401b038311611e1f5760208381860195010111611e1f57565b906040600319830112611e1f576004356001600160401b038111611e1f576101a08184036003190112611e1f5760040191602435906001600160401b038211611e1f5761219191600401612115565b9091565b600435906001600160e01b031982168203611e1f57565b6020600319820112611e1f57600435906001600160401b038211611e1f57610200908290036003190112611e1f5760040190565b6004359063ffffffff82168203611e1f57565b359063ffffffff82168203611e1f57565b60c081019081106001600160401b0382111761221f57604052565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b0382111761221f57604052565b6001600160401b03811161221f57601f01601f191660200190565b51906001600160a01b0382168203611e1f57565b519063ffffffff82168203611e1f57565b90816060910312611e1f576122a88161226f565b9160406122b760208401612283565b92015160ff81168103611e1f5790565b6001600160a01b0391821681529116602082015260400190565b356001600160a01b0381168103611e1f5790565b63ffffffff1663ffffffff811461230c5760010190565b634e487b7160e01b5f52601160045260245ffd5b604051906102a082018281106001600160401b0382111761221f576040525f610280838281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e0820152826102008201528261022082015282610240820152826102608201520152565b60405190606082018281106001600160401b0382111761221f5760409081526002546001600160781b038082168552607882901c16602085015260f01c90830152565b6001600160781b03918216908216019190821161230c57565b61242c6123c8565b80516020820180516001600160781b039081169392169183830180841161230c578015612511574710612502575f8082529091526040015160f01b6001600160f01b031916600255806124e6575b816124ca575b6003546004546040805193845260208401949094526001600160a01b03908116939116917f44de810e3933b974846d126fd6ff43301b1f1cb07041215fc5ae58bae08661e49190a3565b6004546124e19083906001600160a01b03166126ca565b612480565b6003546124fd9082906001600160a01b03166126ca565b61247a565b631e9acf1760e31b5f5260045ffd5b5050505050565b63ffffffff16801561230c575f190190565b81601f82011215611e1f5780359061254182612254565b9261254f6040519485612233565b82845260208383010111611e1f57815f926020809301838601378301015290565b307f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b0316146125e1577f000000000000000000000000d72d821da82964c0546a5501347a3959808e072f6001600160a01b031633036125d257565b630ff3d34d60e41b5f5260045ffd5b63188e60cd60e11b5f5260045ffd5b8015612657577f00000000000000000000000096b7f47ffaaf7560a067dc14210d89001ca0b6ac6001600160a01b0316803b15611e1f575f906004604051809481936323b4efb160e21b83525af18015611e145761264b5750565b5f61265591612233565b565b50565b63ffffffff6008541615159081612682575b5061267357565b631cd4b64760e21b5f5260045ffd5b6001600160e01b0319165f9081526009602052604081205460ff1615915061266c565b600160781b8110156126bd576001600160781b031690565b6335278d125f526004601cfd5b5f80809338935af1156126d957565b63b12d13eb5f526004601cfd5b63ffffffff60065460a01c1615159081612711575b5061270257565b63651c592360e11b5f5260045ffd5b6001600160a01b03165f9081526007602052604081205460ff161591506126fb565b903590601e1981360301821215611e1f57018035906001600160401b038211611e1f57602001918136038313611e1f5756fea164736f6c634300081c000a

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

000000000000000000000000d72d821da82964c0546a5501347a3959808e072f00000000000000000000000000000000000000000000000000000000000003e800000000000000000000000078c5d8df575098a97a3bd1f8dcceb22d71f3a47400000000000000000000000078c5d8df575098a97a3bd1f8dcceb22d71f3a474

-----Decoded View---------------
Arg [0] : atlas (address): 0xD72D821dA82964c0546a5501347a3959808E072f
Arg [1] : oevShareFastlane_ (uint256): 1000
Arg [2] : oevAllocationDestinationFastlane_ (address): 0x78C5d8DF575098a97A3bD1f8DCCEb22D71F3a474
Arg [3] : oevAllocationDestinationProtocol_ (address): 0x78C5d8DF575098a97A3bD1f8DCCEb22D71F3a474

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000d72d821da82964c0546a5501347a3959808e072f
Arg [1] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [2] : 00000000000000000000000078c5d8df575098a97a3bd1f8dcceb22d71f3a474
Arg [3] : 00000000000000000000000078c5d8df575098a97a3bd1f8dcceb22d71f3a474


Deployed Bytecode Sourcemap

1043:15079:21:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;;;;;;559:31:2;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;14247:12;1043:15079;;;;;;;;;;;;;;;;;;;;;;2381:7:4;-1:-1:-1;;;;;1043:15079:21;2372:4:4;2364:24;2360:65;;1043:15079:21;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;2360:65:4;-1:-1:-1;;;2397:28:4;;1043:15079:21;;2397:28:4;1043:15079:21;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;7609:48;1043:15079;;-1:-1:-1;;;;;;1043:15079:21;-1:-1:-1;;;;;1043:15079:21;;;;;;;-1:-1:-1;;;15161:75:21;;1043:15079;15161:75;;1043:15079;;;;15161:75;;15230:4;;1043:15079;15161:75;;;:::i;:::-;;1043:15079;15168:5;-1:-1:-1;;;;;1043:15079:21;15161:75;;;;;;;;;;;1043:15079;-1:-1:-1;15132:104:21;1043:15079;;-1:-1:-1;;;;;;1043:15079:21;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;15161:75;;;;;;;;;;;;;;;;;:::i;:::-;;;1043:15079;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;15161:75;;;1043:15079;;;;15161:75;;;-1:-1:-1;15161:75:21;;;1043:15079;;;;;;;;;4718:53;-1:-1:-1;;;4755:16:21;;1043:15079;4755:16;;1043:15079;;;;;;;;;;;;;;;523:30:2;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;;;;2080:47;1043:15079;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2381:7:4;1043:15079:21;2372:4:4;2364:24;2360:65;;1043:15079:21;;13389:14;1043:15079;;;;;;;:::i;:::-;2372:4:4;1043:15079:21;;5845:289:4;1043:15079:21;5845:289:4;;5913:11;;;1043:15079:21;;;;5845:289:4;;1043:15079:21;;;;5845:289:4;;1043:15079:21;;;;;;;;;;;5845:289:4;;1043:15079:21;;;;;;;;5845:289:4;1043:15079:21;;;;;;;;;2372:4:4;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5262:11:4;1043:15079:21;;5262:11:4;5260:64:8;:69;;1043:15079:21;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;6905:32;1043:15079;;-1:-1:-1;;;;1043:15079:21;;;;;;-1:-1:-1;;;1043:15079:21;;;;;;;;;;;;;;:::i;:::-;1898:7:4;-1:-1:-1;;;;;1043:15079:21;;;;-1:-1:-1;;2978:90:2;;1043:15079:21;2978:90:2;1898:21:4;;1894:62;;896:83:2;;:::i;:::-;1043:15079:21;;-1:-1:-1;;;2209:20:4;;1043:15079:21;;;;2216:5:4;-1:-1:-1;;;;;1043:15079:21;2209:20:4;;;;;;;2806:21;1043:15079:21;;;;2209:20:4;;;1043:15079:21;;;2243:26:4;2239:63;;1043:15079:21;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;1043:15079:21;10811:11;;;:::i;:::-;1043:15079;10811:22;10807:54;;10939:11;;;;:::i;:::-;-1:-1:-1;;;;;;1043:15079:21;;;;;;;;;;;;-1:-1:-1;;;;;;;;1043:15079:21;-1:-1:-1;;;10932:69:21;10928:129;;11128:11;;;;;:::i;:::-;1043:15079;;;;;11117:45;;;1043:15079;;;;-1:-1:-1;;1043:15079:21;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;11426:11;1043:15079;;;;:::i;:::-;11426:11;;:::i;:::-;11448:23;1043:15079;;;;;;;;;;;;;;;;;;;11342:139;;;;;;;1043:15079;;-1:-1:-1;;;11342:139:21;;-1:-1:-1;;;;;1043:15079:21;;;;11342:139;;1043:15079;;;;;;;;-1:-1:-1;;;;;;1043:15079:21;;;;;;;;;;;;11342:139;;1043:15079;;11342:139;;;;;;;;1043:15079;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;;11342:139;;;;;:::i;:::-;1043:15079;;11342:139;;;;;1043:15079;;;;-1:-1:-1;;;;;;1043:15079:21;;;;;;;;;;;;;-1:-1:-1;1043:15079:21;;;;;;;;;;;;10928:129;-1:-1:-1;;;11024:22:21;;1043:15079;11024:22;;1043:15079;-1:-1:-1;;;;;;1043:15079:21;;;;;;;;;;;;;-1:-1:-1;1043:15079:21;;;;10807:54;-1:-1:-1;;;10842:19:21;;1043:15079;10842:19;;1043:15079;-1:-1:-1;;;1043:15079:21;;;;;;;;2239:63:4;-1:-1:-1;;;2278:24:4;;1043:15079:21;2278:24:4;;2209:20;;;;1043:15079:21;2209:20:4;1043:15079:21;2209:20:4;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;;;1043:15079:21;;;;;;;;;1894:62:4;-1:-1:-1;;;1928:28:4;;1043:15079:21;1928:28:4;;1043:15079:21;;;;;;;;;;;;;;;13498:12;1043:15079;;;;;;;;;;;;;;;;;;;;;;;;;;1850:6;1043:15079;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;-1:-1:-1;;;;;1043:15079:21;5142:47;;5138:93;;5241:68;1043:15079;;-1:-1:-1;;;;;;1043:15079:21;;;;;;;;;5138:93;-1:-1:-1;;;5198:33:21;;1043:15079;5497:33;5198;1043:15079;;;;;;;;;;;;;;;2274:41;1043:15079;;;;;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;9234:6;1043:15079;;:::i;:::-;9234:6;:::i;:::-;1043:15079;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;2381:7:4;-1:-1:-1;;;;;1043:15079:21;2372:4:4;2364:24;2360:65;;1043:15079:21;;-1:-1:-1;;;;;1043:15079:21;;7734:10:4;:24;;;7730:90;;1043:15079:21;;;-1:-1:-1;;;;;;1043:15079:21;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;7877:64:4;;;;1043:15079:21;;7730:90:4;-1:-1:-1;;;7781:28:4;;1043:15079:21;4755:16;7781:28:4;2360:65;-1:-1:-1;;;2397:28:4;;1043:15079:21;2397:28:4;;1043:15079:21;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;7155:44;1043:15079;;-1:-1:-1;;;;1043:15079:21;;;;;;-1:-1:-1;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;;;;1237:43:4;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;2396:39;1043:15079;;;;;;;;;;;;;;;;;;;;;14496:12;1043:15079;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;7024:28;1043:15079;;-1:-1:-1;;;;1043:15079:21;;;;;;-1:-1:-1;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;;2230:37;1043:15079;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;-1:-1:-1;;;;;;1043:15079:21;;;;8741:16;1043:15079;;;;;;;;8737:128;;1043:15079;;;8737:128;1043:15079;;8741:16;1043:15079;;;;;;;-1:-1:-1;;1043:15079:21;;;8831:23;1043:15079;;8831:23;1043:15079;;;8831:23;:::i;:::-;1043:15079;;;;;;8831:23;1043:15079;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;:::i;:::-;;;;2321:68;1043:15079;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;:::i;:::-;;;;-1:-1:-1;;;;;;1043:15079:21;;;;;;7835:22;1043:15079;-1:-1:-1;;;;;1043:15079:21;;;;;7819:38;7815:70;;10148:6;;10188:8;10148:6;;:::i;:::-;10188:8;:::i;7815:70::-;-1:-1:-1;;;;;;7866:19:21;;1043:15079;7866:19;;1043:15079;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;-1:-1:-1;;;;;1043:15079:21;;;;9515:15;1043:15079;;;;;;;;9514:24;9510:124;;1043:15079;;;9510:124;1043:15079;;9515:15;1043:15079;;;;;;;-1:-1:-1;;1043:15079:21;9580:4;1043:15079;;;9598:25;1043:15079;-1:-1:-1;;;9598:25:21;1043:15079;;;;;;9598:25;:::i;:::-;1043:15079;;;;;;;;;;9598:25;1043:15079;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;-1:-1:-1;;;;;1043:15079:21;;;;9728:15;1043:15079;;;;;;;;9724:124;;1043:15079;;;9724:124;1043:15079;;9728:15;1043:15079;;;;;;;-1:-1:-1;;1043:15079:21;;;9812:25;1043:15079;-1:-1:-1;;;9812:25:21;1043:15079;;;;;;9812:25;:::i;1043:15079::-;;;;;;;;;;;;;;;13389:14;1043:15079;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;4781:1;;:::i;4718:53::-;-1:-1:-1;;;4755:16:21;;1043:15079;;4755:16;1043:15079;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;15399:22;1043:15079;-1:-1:-1;;;;;1043:15079:21;15385:10;:36;15381:70;;1043:15079;;:::i;:::-;;15605:25;;1043:15079;;;;;15593:9;;1043:15079;15593:9;;1043:15079;;;15593:9;1043:15079;;;;;1850:6;1043:15079;;15593:9;;;1043:15079;15593:9;;1043:15079;;;;;;;16058:55;1043:15079;;;;;;;;;15787:61;15822:26;;;:::i;:::-;1043:15079;;-1:-1:-1;;;;;1043:15079:21;15787:61;:::i;:::-;1043:15079;;;15893:26;;;:::i;:::-;15858:31;;;1043:15079;;15858:31;;;:61;;-1:-1:-1;;;;;1043:15079:21;15858:61;:::i;:::-;-1:-1:-1;;;;;1043:15079:21;;;;;;;;15494:12;1043:15079;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;1043:15079:21;;;;;;;;;;;;-1:-1:-1;;;;;;1043:15079:21;;;;;;;;15593:9;;1043:15079;;15858:31;1043:15079;;;;;;;16058:55;1043:15079;;;-1:-1:-1;;;1043:15079:21;;;;;;;;;-1:-1:-1;;;1043:15079:21;;;;;;;;15381:70;-1:-1:-1;;;15430:21:21;;1043:15079;;15430:21;1043:15079;;;;;;;;;;;;;;;;;1158:35:4;1043:15079:21;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;;;;;;;;:::i;:::-;;;;2441:66;1043:15079;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;1850:6;4882:35;;4878:65;;1287:7:0;1282:12;;;1278:35;;4953:12:21;1043:15079;;-1:-1:-1;;;;;1043:15079:21;;;;;;-1:-1:-1;;;;;;1043:15079:21;;;;;;;;;1278:35:0;18123:191;;;1043:15079:21;18123:191:0;;4878:65:21;-1:-1:-1;;;4926:17:21;;1043:15079;4926:17;;1043:15079;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;-1:-1:-1;;;;;1043:15079:21;5441:47;;5437:93;;1043:15079;;;-1:-1:-1;;;;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;;5420:11:4;1043:15079:21;;5420:11:4;5459:64:8;:69;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;3526:44:8;1043:15079:21;6489:11:4;5260:64:8;:69;;1043:15079:21;;;6489:11:4;5459:64:8;:69;;3580:31;;;1043:15079:21;;6489:11:4;5650:57:8;:62;;1043:15079:21;3668:24:8;;1043:15079:21;;6489:11:4;5848:65:8;:70;;3739:32;;;1043:15079:21;;6489:11:4;6052:63:8;:68;;3824:30;;;1043:15079:21;6489:11:4;3580:31:8;6489:11:4;6246:56:8;:61;;3905:23;;;1043:15079:21;;6489:11:4;6438:60:8;:65;;3977:27;;;1043:15079:21;3824:30:8;6489:11:4;6637:61:8;:66;;1043:15079:21;4054:28:8;;1043:15079:21;;6489:11:4;6827:55:8;:60;;1043:15079:21;4133:22:8;;1043:15079:21;;6489:11:4;7012:55:8;:60;;4204:22;;;1043:15079:21;;6489:11:4;7205:58:8;:63;;4276:25;;;1043:15079:21;;6489:11:4;7403:60:8;:65;;4353:27;;;1043:15079:21;;6489:11:4;7610:61:8;:66;;4434:28;;;1043:15079:21;;6489:11:4;7792:63:8;:68;;4517:30;;;1043:15079:21;;6489:11:4;7965:61:8;:66;;4598:28;;;1043:15079:21;;6489:11:4;8135:62:8;:67;;4675:29;;;1043:15079:21;;6489:11:4;8309:57:8;:62;;1043:15079:21;4752:24:8;;1043:15079:21;;6489:11:4;8474:58:8;:63;;4827:25;;;1043:15079:21;;6489:11:4;8635:54:8;:59;;4899:21;;;1043:15079:21;;6489:11:4;8808:69:8;8807:76;;4962:36;;;1043:15079:21;;6489:11:4;8993:65:8;8992:72;;5055:32;;;1043:15079:21;5055:32:8;1043:15079:21;;;;;;;;;3580:31:8;;;1043:15079:21;;;3580:31:8;1043:15079:21;;;;3668:24:8;;1043:15079:21;;;;;;;3739:32:8;;;1043:15079:21;;;3739:32:8;1043:15079:21;;;3824:30:8;;;1043:15079:21;;;3824:30:8;1043:15079:21;;;3905:23:8;;;1043:15079:21;;;3905:23:8;1043:15079:21;;;3977:27:8;;;1043:15079:21;;;3977:27:8;1043:15079:21;;;;4054:28:8;;1043:15079:21;;;;;;;;4133:22:8;;1043:15079:21;;;;;;;4204:22:8;;;1043:15079:21;;;4204:22:8;1043:15079:21;;;4276:25:8;;;1043:15079:21;;;4276:25:8;1043:15079:21;;;4353:27:8;;;1043:15079:21;;;4353:27:8;1043:15079:21;;;4434:28:8;;;1043:15079:21;;;4434:28:8;1043:15079:21;;;4517:30:8;;;1043:15079:21;;;4517:30:8;1043:15079:21;;;4598:28:8;;;1043:15079:21;;;4598:28:8;1043:15079:21;;;4675:29:8;;;1043:15079:21;;;4675:29:8;1043:15079:21;;;;4752:24:8;;1043:15079:21;;;;;;;4827:25:8;;;1043:15079:21;;;4827:25:8;1043:15079:21;;;4899:21:8;;;1043:15079:21;;;4899:21:8;1043:15079:21;;;4962:36:8;;;1043:15079:21;;;4962:36:8;1043:15079:21;;;5055:32:8;1043:15079:21;;;5055:32:8;1043:15079:21;;;;;;;;;:::i;:::-;-1:-1:-1;;1043:15079:21;-1:-1:-1;;2978:90:2;;;;1898:7:4;-1:-1:-1;;;;;1043:15079:21;1898:21:4;;;1894:62;;1076:15:2;;;;;:::i;:::-;-1:-1:-1;;;;;1123:5:2;1043:15079:21;;;;;1105:23:2;;;;:55;;;;1043:15079:21;1105:90:2;;;;1043:15079:21;1101:155:2;;;-1:-1:-1;;;;;1043:15079:21;1351:16:2;;1043:15079:21;1351:16:2;;:::i;:::-;1043:15079:21;1351:30:2;1347:96;;2978:90;1043:15079:21;896:83:2;;;:::i;:::-;1043:15079:21;;-1:-1:-1;;;2209:20:4;;1043:15079:21;;;;;2209:20:4;;;;;;;1043:15079:21;;;4303:25:4;1043:15079:21;;;2209:20:4;;;1043:15079:21;;;2243:26:4;2239:63;;-1:-1:-1;;;4492:28:3;;;2239:63:4;-1:-1:-1;;;2278:24:4;;;2209:20;;;;2978:90:2;2209:20:4;2978:90:2;2209:20:4;;;;;;;:::i;:::-;;;;;;;1347:96:2;-1:-1:-1;;;1404:28:2;;1043:15079:21;1404:28:2;;1101:155;-1:-1:-1;;;1218:27:2;;1043:15079:21;1218:27:2;;1105:90;1190:4;;;1164:31;1105:90;;;:55;1132:28;;;;-1:-1:-1;1105:55:2;;1894:62:4;-1:-1:-1;;;1928:28:4;;1043:15079:21;1928:28:4;;1043:15079:21;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;13274:18;1043:15079;;13274:18;;1043:15079;;;;;;;;;;;;;;;;;13910:12;1043:15079;13938:32;1043:15079;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;;;;1199:32:4;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;8256:8;1043:15079;;:::i;:::-;;;;;;;;;;;;;14751:12;1043:15079;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1043:15079:21;4722:10;:24;4718:53;;-1:-1:-1;;;;;;1043:15079:21;;;;8527:16;1043:15079;;;;;;;;8526:27;8522:128;;1043:15079;;;8522:128;1043:15079;;8527:16;1043:15079;;;;;;;-1:-1:-1;;1043:15079:21;8598:4;1043:15079;;;8616:23;1043:15079;;8616:23;1043:15079;;;8616:23;:::i;1043:15079::-;;;;;:::i;:::-;-1:-1:-1;;1043:15079:21;-1:-1:-1;;2978:90:2;;;;1898:7:4;-1:-1:-1;;;;;1043:15079:21;1898:21:4;;;1894:62;;1076:15:2;;;;;:::i;:::-;-1:-1:-1;;;;;1123:5:2;1043:15079:21;;;;;1105:23:2;;;;:55;;;;1043:15079:21;1105:90:2;;;;1043:15079:21;1101:155:2;;;-1:-1:-1;;;;;1043:15079:21;1351:16:2;;1043:15079:21;1351:16:2;;:::i;:::-;1043:15079:21;1351:30:2;1347:96;;2978:90;1043:15079:21;896:83:2;;;:::i;:::-;1043:15079:21;;-1:-1:-1;;;2209:20:4;;1043:15079:21;;;;;2209:20:4;;;;;;;1043:15079:21;;;3608:24:4;1043:15079:21;;;2209:20:4;;;1043:15079:21;;2243:26:4;2239:63;;-1:-1:-1;;;4492:28:3;;;1105:90:2;1190:4;;;1164:31;1105:90;;;:55;1132:28;;;;-1:-1:-1;1105:55:2;;1043:15079:21;;;;;;;-1:-1:-1;;1043:15079:21;;;;2381:7:4;-1:-1:-1;;;;;1043:15079:21;2372:4:4;2364:24;2360:65;;8152:17;1043:15079:21;-1:-1:-1;;;;;1043:15079:21;;;8183:10:4;:27;;;8179:91;;1043:15079:21;;;-1:-1:-1;;;;;;1043:15079:21;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;8415:18:4;1043:15079:21;8396:90:4;;;;;1043:15079:21;;;;;;;;8396:90:4;;;;;;;;1043:15079:21;8396:90:4;;;:::i;:::-;;;;;;;;;;;1043:15079:21;8502:64:4;;;;;1043:15079:21;;8396:90:4;;;;;1043:15079:21;8396:90:4;;:::i;:::-;1043:15079:21;8396:90:4;;;;;1043:15079:21;;;;;;;;;8396:90:4;1043:15079:21;;;8179:91:4;8233:26;;;1043:15079:21;8233:26:4;1043:15079:21;;8233:26:4;2360:65;2397:28;;;1043:15079:21;2397:28:4;1043:15079:21;;2397:28:4;1043:15079:21;;;;;;-1:-1:-1;;1043:15079:21;;;;;;13613:20;1043:15079;;;;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;:::i;:::-;-1:-1:-1;;1043:15079:21;-1:-1:-1;;2978:90:2;;1043:15079:21;2978:90:2;1898:7:4;-1:-1:-1;;;;;1043:15079:21;1898:21:4;1894:62;;896:83:2;;:::i;:::-;1043:15079:21;;-1:-1:-1;;;2209:20:4;;1043:15079:21;;;;2216:5:4;-1:-1:-1;;;;;1043:15079:21;2209:20:4;;;;;;;4916:28;1043:15079:21;;;;2209:20:4;;;1043:15079:21;;;2243:26:4;2239:63;;1043:15079:21;;;;:::i;:::-;;2239:63:4;2278:24;;;1043:15079:21;2278:24:4;1043:15079:21;;2278:24:4;2209:20;;;;1043:15079:21;2209:20:4;1043:15079:21;2209:20:4;;;;;;;:::i;:::-;;;;;;;1894:62;1928:28;;;1043:15079:21;1928:28:4;1043:15079:21;;1928:28:4;1043:15079:21;;;;;;-1:-1:-1;;1043:15079:21;;;;;5112:11:4;;6246:56:8;:61;;1043:15079:21;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;2187:37;1043:15079;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;:::i;:::-;12587:22;1043:15079;;;;;;-1:-1:-1;;;;;1043:15079:21;12573:10;:36;12569:70;;1043:15079;;;;;;;;;;;;;;12733:21;;;;1043:15079;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;12768:8;12764:41;;1043:15079;12764:41;12785:20;;;1043:15079;12785:20;1043:15079;;12785:20;1043:15079;;;12569:70;12618:21;;;1043:15079;12618:21;1043:15079;;12618:21;1043:15079;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;:::o;:::-;;;-1:-1:-1;;;;;1043:15079:21;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;1043:15079:21;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;-1:-1:-1;;;;;;1043:15079:21;;;;;;:::o;:::-;;-1:-1:-1;;1043:15079:21;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;-1:-1:-1;;1043:15079:21;;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;:::o;:::-;;;;-1:-1:-1;1043:15079:21;;;;;-1:-1:-1;1043:15079:21;;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;:::o;:::-;-1:-1:-1;;;;;1043:15079:21;;;;;;-1:-1:-1;;1043:15079:21;;;;:::o;:::-;;;-1:-1:-1;;;;;1043:15079:21;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;:::o;:::-;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;:::o;:::-;;-1:-1:-1;;;;;1043:15079:21;;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;-1:-1:-1;1043:15079:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;15494:12;1043:15079;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;;;;;;:::o;:::-;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;:::o;5621:1200::-;1043:15079;;:::i;:::-;;;5816:31;;;1043:15079;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;;5974:20;;5970:33;;6085:21;:39;6081:73;;-1:-1:-1;1043:15079:21;;;;;;;;;;;-1:-1:-1;;;;;;1043:15079:21;5703:12;1043:15079;6428:18;6424:88;;5621:1200;6526:18;6522:88;;5621:1200;6706:32;1043:15079;6740:32;1043:15079;;;;;;;5816:31;1043:15079;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;6680:134;;1043:15079;6680:134;5621:1200::o;6522:88::-;6546:32;1043:15079;6595:14;;1043:15079;;-1:-1:-1;;;;;1043:15079:21;6595:14;:::i;:::-;6522:88;;6424;6448:32;1043:15079;6497:14;;1043:15079;;-1:-1:-1;;;;;1043:15079:21;6497:14;:::i;:::-;6424:88;;6081:73;6133:21;;;-1:-1:-1;6133:21:21;;-1:-1:-1;6133:21:21;5970:33;5996:7;;;;;:::o;1043:15079::-;;;;;;;-1:-1:-1;;1043:15079:21;;:::o;:::-;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;1043:15079:21;;;;;;;;;;;;;;:::o;1466:247:2:-;1535:4;1544:6;-1:-1:-1;;;;;1043:15079:21;1527:23:2;1523:95;;1645:5;-1:-1:-1;;;;;1043:15079:21;1631:10:2;:19;1627:80;;1466:247::o;1627:80::-;1673:23;;;;;;;;1523:95;1573:34;;;;;;;;11723:399:21;11841:14;;11837:27;;12075:7;-1:-1:-1;;;;;1043:15079:21;12052:63;;;;;11854:1;1043:15079;12052:63;1043:15079;;;;;;;;;12052:63;;;;;;;;;;11723:399;:::o;12052:63::-;11854:1;12052:63;;;:::i;:::-;11723:399::o;11837:27::-;11857:7;:::o;8278:166::-;1043:15079;8355:21;1043:15079;;8355:25;;:56;;;;8278:166;8351:86;;;8278:166::o;8351:86::-;8420:17;;;-1:-1:-1;8420:17:21;;-1:-1:-1;8420:17:21;8355:56;-1:-1:-1;;;;;;1043:15079:21;-1:-1:-1;1043:15079:21;;;8385:16;1043:15079;;;;;;;;8384:27;;-1:-1:-1;8355:56:21;;3088:142:0;-1:-1:-1;;;3164:13:0;;;3160:36;;-1:-1:-1;;;;;1043:15079:21;;3088:142:0:o;3160:36::-;18123:191;;;;;;4031:342:1;4146:221;4031:342;;;4146:221;;;;;;;4031:342::o;4146:221::-;;;;;;;9254:177:21;1043:15079;9330:23;1043:15079;;;;9330:27;;:55;;;;9254:177;9326:98;;;9254:177::o;9326:98::-;9394:30;;;-1:-1:-1;9394:30:21;;-1:-1:-1;9394:30:21;9330:55;-1:-1:-1;;;;;1043:15079:21;-1:-1:-1;1043:15079:21;;;9362:15;1043:15079;;;;;;;;9361:24;;-1:-1:-1;9330:55:21;;1043:15079;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1043:15079:21;;;;;;;;;;;;;;:::o

Swarm Source

none

Block Transaction Gas Used Reward
view all blocks ##produced##

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.