Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/contracts/atlas/AtlETH.sol
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ abstract contract AtlETH is Permit69 {

if (_amt <= _balance) {
s_aData.balance = _balance - _amt;
} else if (SafeBlockNumber.get() > S_accessData[account].lastAccessedBlock + ESCROW_DURATION) {
} else if (SafeBlockNumber.get(IS_ARBITRUM_STACK) > S_accessData[account].lastAccessedBlock + ESCROW_DURATION) {
uint112 _shortfall = _amt - _balance;
s_aData.balance = 0;
s_aData.unbonding -= _shortfall; // underflow here to revert if insufficient balance
Expand Down Expand Up @@ -205,11 +205,11 @@ abstract contract AtlETH is Permit69 {
EscrowAccountAccessData storage s_aData = S_accessData[owner];

s_aData.bonded -= _amt;
s_aData.lastAccessedBlock = uint32(SafeBlockNumber.get());
s_aData.lastAccessedBlock = uint32(SafeBlockNumber.get(IS_ARBITRUM_STACK));

s_balanceOf[owner].unbonding += _amt;

emit Unbond(owner, amount, SafeBlockNumber.get() + ESCROW_DURATION + 1);
emit Unbond(owner, amount, SafeBlockNumber.get(IS_ARBITRUM_STACK) + ESCROW_DURATION + 1);
}

/// @notice Redeems the specified amount of AtlETH tokens for withdrawal.
Expand All @@ -220,7 +220,8 @@ abstract contract AtlETH is Permit69 {
/// @param owner The address of the account redeeming AtlETH tokens for withdrawal.
/// @param amount The amount of AtlETH tokens to redeem for withdrawal.
function _redeem(address owner, uint256 amount) internal {
if (SafeBlockNumber.get() <= uint256(S_accessData[owner].lastAccessedBlock) + ESCROW_DURATION) {
if (SafeBlockNumber.get(IS_ARBITRUM_STACK) <= uint256(S_accessData[owner].lastAccessedBlock) + ESCROW_DURATION)
{
revert EscrowLockActive();
}

Expand Down
4 changes: 2 additions & 2 deletions src/contracts/atlas/AtlasVerification.sol
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,13 @@ contract AtlasVerification is EIP712, NonceManager, DAppIntegration {
}

// Check if past user's deadline
if (userOp.deadline != 0 && SafeBlockNumber.get() > userOp.deadline) {
if (userOp.deadline != 0 && SafeBlockNumber.get(IS_ARBITRUM_STACK) > userOp.deadline) {
return
(allSolversGasLimit, allSolversCalldataGas, bidFindOverhead, ValidCallsResult.UserDeadlineReached);
}

// Check if past dapp's deadline
if (dAppOp.deadline != 0 && SafeBlockNumber.get() > dAppOp.deadline) {
if (dAppOp.deadline != 0 && SafeBlockNumber.get(IS_ARBITRUM_STACK) > dAppOp.deadline) {
return
(allSolversGasLimit, allSolversCalldataGas, bidFindOverhead, ValidCallsResult.DAppDeadlineReached);
}
Expand Down
3 changes: 3 additions & 0 deletions src/contracts/atlas/DAppIntegration.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import { SafeBlockNumber } from "../libraries/SafeBlockNumber.sol";
import { IDAppControl } from "../interfaces/IDAppControl.sol";
import { IAtlas } from "../interfaces/IAtlas.sol";
import { CallBits } from "../libraries/CallBits.sol";
Expand All @@ -15,6 +16,7 @@ contract DAppIntegration {

address public immutable ATLAS;
address public immutable L2_GAS_CALCULATOR;
bool public immutable IS_ARBITRUM_STACK;

// map for tracking which accounts are approved for a given dApp
// keccak256(governance, signor) => enabled
Expand All @@ -27,6 +29,7 @@ contract DAppIntegration {
constructor(address atlas, address l2GasCalculator) {
ATLAS = atlas;
L2_GAS_CALCULATOR = l2GasCalculator;
IS_ARBITRUM_STACK = SafeBlockNumber.isArbitrumStack();
}

// ---------------------------------------------------- //
Expand Down
4 changes: 2 additions & 2 deletions src/contracts/atlas/Escrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ abstract contract Escrow is AtlETH {
view
returns (uint256 result)
{
if (solverOp.deadline != 0 && SafeBlockNumber.get() > solverOp.deadline) {
if (solverOp.deadline != 0 && SafeBlockNumber.get(IS_ARBITRUM_STACK) > solverOp.deadline) {
result |= (
1
<< uint256(
Expand All @@ -415,7 +415,7 @@ abstract contract Escrow is AtlETH {

uint256 lastAccessedBlock = S_accessData[solverOp.from].lastAccessedBlock;

if (lastAccessedBlock >= SafeBlockNumber.get()) {
if (lastAccessedBlock >= SafeBlockNumber.get(IS_ARBITRUM_STACK)) {
result |= 1 << uint256(SolverOutcome.PerBlockLimit);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/atlas/GasAccounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ abstract contract GasAccounting is SafetyLocks {
S_bondedTotalSupply -= amount;

// update lastAccessedBlock since bonded balance is decreasing
accountData.lastAccessedBlock = uint32(SafeBlockNumber.get());
accountData.lastAccessedBlock = uint32(SafeBlockNumber.get(IS_ARBITRUM_STACK));
// NOTE: accountData changes must be persisted to storage separately
}

Expand Down
3 changes: 3 additions & 0 deletions src/contracts/atlas/Storage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity 0.8.28;

import "../types/EscrowTypes.sol";
import "../libraries/AccountingMath.sol";
import { SafeBlockNumber } from "../libraries/SafeBlockNumber.sol";

import { AtlasEvents } from "../types/AtlasEvents.sol";
import { AtlasErrors } from "../types/AtlasErrors.sol";
Expand All @@ -17,6 +18,7 @@ contract Storage is AtlasEvents, AtlasErrors, AtlasConstants {
address public immutable SIMULATOR;
address public immutable L2_GAS_CALCULATOR;
uint256 public immutable ESCROW_DURATION;
bool internal immutable IS_ARBITRUM_STACK; // True if on an Arbitrum stack chain, otherwise false

// AtlETH public constants
// These constants double as interface functions for the ERC20 standard, hence the lowercase naming convention.
Expand Down Expand Up @@ -66,6 +68,7 @@ contract Storage is AtlasEvents, AtlasErrors, AtlasConstants {
SIMULATOR = simulator;
L2_GAS_CALCULATOR = l2GasCalculator;
ESCROW_DURATION = escrowDuration;
IS_ARBITRUM_STACK = SafeBlockNumber.isArbitrumStack();

// Check Atlas gas surcharge fits in 24 bits
if(atlasSurchargeRate > type(uint24).max) {
Expand Down
8 changes: 7 additions & 1 deletion src/contracts/examples/fastlane-online/BaseStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
pragma solidity 0.8.28;

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

import { Reputation } from "./FastLaneTypes.sol";

import { SafeBlockNumber } from "../../libraries/SafeBlockNumber.sol";

contract BaseStorage {
error FLOnline_NotUnlocked();

Expand All @@ -18,6 +19,7 @@ contract BaseStorage {
uint256 internal constant _CONGESTION_BASE = 100_000;
bytes32 private constant _USER_LOCK_SLOT = keccak256("FLO_USER_LOCK");
bytes32 private constant _WINNING_SOLVER_SLOT = keccak256("FLO_WINNING_SOLVER");
bool public immutable IS_ARBITRUM_STACK;

uint256 internal S_rake;

Expand All @@ -36,6 +38,10 @@ contract BaseStorage {
// SolverFrom Reputation
mapping(address => Reputation) internal S_solverReputations;

constructor() {
IS_ARBITRUM_STACK = SafeBlockNumber.isArbitrumStack();
}

//////////////////////////////////////////////
///// VIEW FUNCTIONS //////
//////////////////////////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/examples/fastlane-online/SolverGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ contract SolverGateway is OuterHelpers {
// NOTE: Anyone can call this on behalf of the solver
// NOTE: the solverOp deadline cannot be before the userOp deadline, therefore if the
// solverOp deadline is passed then we know the userOp deadline is passed.
if (solverOp.deadline >= SafeBlockNumber.get()) {
if (solverOp.deadline >= SafeBlockNumber.get(IS_ARBITRUM_STACK)) {
revert SolverGateway_RefundCongestionBuyIns_DeadlineNotPassed();
}

Expand Down
2 changes: 1 addition & 1 deletion src/contracts/examples/v4-example/UniV4Hook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ contract UniV4Hook is V4DAppControl {
abi.encodePacked(
IPoolManager.Currency.unwrap(key.currency0),
IPoolManager.Currency.unwrap(key.currency1),
SafeBlockNumber.get()
SafeBlockNumber.get(IS_ARBITRUM_STACK)
)
);

Expand Down
4 changes: 3 additions & 1 deletion src/contracts/examples/v4-example/V4DAppControl.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ contract V4DAppControl is DAppControl {
bytes4 public constant SWAP = IPoolManager.swap.selector;
address public immutable hook;
address public immutable v4Singleton;
bool public immutable IS_ARBITRUM_STACK;

// Map to track when "Non Adversarial" flow is allowed.
// NOTE: This hook is meant to be used for multiple pairs
Expand Down Expand Up @@ -80,6 +81,7 @@ contract V4DAppControl is DAppControl {
{
hook = address(this);
v4Singleton = _v4Singleton;
IS_ARBITRUM_STACK = SafeBlockNumber.isArbitrumStack();
}

/////////////////////////////////////////////////////////
Expand Down Expand Up @@ -188,7 +190,7 @@ contract V4DAppControl is DAppControl {
abi.encodePacked(
IPoolManager.Currency.unwrap(key.currency0),
IPoolManager.Currency.unwrap(key.currency1),
SafeBlockNumber.get()
SafeBlockNumber.get(IS_ARBITRUM_STACK)
)
);

Expand Down
6 changes: 4 additions & 2 deletions src/contracts/helpers/Sorter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ contract Sorter is AtlasConstants {

IAtlas public immutable ATLAS;
IAtlasVerification public immutable VERIFICATION;
bool public immutable IS_ARBITRUM_STACK;

struct SortingData {
uint256 amount;
Expand All @@ -34,6 +35,7 @@ contract Sorter is AtlasConstants {
constructor(address _atlas) {
ATLAS = IAtlas(_atlas);
VERIFICATION = IAtlasVerification(ATLAS.VERIFICATION());
IS_ARBITRUM_STACK = SafeBlockNumber.isArbitrumStack();
}

function sortBids(
Expand Down Expand Up @@ -109,7 +111,7 @@ contract Sorter is AtlasConstants {

// Solvers can only do one tx per block - this prevents double counting bonded balances
uint256 solverLastActiveBlock = ATLAS.accountLastActiveBlock(solverOp.from);
if (solverLastActiveBlock >= SafeBlockNumber.get()) {
if (solverLastActiveBlock >= SafeBlockNumber.get(IS_ARBITRUM_STACK)) {
return false;
}

Expand All @@ -129,7 +131,7 @@ contract Sorter is AtlasConstants {
}

// solverOp.deadline must be in the future
if (solverOp.deadline != 0 && SafeBlockNumber.get() > solverOp.deadline) {
if (solverOp.deadline != 0 && SafeBlockNumber.get(IS_ARBITRUM_STACK) > solverOp.deadline) {
return false;
}

Expand Down
28 changes: 15 additions & 13 deletions src/contracts/libraries/SafeBlockNumber.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,24 @@ library SafeBlockNumber {
// https://arbiscan.io/address/0x0000000000000000000000000000000000000064
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
function get(bool useArbSys) internal view returns (uint256) {
if (useArbSys) {
return ARB_SYS.arbBlockNumber();
} else {
return block.number;
}
}

// TODO this still bloats Atlas contract size even when just used in constructor. Will need to pass in true/false as
// a constructor arg
function isArbitrumStack() internal view returns (bool) {
uint256 chainId = block.chainid;
return (
chainId == 42_161 // Arbitrum One
|| chainId == 42_170 // Arbitrum Nova
|| chainId == 421_614 // Arbitrum Sepolia
|| chainId == 98_866 // Plume
|| chainId == 98_867
); // Plume Testnet
}
}