Source Code
Overview
HYPE Balance
HYPE Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Sorter
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 18 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { IAtlas } from "../interfaces/IAtlas.sol";
import { IDAppControl } from "../interfaces/IDAppControl.sol";
import { IAtlasVerification } from "../interfaces/IAtlasVerification.sol";
import { CallBits } from "../libraries/CallBits.sol";
import { AccountingMath } from "../libraries/AccountingMath.sol";
import { CallVerification } from "../libraries/CallVerification.sol";
import { SafeBlockNumber } from "../libraries/SafeBlockNumber.sol";
import { AtlasConstants } from "../types/AtlasConstants.sol";
import "../types/UserOperation.sol";
import "../types/SolverOperation.sol";
import "../types/DAppOperation.sol";
import "../types/ConfigTypes.sol";
contract Sorter is AtlasConstants {
using CallBits for uint32;
using CallVerification for UserOperation;
using AccountingMath for uint256;
IAtlas public immutable ATLAS;
IAtlasVerification public immutable VERIFICATION;
struct SortingData {
uint256 amount;
bool valid;
}
constructor(address _atlas) {
ATLAS = IAtlas(_atlas);
VERIFICATION = IAtlasVerification(ATLAS.VERIFICATION());
}
function sortBids(
UserOperation calldata userOp,
SolverOperation[] calldata solverOps
)
external
view
returns (SolverOperation[] memory)
{
DAppConfig memory dConfig = IDAppControl(userOp.control).getDAppConfig(userOp);
uint256 count = solverOps.length;
(SortingData[] memory sortingData, uint256 invalid) = _getSortingData(dConfig, userOp, solverOps, count);
uint256[] memory sorted = _sort(sortingData, count, invalid);
count -= invalid;
SolverOperation[] memory solverOpsSorted = new SolverOperation[](count);
for (uint256 i; i < count; ++i) {
solverOpsSorted[i] = solverOps[sorted[i]];
}
return solverOpsSorted;
}
function _verifyBidFormat(address bidToken, SolverOperation calldata solverOp) internal pure returns (bool) {
return solverOp.bidToken == bidToken;
}
/// @dev Verifies that the solver is eligible
/// @dev Does not check solver signature as it might be trusted (solverOp.from == bundler)
/// @dev Checks other than signature are same as those done in `verifySolverOp()` in AtlasVerification and
/// `_validateSolverOpGasAndValue()` and `_validateSolverOpDeadline()` in Atlas
function _verifySolverEligibility(
DAppConfig memory dConfig,
UserOperation calldata userOp,
SolverOperation calldata solverOp,
uint256 totalSurchargeRate
)
internal
view
returns (bool)
{
// Make sure the solver has enough funds bonded
uint256 solverBalance = ATLAS.balanceOfBonded(solverOp.from);
// solverOp.gas has a ceiling of dConfig.solverGasLimit
uint256 solverOpGasLimit = Math.min(solverOp.gas, dConfig.solverGasLimit);
// Calldata gas a winning solver would pay for: non-solverOp calldata + their own solverOp calldata
uint256 calldataGas = (
USER_OP_STATIC_LENGTH + DAPP_OP_LENGTH + _SOLVER_OP_STATIC_LENGTH + _EXTRA_CALLDATA_LENGTH
+ userOp.data.length + solverOp.data.length
) * _GAS_PER_CALLDATA_BYTE;
// Execution gas a winning solver would pay for
uint256 executionGas = _BASE_TX_GAS_USED + _PRE_EXECUTE_METACALL_GAS + _POST_SETTLE_METACALL_GAS
+ solverOpGasLimit + userOp.gas + dConfig.dappGasLimit;
uint256 maxSolverCost = (solverOp.maxFeePerGas * (executionGas + calldataGas)).withSurcharge(totalSurchargeRate);
if (solverBalance < maxSolverCost) {
return false;
}
// solverOp.to must be the atlas address
if (solverOp.to != address(ATLAS)) {
return false;
}
// Solvers can only do one tx per block - this prevents double counting bonded balances
uint256 solverLastActiveBlock = ATLAS.accountLastActiveBlock(solverOp.from);
if (solverLastActiveBlock >= SafeBlockNumber.get()) {
return false;
}
// Ensure the solver control address matches the configured dApp control address
if (dConfig.to != solverOp.control) {
return false;
}
// Make sure that the solver's maxFeePerGas matches or exceeds the user's
if (solverOp.maxFeePerGas < userOp.maxFeePerGas) {
return false;
}
// solverOp.solver must not be the atlas or verification address
if (solverOp.solver == address(ATLAS) || solverOp.solver == address(VERIFICATION)) {
return false;
}
// solverOp.deadline must be in the future
if (solverOp.deadline != 0 && SafeBlockNumber.get() > solverOp.deadline) {
return false;
}
return true;
}
function _getSortingData(
DAppConfig memory dConfig,
UserOperation calldata userOp,
SolverOperation[] calldata solverOps,
uint256 count
)
internal
view
returns (SortingData[] memory, uint256)
{
address bidToken = IDAppControl(dConfig.to).getBidFormat(userOp);
uint256 totalSurchargeRate = ATLAS.getAtlasSurchargeRate() + userOp.bundlerSurchargeRate;
SortingData[] memory sortingData = new SortingData[](count);
bytes32 userOpHash = VERIFICATION.getUserOperationHash(userOp);
uint256 invalid;
for (uint256 i; i < count; ++i) {
if (
solverOps[i].userOpHash == userOpHash && _verifyBidFormat(bidToken, solverOps[i])
&& _verifySolverEligibility(dConfig, userOp, solverOps[i], totalSurchargeRate)
) {
sortingData[i] = SortingData({ amount: solverOps[i].bidAmount, valid: true });
} else {
sortingData[i] = SortingData({ amount: 0, valid: false });
unchecked {
++invalid;
}
}
}
return (sortingData, invalid);
}
function _sort(
SortingData[] memory sortingData,
uint256 count,
uint256 invalid
)
internal
pure
returns (uint256[] memory)
{
uint256[] memory sorted = new uint256[](count - invalid);
if (sorted.length == 0) {
return sorted;
}
int256 topBidAmount;
int256 topBidIndex;
for (uint256 i; i < sorted.length; ++i) {
topBidAmount = -1;
topBidIndex = -1;
for (uint256 j; j < count; ++j) {
if (sortingData[j].valid && int256(sortingData[j].amount) > topBidAmount) {
topBidAmount = int256(sortingData[j].amount);
topBidIndex = int256(j);
}
}
if (topBidIndex == -1) {
// all indices in sorting data are invalid
break;
}
sortingData[uint256(topBidIndex)].valid = false;
sorted[i] = uint256(topBidIndex);
}
return sorted;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Muldiv operation overflow.
*/
error MathOverflowedMulDiv();
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
return a / b;
}
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
* Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0 = x * y; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator.
// Always >= 1. See https://cs.stackexchange.com/q/138556/92363.
uint256 twos = denominator & (0 - denominator);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
// works in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}//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 "../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;
}//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: 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;
}
}//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
library AccountingMath {
uint256 internal constant _MAX_BUNDLER_REFUND_RATE = 8000; // out of 10_000 = 80%
uint256 internal constant _SCALE = 10_000; // 10_000 / 10_000 = 100%
function withSurcharge(uint256 amount, uint256 surchargeRate) internal pure returns (uint256 adjustedAmount) {
adjustedAmount = amount * (_SCALE + surchargeRate) / _SCALE;
}
function withoutSurcharge(uint256 amount, uint256 surchargeRate) internal pure returns (uint256 unadjustedAmount) {
unadjustedAmount = amount * _SCALE / (_SCALE + surchargeRate);
}
function withSurcharges(
uint256 amount,
uint256 atlasSurchargeRate,
uint256 bundlerSurchargeRate
)
internal
pure
returns (uint256 adjustedAmount)
{
adjustedAmount = amount * (_SCALE + atlasSurchargeRate + bundlerSurchargeRate) / _SCALE;
}
// gets the Atlas surcharge from an unadjusted amount
function getSurcharge(
uint256 unadjustedAmount,
uint256 surchargeRate
)
internal
pure
returns (uint256 surchargeAmount)
{
surchargeAmount = unadjustedAmount * surchargeRate / _SCALE;
}
// NOTE: This max should only be applied when there are no winning solvers.
// Set to 80% of the metacall gas cost, because the remaining 20% can be collected through storage refunds.
function maxBundlerRefund(uint256 metacallGasCost) internal pure returns (uint256 maxRefund) {
maxRefund = metacallGasCost * _MAX_BUNDLER_REFUND_RATE / _SCALE;
}
}//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import "../types/SolverOperation.sol";
import "../types/UserOperation.sol";
import { CallBits } from "./CallBits.sol";
library CallVerification {
using CallBits for uint32;
function getCallChainHash(
UserOperation memory userOp,
SolverOperation[] memory solverOps
)
internal
pure
returns (bytes32 callSequenceHash)
{
bytes memory callSequence = abi.encodePacked(abi.encode(userOp), abi.encode(solverOps));
callSequenceHash = keccak256(callSequence);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import { ArbSys } from "nitro-contracts/src/precompiles/ArbSys.sol";
library SafeBlockNumber {
// https://arbiscan.io/address/0x0000000000000000000000000000000000000064
// https://github.com/OffchainLabs/nitro/blob/9270a057fa8b30fb960872d74f7632aae8f5efbe/precompiles/ArbSys.go#L35
ArbSys internal constant ARB_SYS = ArbSys(address(0x0000000000000000000000000000000000000064));
uint256 internal constant ARBITRUM_ONE_CHAIN_ID = 42_161;
uint256 internal constant ARBITRUM_NOVA_CHAIN_ID = 42_170;
uint256 internal constant ARBITRUM_SEPOLIA_CHAIN_ID = 421_614;
uint256 internal constant PLUME_CHAIN_ID = 98_866;
uint256 internal constant PLUME_TESTNET_CHAIN_ID = 98_867;
function get() internal view returns (uint256) {
uint256 chainId = block.chainid;
if (
chainId == ARBITRUM_ONE_CHAIN_ID || chainId == ARBITRUM_NOVA_CHAIN_ID
|| chainId == ARBITRUM_SEPOLIA_CHAIN_ID || chainId == PLUME_CHAIN_ID || chainId == PLUME_TESTNET_CHAIN_ID
) {
// Arbitrum One or Nova chain
return ARB_SYS.arbBlockNumber();
} else {
return block.number;
}
}
}//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import "./ValidCalls.sol";
import { GasAccLib } from "../libraries/GasAccLib.sol";
// NOTE: Internal constants that are defined but not used in the logic of a smart contract, will NOT be included in the
// bytecode of the smart contract when compiled. However, public constants will be included in every inheriting contract
// as they are part of the ABI. As such, only internal constants are defined in this shared contract.
contract AtlasConstants {
// ------------------------------------------------------- //
// ATLAS CONSTANTS //
// ------------------------------------------------------- //
// Atlas constants
uint256 internal constant _GAS_VALUE_DECIMALS_TO_DROP = 1e9; // measured in gwei
uint256 internal constant _UNLOCKED = 0;
// Atlas constants used in `_bidFindingIteration()`
uint256 internal constant _BITS_FOR_INDEX = 16;
uint256 internal constant _FIRST_16_BITS_TRUE_MASK = uint256(0xFFFF);
// Escrow constants
uint256 internal constant _VALIDATION_GAS_LIMIT = 500_000;
uint256 internal constant _GRACEFUL_RETURN_GAS_OFFSET = 40_000;
// Gas Accounting constants
uint256 internal constant _GAS_PER_CALLDATA_BYTE = GasAccLib._GAS_PER_CALLDATA_BYTE;
// Calldata bytes charged at half the upper rate of 16 gas per byte (i.e. charged at 8 gas per byte), for both zero
// and non-zero bytes of calldata.
uint256 internal constant _BASE_TX_GAS_USED = 21_000;
uint256 internal constant _PRE_EXECUTE_METACALL_GAS = 150_000; // Approx gas used from start of metacall to the
// `execute()` function call, including EE deployment cost. For gas limit estimation purposes.
uint256 internal constant _POST_SETTLE_METACALL_GAS = 70_000; // Approx gas used from the gasleft() measurement
// taken at the start of `_settle()`. For full metacall gas reimbursement purposes.
uint256 internal constant _EXECUTE_SOLVER_OVERHEAD = 45_000; // Approx upper bound gas used by each
// `_executeSolverOperation()` call, excluding the `_solverOpWrapper()` gas. For gas limit estimation purposes.
uint256 internal constant _SOLVER_OP_STATIC_LENGTH = GasAccLib._SOLVER_OP_STATIC_LENGTH; // SolverOperation calldata
// length excluding solverOp.data
uint256 internal constant _BUNDLER_FAULT_OFFSET = 4500; // Extra gas to write off if solverOp failure is bundler
// fault in `_handleSolverFailAccounting()`. Value is worst-case gas measured for bundler fault.
uint256 internal constant _SOLVER_FAULT_OFFSET = 28_800; // Extra gas to charge solver if solverOp failure is solver
// fault in `_handleSolverFailAccounting()`. Value is worst-case gas measured for solver fault.
uint256 internal constant _EXTRA_CALLDATA_LENGTH = 238; // incl. gasRefundBeneficiary address and dynamic offset
// calldata
// First 160 bits of _solverLock are the address of the current solver.
// The 161st bit represents whether the solver has called back via `reconcile`.
// The 162nd bit represents whether the solver's outstanding debt has been repaid via `reconcile`.
uint256 internal constant _SOLVER_CALLED_BACK_MASK = 1 << 161;
uint256 internal constant _SOLVER_FULFILLED_MASK = 1 << 162;
// Used to set Lock phase without changing the activeEnvironment or callConfig.
uint256 internal constant _LOCK_PHASE_MASK =
uint256(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00);
// ValidCalls error threshold before which the metacall reverts, and after which it returns gracefully to store
// nonces as used.
uint8 internal constant _GRACEFUL_RETURN_THRESHOLD = uint8(ValidCallsResult.InvertBidValueCannotBeExPostBids) + 1;
// ------------------------------------------------------- //
// ATLAS VERIFICATION CONSTANTS //
// ------------------------------------------------------- //
uint8 internal constant _MAX_SOLVERS = type(uint8).max - 1;
uint256 internal constant _BID_FIND_OVERHEAD = 5000; // Overhead gas for the logic required to execute and sort each
// solverOp in `_bidFindingIteration()`
// Params below are used to calculate the tolerated max diff between actual gasleft and expected gasleft, in the
// `_getAndVerifyGasLimits()` function. This tolerance is mostly for calldata gas cost differences.
uint256 internal constant _UPPER_BASE_EXEC_GAS_TOLERANCE = 20_000;
uint256 internal constant _LOWER_BASE_EXEC_GAS_TOLERANCE = 60_000;
uint256 internal constant _TOLERANCE_PER_SOLVER = 33_000;
}//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
}//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.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;
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
}//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
}// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.4.21 <0.9.0;
/**
* @title System level functionality
* @notice For use by contracts to interact with core L2-specific functionality.
* Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064.
*/
interface ArbSys {
/**
* @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0)
* @return block number as int
*/
function arbBlockNumber() external view returns (uint256);
/**
* @notice Get Arbitrum block hash (reverts unless currentBlockNum-256 <= arbBlockNum < currentBlockNum)
* @return block hash
*/
function arbBlockHash(
uint256 arbBlockNum
) external view returns (bytes32);
/**
* @notice Gets the rollup's unique chain identifier
* @return Chain identifier as int
*/
function arbChainID() external view returns (uint256);
/**
* @notice Get internal version number identifying an ArbOS build, this is `55 + nitroArbOS version number`
* e.g. on ArbOS 31 this would return 86. This is the only function that have the 55 offset.
* @return version number as int
*/
function arbOSVersion() external view returns (uint256);
/**
* @notice Returns 0 since Nitro has no concept of storage gas
* @return uint 0
*/
function getStorageGasAvailable() external view returns (uint256);
/**
* @notice (deprecated) check if current call is top level (meaning it was triggered by an EoA or a L1 contract)
* @dev this call has been deprecated and may be removed in a future release
* @return true if current execution frame is not a call by another L2 contract
*/
function isTopLevelCall() external view returns (bool);
/**
* @notice map L1 sender contract address to its L2 alias
* @param sender sender address
* @param unused argument no longer used
* @return aliased sender address
*/
function mapL1SenderContractAddressToL2Alias(
address sender,
address unused
) external pure returns (address);
/**
* @notice check if the caller (of this caller of this) is an aliased L1 contract address
* @return true iff the caller's address is an alias for an L1 contract address
*/
function wasMyCallersAddressAliased() external view returns (bool);
/**
* @notice return the address of the caller (of this caller of this), without applying L1 contract address aliasing
* @return address of the caller's caller, without applying L1 contract address aliasing
*/
function myCallersAddressWithoutAliasing() external view returns (address);
/**
* @notice Send given amount of Eth to dest from sender.
* This is a convenience function, which is equivalent to calling sendTxToL1 with empty data.
* @param destination recipient address on L1
* @return unique identifier for this L2-to-L1 transaction.
*/
function withdrawEth(
address destination
) external payable returns (uint256);
/**
* @notice Send a transaction to L1
* @dev it is not possible to execute on the L1 any L2-to-L1 transaction which contains data
* to a contract address without any code (as enforced by the Bridge contract).
* @param destination recipient address on L1
* @param data (optional) calldata for L1 contract call
* @return a unique identifier for this L2-to-L1 transaction.
*/
function sendTxToL1(
address destination,
bytes calldata data
) external payable returns (uint256);
/**
* @notice Get send Merkle tree state
* @return size number of sends in the history
* @return root root hash of the send history
* @return partials hashes of partial subtrees in the send history tree
*/
function sendMerkleTreeState()
external
view
returns (uint256 size, bytes32 root, bytes32[] memory partials);
/**
* @notice creates a send txn from L2 to L1
* @param position = (level << 192) + leaf = (0 << 192) + leaf = leaf
*/
event L2ToL1Tx(
address caller,
address indexed destination,
uint256 indexed hash,
uint256 indexed position,
uint256 arbBlockNum,
uint256 ethBlockNum,
uint256 timestamp,
uint256 callvalue,
bytes data
);
/// @dev DEPRECATED in favour of the new L2ToL1Tx event above after the nitro upgrade
event L2ToL1Transaction(
address caller,
address indexed destination,
uint256 indexed uniqueId,
uint256 indexed batchNumber,
uint256 indexInBatch,
uint256 arbBlockNum,
uint256 ethBlockNum,
uint256 timestamp,
uint256 callvalue,
bytes data
);
/**
* @notice logs a merkle branch for proof synthesis
* @param reserved an index meant only to align the 4th index with L2ToL1Transaction's 4th event
* @param hash the merkle hash
* @param position = (level << 192) + leaf
*/
event SendMerkleUpdate(
uint256 indexed reserved, bytes32 indexed hash, uint256 indexed position
);
error InvalidBlockNumber(uint256 requested, uint256 current);
}//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import { SafeCast } from "openzeppelin-contracts/contracts/utils/math/SafeCast.sol";
import { AccountingMath } from "./AccountingMath.sol";
import { IL2GasCalculator } from "../interfaces/IL2GasCalculator.sol";
// All GasLedger vars are measured in units of gas.
// All GasLedger vars also include calldata and execution gas components.
// remainingMaxGas and unreachedSolverGas measure max gas limits (C + E).
// writeoffsGas and solverFaultFailureGas measure actual gas used (C + E).
// Only stores base gas values. Does not include the surcharges or gasprice components.
// type(uint40).max ~= 1.09 x 10^12, plenty even for gigagas (10^9) blocks
struct GasLedger {
uint40 remainingMaxGas; // Measured at start, decreased by solverOp gas limits when reached
uint40 writeoffsGas; // Gas used for solverOps but written off due to bundler fault
uint40 solverFaultFailureGas; // Gas used by solverOps that failed due to solver fault
uint40 unreachedSolverGas; // Sum of gas limits of solverOps not yet reached in the current metacall
uint40 maxApprovedGasSpend; // Max gas units approved by current solver to be spent from their bonded atlETH
uint24 atlasSurchargeRate; // Scale is 10_000 (100%) --> max atlas surcharge rate ~= 167.77x or 16777%
uint24 bundlerSurchargeRate; // Scale is 10_000 (100%) --> max bundler surcharge rate ~= 167.77x or 16777%
// NOTE: 8 bits unused.
}
// All BorrowsLedger vars are measured in units of native token (wei).
struct BorrowsLedger {
uint128 borrows; // Total native token value borrowed in the current metacall
uint128 repays; // Total native token value repaid in the current metacall
}
library GasAccLib {
using AccountingMath for uint256;
using SafeCast for uint256;
uint256 internal constant _SOLVER_OP_STATIC_LENGTH = 608;
uint256 internal constant _GAS_PER_CALLDATA_BYTE = 8; // Half of the upper 16 gas per non-zero byte, applied to all
// calldata bytes.
function pack(GasLedger memory gasLedger) internal pure returns (uint256) {
return uint256(gasLedger.remainingMaxGas) | (uint256(gasLedger.writeoffsGas) << 40)
| (uint256(gasLedger.solverFaultFailureGas) << 80) | (uint256(gasLedger.unreachedSolverGas) << 120)
| (uint256(gasLedger.maxApprovedGasSpend) << 160) | (uint256(gasLedger.atlasSurchargeRate) << 200)
| (uint256(gasLedger.bundlerSurchargeRate) << 224);
}
function pack(BorrowsLedger memory borrowsLedger) internal pure returns (uint256) {
return uint256(borrowsLedger.borrows) | (uint256(borrowsLedger.repays) << 128);
}
function toGasLedger(uint256 gasLedgerPacked) internal pure returns (GasLedger memory) {
return GasLedger({
remainingMaxGas: uint40(gasLedgerPacked),
writeoffsGas: uint40(gasLedgerPacked >> 40),
solverFaultFailureGas: uint40(gasLedgerPacked >> 80),
unreachedSolverGas: uint40(gasLedgerPacked >> 120),
maxApprovedGasSpend: uint40(gasLedgerPacked >> 160),
atlasSurchargeRate: uint24(gasLedgerPacked >> 200),
bundlerSurchargeRate: uint24(gasLedgerPacked >> 224)
});
}
function toBorrowsLedger(uint256 borrowsLedgerPacked) internal pure returns (BorrowsLedger memory) {
return BorrowsLedger({ borrows: uint128(borrowsLedgerPacked), repays: uint128(borrowsLedgerPacked >> 128) });
}
function netRepayments(BorrowsLedger memory bL) internal pure returns (int256) {
return uint256(bL.repays).toInt256() - uint256(bL.borrows).toInt256();
}
// Returns the max gas liability (in native token units) for the current solver.
// `remainingMaxGas` is max gas limit as measured at start of metacall, with the gas limit of each solverOp
// subtracted at the end of its execution.
// `unreachedSolverGas` is the sum of solverOp gas limits not yet reached, with gas limit of current solverOp
// subtracted at the start of its execution, before bonded balance check.
// Thus `remainingMaxGas - unreachedSolverGas` is the max gas the current solver might need to pay for if they win,
// including dApp hook gas limits and userOp gas limit.
function solverGasLiability(GasLedger memory gL) internal view returns (uint256) {
return uint256(gL.remainingMaxGas - gL.unreachedSolverGas).withSurcharge(
uint256(gL.atlasSurchargeRate + gL.bundlerSurchargeRate)
) * tx.gasprice;
}
// Returns the sum of the Atlas and bundler surcharge rates.
// Scale of the returned value is 10_000 (100%).
function totalSurchargeRate(GasLedger memory gL) internal pure returns (uint256) {
return uint256(gL.atlasSurchargeRate + gL.bundlerSurchargeRate);
}
function solverOpCalldataGas(uint256 calldataLength, address l2GasCalculator) internal view returns (uint256 gas) {
if (l2GasCalculator == address(0)) {
// Default to using mainnet gas calculations
// _SOLVER_OP_STATIC_LENGTH = SolverOperation calldata length excluding solverOp.data
gas = (calldataLength + _SOLVER_OP_STATIC_LENGTH) * _GAS_PER_CALLDATA_BYTE;
} else {
gas = IL2GasCalculator(l2GasCalculator).getCalldataGas(calldataLength + _SOLVER_OP_STATIC_LENGTH);
}
}
function calldataGas(uint256 calldataLength, address l2GasCalculator) internal view returns (uint256 gas) {
if (l2GasCalculator == address(0)) {
// Default to using mainnet gas calculations
gas = calldataLength * _GAS_PER_CALLDATA_BYTE;
} else {
gas = IL2GasCalculator(l2GasCalculator).getCalldataGas(calldataLength);
}
}
function metacallCalldataGas(
uint256 msgDataLength,
address l2GasCalculator
)
internal
view
returns (uint256 calldataGas)
{
if (l2GasCalculator == address(0)) {
calldataGas = msgDataLength * _GAS_PER_CALLDATA_BYTE;
} else {
calldataGas = IL2GasCalculator(l2GasCalculator).initialGasUsed(msgDataLength);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.20;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeCast {
/**
* @dev Value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
/**
* @dev An int value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedIntToUint(int256 value);
/**
* @dev Value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
/**
* @dev An uint value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedUintToInt(uint256 value);
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toUint248(uint256 value) internal pure returns (uint248) {
if (value > type(uint248).max) {
revert SafeCastOverflowedUintDowncast(248, value);
}
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toUint240(uint256 value) internal pure returns (uint240) {
if (value > type(uint240).max) {
revert SafeCastOverflowedUintDowncast(240, value);
}
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toUint232(uint256 value) internal pure returns (uint232) {
if (value > type(uint232).max) {
revert SafeCastOverflowedUintDowncast(232, value);
}
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) {
revert SafeCastOverflowedUintDowncast(224, value);
}
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toUint216(uint256 value) internal pure returns (uint216) {
if (value > type(uint216).max) {
revert SafeCastOverflowedUintDowncast(216, value);
}
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toUint208(uint256 value) internal pure returns (uint208) {
if (value > type(uint208).max) {
revert SafeCastOverflowedUintDowncast(208, value);
}
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toUint200(uint256 value) internal pure returns (uint200) {
if (value > type(uint200).max) {
revert SafeCastOverflowedUintDowncast(200, value);
}
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toUint192(uint256 value) internal pure returns (uint192) {
if (value > type(uint192).max) {
revert SafeCastOverflowedUintDowncast(192, value);
}
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toUint184(uint256 value) internal pure returns (uint184) {
if (value > type(uint184).max) {
revert SafeCastOverflowedUintDowncast(184, value);
}
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toUint176(uint256 value) internal pure returns (uint176) {
if (value > type(uint176).max) {
revert SafeCastOverflowedUintDowncast(176, value);
}
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toUint168(uint256 value) internal pure returns (uint168) {
if (value > type(uint168).max) {
revert SafeCastOverflowedUintDowncast(168, value);
}
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) {
revert SafeCastOverflowedUintDowncast(160, value);
}
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toUint152(uint256 value) internal pure returns (uint152) {
if (value > type(uint152).max) {
revert SafeCastOverflowedUintDowncast(152, value);
}
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toUint144(uint256 value) internal pure returns (uint144) {
if (value > type(uint144).max) {
revert SafeCastOverflowedUintDowncast(144, value);
}
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toUint136(uint256 value) internal pure returns (uint136) {
if (value > type(uint136).max) {
revert SafeCastOverflowedUintDowncast(136, value);
}
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) {
revert SafeCastOverflowedUintDowncast(128, value);
}
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toUint120(uint256 value) internal pure returns (uint120) {
if (value > type(uint120).max) {
revert SafeCastOverflowedUintDowncast(120, value);
}
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toUint112(uint256 value) internal pure returns (uint112) {
if (value > type(uint112).max) {
revert SafeCastOverflowedUintDowncast(112, value);
}
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toUint104(uint256 value) internal pure returns (uint104) {
if (value > type(uint104).max) {
revert SafeCastOverflowedUintDowncast(104, value);
}
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) {
revert SafeCastOverflowedUintDowncast(96, value);
}
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toUint88(uint256 value) internal pure returns (uint88) {
if (value > type(uint88).max) {
revert SafeCastOverflowedUintDowncast(88, value);
}
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toUint80(uint256 value) internal pure returns (uint80) {
if (value > type(uint80).max) {
revert SafeCastOverflowedUintDowncast(80, value);
}
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toUint72(uint256 value) internal pure returns (uint72) {
if (value > type(uint72).max) {
revert SafeCastOverflowedUintDowncast(72, value);
}
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) {
revert SafeCastOverflowedUintDowncast(64, value);
}
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toUint56(uint256 value) internal pure returns (uint56) {
if (value > type(uint56).max) {
revert SafeCastOverflowedUintDowncast(56, value);
}
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toUint48(uint256 value) internal pure returns (uint48) {
if (value > type(uint48).max) {
revert SafeCastOverflowedUintDowncast(48, value);
}
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toUint40(uint256 value) internal pure returns (uint40) {
if (value > type(uint40).max) {
revert SafeCastOverflowedUintDowncast(40, value);
}
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) {
revert SafeCastOverflowedUintDowncast(32, value);
}
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toUint24(uint256 value) internal pure returns (uint24) {
if (value > type(uint24).max) {
revert SafeCastOverflowedUintDowncast(24, value);
}
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) {
revert SafeCastOverflowedUintDowncast(16, value);
}
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert SafeCastOverflowedUintDowncast(8, value);
}
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) {
revert SafeCastOverflowedIntToUint(value);
}
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(248, value);
}
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(240, value);
}
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(232, value);
}
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(224, value);
}
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(216, value);
}
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(208, value);
}
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(200, value);
}
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(192, value);
}
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(184, value);
}
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(176, value);
}
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(168, value);
}
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(160, value);
}
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(152, value);
}
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(144, value);
}
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(136, value);
}
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(128, value);
}
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(120, value);
}
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(112, value);
}
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(104, value);
}
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(96, value);
}
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(88, value);
}
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(80, value);
}
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(72, value);
}
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(64, value);
}
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(56, value);
}
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(48, value);
}
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(40, value);
}
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(32, value);
}
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(24, value);
}
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(16, value);
}
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(8, value);
}
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
if (value > uint256(type(int256).max)) {
revert SafeCastOverflowedUintToInt(value);
}
return int256(value);
}
}//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
interface IL2GasCalculator {
/// @notice Calculate the cost (in gas units) of calldata in ETH on a L2 with a different fee structure than mainnet
function getCalldataGas(uint256 calldataLength) external view returns (uint256 calldataGas);
/// @notice Gets the cost (in gas units) of initial gas used for a tx with a different calldata fee than mainnet
function initialGasUsed(uint256 calldataLength) external view returns (uint256 gasUsed);
}{
"remappings": [
"ds-test/=lib/forge-std/lib/ds-test/src/",
"eth-gas-reporter/=node_modules/eth-gas-reporter/",
"forge-std/=lib/forge-std/src/",
"hardhat/=node_modules/hardhat/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"solady/=lib/solady/src/",
"nitro-contracts/=lib/nitro-contracts/",
"@offchainlabs/upgrade-executor/=lib/nitro-contracts/node_modules/@offchainlabs/upgrade-executor/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@uniswap/lib/=lib/nitro-contracts/node_modules/@uniswap/lib/contracts/",
"@uniswap/v2-core/=lib/nitro-contracts/node_modules/@uniswap/v2-core/contracts/",
"chainlink/=lib/chainlink/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"redstone-oracles-monorepo/=lib/redstone-oracles-monorepo/",
"solmate/=lib/solmate/src/"
],
"optimizer": {
"enabled": true,
"runs": 18
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": true
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_atlas","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ATLAS","outputs":[{"internalType":"contract IAtlas","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERIFICATION","outputs":[{"internalType":"contract IAtlasVerification","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":"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"},{"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":"solverOps","type":"tuple[]"}],"name":"sortBids","outputs":[{"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":"","type":"tuple[]"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c080604052346100e057602060049161003861120a91823803809361002582846100e4565b82396001600160a01b039281019061011b565b168060805260405192838092630f235ce960e31b82525afa9081156100d5575f916100a6575b506001600160a01b031660a0526040516110cf908161013b82396080518181816052015281816101df0152610d2d015260a051818181609a015281816102890152610f5c0152f35b6100c8915060203d6020116100ce575b6100c081836100e4565b81019061011b565b5f61005e565b503d6100b6565b6040513d5f823e3d90fd5b5f80fd5b601f909101601f19168101906001600160401b0382119082101761010757604052565b634e487b7160e01b5f52604160045260245ffd5b908160209103126100e057516001600160a01b03811681036100e0579056fe6080806040526004361015610012575f80fd5b5f3560e01c9081635d7563f4146100c957508063791ae748146100855763e982ae921461003d575f80fd5b34610081575f366003190112610081576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5f80fd5b34610081575f366003190112610081576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610081576040366003190112610081576004356001600160401b0381116100815780600401610200600319833603011261008157602435916001600160401b0383116100815736602384011215610081578260040135936001600160401b038511610081576024840193602436918760051b0101116100815760c0816001600160a01b0361015b610104860161089e565b63e514a79d60e01b835216818061017588600483016109a5565b03915afa90811561070e575f916107ae575b50805160405163476aa3b960e11b8152929060209084906001600160a01b031681806101b689600483016109a5565b03915afa92831561070e575f93610772575b50604051635b651b0560e01b8152906020826004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa91821561070e575f9261073c575b50610184013562ffffff81168091036100815761023391610be7565b9161023d86610b30565b9261024b60405194856108e9565b868452601f1961025a88610b30565b015f5b81811061071957505060405163c51ff57960e01b8152926020848061028589600483016109a5565b03817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa93841561070e575f946106da575b509492909187925f9687955f5b8681106105e357868b896102ed6102e682858f610bf4565b9184610b0f565b916102f783610b30565b9361030560405195866108e9565b838552601f1961031485610b30565b015f5b8181106105775750505f5b84811061044d57856040518091602082016020835281518091526040830190602060408260051b8601019301915f905b82821061036157505050500390f35b9193600191939550602061043d8192603f198a8203018652885190858060a01b038251168152858060a01b0384830151168482015260408201516040820152606082015160608201526080820151608082015260a082015160a0820152858060a01b0360c08301511660c0820152858060a01b0360e08301511660e0820152610100820151610100820152858060a01b036101208301511661012082015261014082015161014082015261018061042b6101608401516101a06101608501526101a084019061087a565b9201519061018081840391015261087a565b9601920192018594939192610352565b61046261045a8286610b47565b518385610b6f565b906101a0823603126100815760405161047a816108cd565b6104838361092f565b81526104916020840161092f565b602082015260408301356040820152606083013560608201526080830135608082015260a083013560a08201526104ca60c0840161092f565b60c08201526104db60e0840161092f565b60e08201526101008301356101008201526104f9610120840161092f565b6101208201526101408301356101408201526101608301356001600160401b0381116100815761052c9036908501610b92565b6101608201526101808301356001600160401b0381116100815760019361055591369101610b92565b6101808201526105658289610b47565b526105708188610b47565b5001610322565b602090604051610586816108cd565b5f81525f838201525f60408201525f60608201525f60808201525f60a08201525f60c08201525f60e08201525f6101008201525f6101208201525f6101408201526060610160820152606061018082015282828a01015201610317565b9193958597506105fb83610100928d98949698610b6f565b013514806106af575b80610693575b1561065c57806101406106206001938d8d610b6f565b01356040519061062f826108b2565b8152826020820152610641828a610b47565b5261064c8189610b47565b505b0191879593918a95936102ce565b966001809160405161066d816108b2565b5f81525f60208201526106808b8b610b47565b5261068b8a8a610b47565b50019761064e565b506106aa846106a3838d8d610b6f565b8486610d29565b61060a565b506106c76101206106c1838d8d610b6f565b0161089e565b6001600160a01b03868116911614610604565b9093506020813d602011610706575b816106f6602093836108e9565b81010312610081575192886102c1565b3d91506106e9565b6040513d5f823e3d90fd5b602090604051610728816108b2565b5f81525f838201528282890101520161025d565b9091506020813d60201161076a575b81610758602093836108e9565b81010312610081575190610184610217565b3d915061074b565b9092506020813d6020116107a6575b8161078e602093836108e9565b810103126100815761079f9061090a565b91866101c8565b3d9150610781565b905060c0813d60c011610872575b816107c960c093836108e9565b81010312610081576040519060c08201908282106001600160401b0383111761085e5760a0916040526107fb8161090a565b83526108096020820161091e565b602084015261081a6040820161090a565b604084015261082b6060820161091e565b606084015261083c6080820161091e565b608084015201516001600160801b03811681036100815760a082015285610187565b634e487b7160e01b5f52604160045260245ffd5b3d91506107bc565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b356001600160a01b03811681036100815790565b604081019081106001600160401b0382111761085e57604052565b6101a081019081106001600160401b0382111761085e57604052565b90601f801991011681019081106001600160401b0382111761085e57604052565b51906001600160a01b038216820361008157565b519063ffffffff8216820361008157565b35906001600160a01b038216820361008157565b359063ffffffff8216820361008157565b9035601e19823603018112156100815701602081359101916001600160401b03821161008157813603831361008157565b908060209392818452848401375f828201840152601f01601f1916010190565b60208152906001600160a01b036109bb8261092f565b16602083015260018060a01b036109d46020830161092f565b1660408301526040810135606083015260608101356080830152608081013560a083015260a081013560c083015260c081013560e083015260018060a01b03610a1f60e0830161092f565b1661010083015260018060a01b03610a3a610100830161092f565b1661012083015263ffffffff610a536101208301610943565b1661014083015263ffffffff610a6c6101408301610943565b1661016083015263ffffffff610a856101608301610943565b166101808301526101808101359162ffffff831680930361008157610b0c926101a082015260018060a01b03610abe6101a0840161092f565b166101c0820152610af9610aed610ad96101c0850185610954565b6102006101e0860152610220850191610985565b926101e0810190610954565b91610200601f1982860301910152610985565b90565b91908203918211610b1c57565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b03811161085e5760051b60200190565b8051821015610b5b5760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b9190811015610b5b5760051b8101359061019e1981360301821215610081570190565b81601f82011215610081578035906001600160401b03821161085e5760405192610bc6601f8401601f1916602001856108e9565b8284526020838301011161008157815f926020809301838601378301015290565b91908201809211610b1c57565b9291610c009082610b0f565b92610c0a84610b30565b93610c1860405195866108e9565b808552610c27601f1991610b30565b01366020860137835115610ce0575f5b8451811015610cdb575f19805f5b858110610c815750505f198114610c7b5790815f6020610c6760019587610b47565b510152610c748288610b47565b5201610c37565b50505050565b6020610c938287999699989598610b47565b510151151580610cc7575b610cb1575b600101959295949194610c45565b809550610cbf915084610b47565b515184610ca3565b5081610cd38287610b47565b515113610c9e565b505050565b5050565b903590601e198136030182121561008157018035906001600160401b0382116100815760200191813603831361008157565b81810292918115918404141715610b1c57565b91927f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692909190610d628561089e565b60405163825ad60760e01b81526001600160a01b039091166004820152602081602481885afa90811561070e575f91610fe0575b50606086013563ffffffff6060840151168082105f14610fd85750935b610dc16101c0850185610ce4565b905061070e018061070e11610b1c57610dea90610de26101608a018a610ce4565b919050610be7565b948560031b9580870460081490151715610b1c576203ad6801806203ad6811610b1c57610e42610e36610e25610e4893606089013590610be7565b63ffffffff60808801511690610be7565b9660808a013597610be7565b86610d16565b9061271001908161271011610b1c5761271091610e6491610d16565b0411610f9d57836001600160a01b03610e7f6020880161089e565b1603610f9d57610e8e8561089e565b604051633e1042bd60e11b81526001600160a01b039091166004820152602081602481885afa90811561070e575f91610fa6575b50610ecb611012565b1115610f9d57516001600160a01b0390811690610eea60e0870161089e565b1603610f95576080013511610f8f5760c08201906001600160a01b03610f0f8361089e565b1614908115610f50575b50610f4b5760a001358015159081610f3a575b50610f3657600190565b5f90565b9050610f44611012565b115f610f2c565b505f90565b610f5a915061089e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081169116145f610f19565b50505f90565b505050505f90565b50505050505f90565b90506020813d602011610fd0575b81610fc1602093836108e9565b8101031261008157515f610ec2565b3d9150610fb4565b905093610db3565b90506020813d60201161100a575b81610ffb602093836108e9565b8101031261008157515f610d96565b3d9150610fee565b61a4b1461480156110b7575b80156110ab575b801561109f575b8015611093575b1561108f5760405163a3b1b31d60e01b815260208160048160645afa90811561070e575f91611060575090565b90506020813d602011611087575b8161107b602093836108e9565b81010312610081575190565b3d915061106e565b4390565b50620182334614611033565b5062018232461461102c565b5062066eee4614611025565b5061a4ba461461101e56fea164736f6c634300081c000a000000000000000000000000137b8fdf027598f1bf5f2d60cb081bd8539bd8c7
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f3560e01c9081635d7563f4146100c957508063791ae748146100855763e982ae921461003d575f80fd5b34610081575f366003190112610081576040517f000000000000000000000000137b8fdf027598f1bf5f2d60cb081bd8539bd8c76001600160a01b03168152602090f35b5f80fd5b34610081575f366003190112610081576040517f0000000000000000000000002b072c802605cd2a0ffa4631529fbcff1e4843b16001600160a01b03168152602090f35b34610081576040366003190112610081576004356001600160401b0381116100815780600401610200600319833603011261008157602435916001600160401b0383116100815736602384011215610081578260040135936001600160401b038511610081576024840193602436918760051b0101116100815760c0816001600160a01b0361015b610104860161089e565b63e514a79d60e01b835216818061017588600483016109a5565b03915afa90811561070e575f916107ae575b50805160405163476aa3b960e11b8152929060209084906001600160a01b031681806101b689600483016109a5565b03915afa92831561070e575f93610772575b50604051635b651b0560e01b8152906020826004817f000000000000000000000000137b8fdf027598f1bf5f2d60cb081bd8539bd8c76001600160a01b03165afa91821561070e575f9261073c575b50610184013562ffffff81168091036100815761023391610be7565b9161023d86610b30565b9261024b60405194856108e9565b868452601f1961025a88610b30565b015f5b81811061071957505060405163c51ff57960e01b8152926020848061028589600483016109a5565b03817f0000000000000000000000002b072c802605cd2a0ffa4631529fbcff1e4843b16001600160a01b03165afa93841561070e575f946106da575b509492909187925f9687955f5b8681106105e357868b896102ed6102e682858f610bf4565b9184610b0f565b916102f783610b30565b9361030560405195866108e9565b838552601f1961031485610b30565b015f5b8181106105775750505f5b84811061044d57856040518091602082016020835281518091526040830190602060408260051b8601019301915f905b82821061036157505050500390f35b9193600191939550602061043d8192603f198a8203018652885190858060a01b038251168152858060a01b0384830151168482015260408201516040820152606082015160608201526080820151608082015260a082015160a0820152858060a01b0360c08301511660c0820152858060a01b0360e08301511660e0820152610100820151610100820152858060a01b036101208301511661012082015261014082015161014082015261018061042b6101608401516101a06101608501526101a084019061087a565b9201519061018081840391015261087a565b9601920192018594939192610352565b61046261045a8286610b47565b518385610b6f565b906101a0823603126100815760405161047a816108cd565b6104838361092f565b81526104916020840161092f565b602082015260408301356040820152606083013560608201526080830135608082015260a083013560a08201526104ca60c0840161092f565b60c08201526104db60e0840161092f565b60e08201526101008301356101008201526104f9610120840161092f565b6101208201526101408301356101408201526101608301356001600160401b0381116100815761052c9036908501610b92565b6101608201526101808301356001600160401b0381116100815760019361055591369101610b92565b6101808201526105658289610b47565b526105708188610b47565b5001610322565b602090604051610586816108cd565b5f81525f838201525f60408201525f60608201525f60808201525f60a08201525f60c08201525f60e08201525f6101008201525f6101208201525f6101408201526060610160820152606061018082015282828a01015201610317565b9193958597506105fb83610100928d98949698610b6f565b013514806106af575b80610693575b1561065c57806101406106206001938d8d610b6f565b01356040519061062f826108b2565b8152826020820152610641828a610b47565b5261064c8189610b47565b505b0191879593918a95936102ce565b966001809160405161066d816108b2565b5f81525f60208201526106808b8b610b47565b5261068b8a8a610b47565b50019761064e565b506106aa846106a3838d8d610b6f565b8486610d29565b61060a565b506106c76101206106c1838d8d610b6f565b0161089e565b6001600160a01b03868116911614610604565b9093506020813d602011610706575b816106f6602093836108e9565b81010312610081575192886102c1565b3d91506106e9565b6040513d5f823e3d90fd5b602090604051610728816108b2565b5f81525f838201528282890101520161025d565b9091506020813d60201161076a575b81610758602093836108e9565b81010312610081575190610184610217565b3d915061074b565b9092506020813d6020116107a6575b8161078e602093836108e9565b810103126100815761079f9061090a565b91866101c8565b3d9150610781565b905060c0813d60c011610872575b816107c960c093836108e9565b81010312610081576040519060c08201908282106001600160401b0383111761085e5760a0916040526107fb8161090a565b83526108096020820161091e565b602084015261081a6040820161090a565b604084015261082b6060820161091e565b606084015261083c6080820161091e565b608084015201516001600160801b03811681036100815760a082015285610187565b634e487b7160e01b5f52604160045260245ffd5b3d91506107bc565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b356001600160a01b03811681036100815790565b604081019081106001600160401b0382111761085e57604052565b6101a081019081106001600160401b0382111761085e57604052565b90601f801991011681019081106001600160401b0382111761085e57604052565b51906001600160a01b038216820361008157565b519063ffffffff8216820361008157565b35906001600160a01b038216820361008157565b359063ffffffff8216820361008157565b9035601e19823603018112156100815701602081359101916001600160401b03821161008157813603831361008157565b908060209392818452848401375f828201840152601f01601f1916010190565b60208152906001600160a01b036109bb8261092f565b16602083015260018060a01b036109d46020830161092f565b1660408301526040810135606083015260608101356080830152608081013560a083015260a081013560c083015260c081013560e083015260018060a01b03610a1f60e0830161092f565b1661010083015260018060a01b03610a3a610100830161092f565b1661012083015263ffffffff610a536101208301610943565b1661014083015263ffffffff610a6c6101408301610943565b1661016083015263ffffffff610a856101608301610943565b166101808301526101808101359162ffffff831680930361008157610b0c926101a082015260018060a01b03610abe6101a0840161092f565b166101c0820152610af9610aed610ad96101c0850185610954565b6102006101e0860152610220850191610985565b926101e0810190610954565b91610200601f1982860301910152610985565b90565b91908203918211610b1c57565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b03811161085e5760051b60200190565b8051821015610b5b5760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b9190811015610b5b5760051b8101359061019e1981360301821215610081570190565b81601f82011215610081578035906001600160401b03821161085e5760405192610bc6601f8401601f1916602001856108e9565b8284526020838301011161008157815f926020809301838601378301015290565b91908201809211610b1c57565b9291610c009082610b0f565b92610c0a84610b30565b93610c1860405195866108e9565b808552610c27601f1991610b30565b01366020860137835115610ce0575f5b8451811015610cdb575f19805f5b858110610c815750505f198114610c7b5790815f6020610c6760019587610b47565b510152610c748288610b47565b5201610c37565b50505050565b6020610c938287999699989598610b47565b510151151580610cc7575b610cb1575b600101959295949194610c45565b809550610cbf915084610b47565b515184610ca3565b5081610cd38287610b47565b515113610c9e565b505050565b5050565b903590601e198136030182121561008157018035906001600160401b0382116100815760200191813603831361008157565b81810292918115918404141715610b1c57565b91927f000000000000000000000000137b8fdf027598f1bf5f2d60cb081bd8539bd8c76001600160a01b031692909190610d628561089e565b60405163825ad60760e01b81526001600160a01b039091166004820152602081602481885afa90811561070e575f91610fe0575b50606086013563ffffffff6060840151168082105f14610fd85750935b610dc16101c0850185610ce4565b905061070e018061070e11610b1c57610dea90610de26101608a018a610ce4565b919050610be7565b948560031b9580870460081490151715610b1c576203ad6801806203ad6811610b1c57610e42610e36610e25610e4893606089013590610be7565b63ffffffff60808801511690610be7565b9660808a013597610be7565b86610d16565b9061271001908161271011610b1c5761271091610e6491610d16565b0411610f9d57836001600160a01b03610e7f6020880161089e565b1603610f9d57610e8e8561089e565b604051633e1042bd60e11b81526001600160a01b039091166004820152602081602481885afa90811561070e575f91610fa6575b50610ecb611012565b1115610f9d57516001600160a01b0390811690610eea60e0870161089e565b1603610f95576080013511610f8f5760c08201906001600160a01b03610f0f8361089e565b1614908115610f50575b50610f4b5760a001358015159081610f3a575b50610f3657600190565b5f90565b9050610f44611012565b115f610f2c565b505f90565b610f5a915061089e565b7f0000000000000000000000002b072c802605cd2a0ffa4631529fbcff1e4843b16001600160a01b039081169116145f610f19565b50505f90565b505050505f90565b50505050505f90565b90506020813d602011610fd0575b81610fc1602093836108e9565b8101031261008157515f610ec2565b3d9150610fb4565b905093610db3565b90506020813d60201161100a575b81610ffb602093836108e9565b8101031261008157515f610d96565b3d9150610fee565b61a4b1461480156110b7575b80156110ab575b801561109f575b8015611093575b1561108f5760405163a3b1b31d60e01b815260208160048160645afa90811561070e575f91611060575090565b90506020813d602011611087575b8161107b602093836108e9565b81010312610081575190565b3d915061106e565b4390565b50620182334614611033565b5062018232461461102c565b5062066eee4614611025565b5061a4ba461461101e56fea164736f6c634300081c000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000137b8fdf027598f1bf5f2d60cb081bd8539bd8c7
-----Decoded View---------------
Arg [0] : _atlas (address): 0x137B8Fdf027598f1Bf5F2d60cB081bD8539BD8c7
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000137b8fdf027598f1bf5f2d60cb081bd8539bd8c7
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in HYPE
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.