S Price: $0.512277 (+0.99%)

Contract

0x1CeC01DC0fFEE5eB5aF47DbEc1809F2A7c601C30

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ZeroExSettlerDeployerSafeModule

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
cancun EvmVersion
File 1 of 12 : SafeModule.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import {IDeployer, IDeployerRemove} from "./IDeployer.sol";
import {Feature} from "./Feature.sol";
import {Nonce} from "./Nonce.sol";
import {Revert} from "../utils/Revert.sol";

interface ISafeMinimal {
    enum Operation {
        Call,
        DelegateCall
    }

    function execTransactionFromModuleReturnData(address to, uint256 value, bytes memory data, Operation operation)
        external
        returns (bool success, bytes memory returnData);

    function isOwner(address) external view returns (bool);
}

contract ZeroExSettlerDeployerSafeModule is IDeployerRemove {
    using Revert for bool;

    ISafeMinimal public immutable safe;
    IDeployer public constant deployer = IDeployer(0x00000000000004533Fe15556B1E086BB1A72cEae);

    constructor(address _safe) {
        assert(address(this) == 0x1CeC01DC0fFEE5eB5aF47DbEc1809F2A7c601C30 || block.chainid == 31337);
        safe = ISafeMinimal(_safe);
    }

    modifier onlyOwner() {
        require(safe.isOwner(msg.sender));
        _;
    }

    function _callSafeReturnBool() internal onlyOwner returns (bool) {
        (bool success, bytes memory returnData) =
            safe.execTransactionFromModuleReturnData(address(deployer), 0, msg.data, ISafeMinimal.Operation.Call);
        success.maybeRevert(returnData);
        return abi.decode(returnData, (bool));
    }

    function remove(Feature, Nonce) external override returns (bool) {
        return _callSafeReturnBool();
    }

    function remove(address) external override returns (bool) {
        return _callSafeReturnBool();
    }

    function removeAll(Feature) external override returns (bool) {
        return _callSafeReturnBool();
    }
}

File 2 of 12 : IDeployer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import {IERC165} from "@forge-std/interfaces/IERC165.sol";
import {IOwnable} from "./TwoStepOwnable.sol";
import {IERC1967Proxy} from "../proxy/ERC1967UUPSUpgradeable.sol";
import {IMultiCall} from "../utils/MultiCall.sol";
import {Feature} from "./Feature.sol";
import {Nonce} from "./Nonce.sol";

interface IERC721View is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event PermanentURI(string, uint256 indexed); // not technically part of the standard

    function balanceOf(address) external view returns (uint256);
    function ownerOf(uint256 tokenId) external view returns (address);
    function getApproved(uint256 tokenId) external view returns (address);
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

interface IERC721ViewMetadata is IERC721View {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256) external view returns (string memory);
}

interface IDeployerRemove {
    function remove(Feature, Nonce) external returns (bool);
    function remove(address) external returns (bool);
    function removeAll(Feature) external returns (bool);
}

interface IDeployer is IOwnable, IERC721ViewMetadata, IMultiCall, IDeployerRemove {
    function authorized(Feature) external view returns (address, uint40);
    function descriptionHash(Feature) external view returns (bytes32);
    function prev(Feature) external view returns (address);
    function next(Feature) external view returns (address);
    function deployInfo(address) external view returns (Feature, Nonce);
    function authorize(Feature, address, uint40) external returns (bool);
    function setDescription(Feature, string calldata) external returns (string memory);
    function deploy(Feature, bytes calldata) external payable returns (address, Nonce);

    // ERC-6093 errors
    error ERC721InvalidOwner(address owner);
    error ERC721NonexistentToken(uint256 tokenId);

    error FeatureNotInitialized(Feature);
    error FeatureInitialized(Feature);
    error DeployFailed(Feature, Nonce, address);
    error FutureNonce(Nonce);
    error NoInstance();

    event Authorized(Feature indexed, address indexed, uint40);
    event Deployed(Feature indexed, Nonce indexed, address indexed);
    event Removed(Feature indexed, Nonce indexed, address indexed);
    event RemovedAll(Feature indexed);
}

File 3 of 12 : Feature.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import {Panic} from "../utils/Panic.sol";

type Feature is uint128;

function eq(Feature a, Feature b) pure returns (bool) {
    return Feature.unwrap(a) == Feature.unwrap(b);
}

function isNull(Feature a) pure returns (bool) {
    return Feature.unwrap(a) == 0;
}

using {eq as ==, isNull} for Feature global;

function wrap(uint256 x) pure returns (Feature) {
    if (x > type(uint128).max) {
        Panic.panic(Panic.ARITHMETIC_OVERFLOW);
    }
    if (x == 0) {
        Panic.panic(Panic.ENUM_CAST);
    }
    return Feature.wrap(uint128(x));
}

File 4 of 12 : Nonce.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

/// @dev if you update this, you also have to update the length of the array `NonceList.List.links` in Deployer.sol
type Nonce is uint32;

function incr(Nonce a) pure returns (Nonce) {
    return Nonce.wrap(Nonce.unwrap(a) + 1);
}

function gt(Nonce a, Nonce b) pure returns (bool) {
    return Nonce.unwrap(a) > Nonce.unwrap(b);
}

function eq(Nonce a, Nonce b) pure returns (bool) {
    return Nonce.unwrap(a) == Nonce.unwrap(b);
}

function isNull(Nonce a) pure returns (bool) {
    return Nonce.unwrap(a) == 0;
}

using {incr, gt as >, eq as ==, isNull} for Nonce global;

Nonce constant zero = Nonce.wrap(0);

File 5 of 12 : Revert.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

library Revert {
    function _revert(bytes memory reason) internal pure {
        assembly ("memory-safe") {
            revert(add(reason, 0x20), mload(reason))
        }
    }

    function maybeRevert(bool success, bytes memory reason) internal pure {
        if (!success) {
            _revert(reason);
        }
    }
}

File 6 of 12 : IERC165.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

interface IERC165 {
    /// @notice Query if a contract implements an interface
    /// @param interfaceID The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    /// uses less than 30,000 gas.
    /// @return `true` if the contract implements `interfaceID` and
    /// `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

File 7 of 12 : TwoStepOwnable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import {AbstractContext} from "../Context.sol";
import {IERC165} from "@forge-std/interfaces/IERC165.sol";

interface IOwnable is IERC165 {
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    function owner() external view returns (address);

    function transferOwnership(address) external returns (bool);

    error PermissionDenied();
    error ZeroAddress();
}

abstract contract AbstractOwnable is IOwnable {
    // This looks stupid (and it is), but this is required due to the glaring
    // deficiencies in Solidity's inheritance system.

    function _requireOwner() internal view virtual;

    /// This function should be overridden exactly once. This provides the base
    /// implementation. Mixin classes may modify `owner`.
    function _ownerImpl() internal view virtual returns (address);

    function owner() public view virtual override returns (address) {
        return _ownerImpl();
    }

    function _setOwner(address) internal virtual;

    constructor() {
        assert(type(IOwnable).interfaceId == 0x7f5828d0);
        assert(type(IERC165).interfaceId == 0x01ffc9a7);
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId || interfaceId == type(IOwnable).interfaceId;
    }

    /// This modifier is not virtual on purpose; override _requireOwner instead.
    modifier onlyOwner() {
        _requireOwner();
        _;
    }
}

abstract contract AddressSlotStorage {
    type AddressSlot is bytes32;

    function _get(AddressSlot s) internal view returns (address r) {
        assembly ("memory-safe") {
            r := sload(s)
        }
    }

    function _set(AddressSlot s, address v) internal {
        assembly ("memory-safe") {
            sstore(s, v)
        }
    }
}

abstract contract OwnableStorageBase is AddressSlotStorage {
    function _ownerSlot() internal pure virtual returns (AddressSlot);
}

abstract contract OwnableStorage is OwnableStorageBase {
    address private _owner;

    function _ownerSlot() internal pure override returns (AddressSlot r) {
        assembly ("memory-safe") {
            r := _owner.slot
        }
    }

    constructor() {
        assert(AddressSlot.unwrap(_ownerSlot()) == bytes32(0));
    }
}

abstract contract OwnableBase is AbstractContext, AbstractOwnable {
    function renounceOwnership() public virtual returns (bool);
}

abstract contract OwnableImpl is OwnableStorageBase, OwnableBase {
    function _ownerImpl() internal view override returns (address) {
        return _get(_ownerSlot());
    }

    function _setOwner(address newOwner) internal virtual override {
        emit OwnershipTransferred(owner(), newOwner);
        _set(_ownerSlot(), newOwner);
    }

    function _requireOwner() internal view override {
        if (_msgSender() != owner()) {
            revert PermissionDenied();
        }
    }

    function renounceOwnership() public virtual override onlyOwner returns (bool) {
        _setOwner(address(0));
        return true;
    }

    function transferOwnership(address newOwner) public virtual override onlyOwner returns (bool) {
        if (newOwner == address(0)) {
            revert ZeroAddress();
        }
        _setOwner(newOwner);
        return true;
    }
}

abstract contract Ownable is OwnableStorage, OwnableImpl {}

abstract contract AbstractTwoStepOwnable is AbstractOwnable {
    function _requirePendingOwner() internal view virtual;

    function pendingOwner() public view virtual returns (address);

    function _setPendingOwner(address) internal virtual;

    /// This modifier is not virtual on purpose; override _requirePendingOwner
    /// instead.
    modifier onlyPendingOwner() {
        _requirePendingOwner();
        _;
    }

    event OwnershipPending(address indexed);
}

abstract contract TwoStepOwnableStorageBase is AddressSlotStorage {
    function _pendingOwnerSlot() internal pure virtual returns (AddressSlot);
}

abstract contract TwoStepOwnableStorage is TwoStepOwnableStorageBase {
    address private _pendingOwner;

    function _pendingOwnerSlot() internal pure override returns (AddressSlot r) {
        assembly ("memory-safe") {
            r := _pendingOwner.slot
        }
    }

    constructor() {
        assert(AddressSlot.unwrap(_pendingOwnerSlot()) == bytes32(uint256(1)));
    }
}

abstract contract TwoStepOwnableBase is OwnableBase, AbstractTwoStepOwnable {}

abstract contract TwoStepOwnableImpl is TwoStepOwnableStorageBase, TwoStepOwnableBase {
    function pendingOwner() public view override returns (address) {
        return _get(_pendingOwnerSlot());
    }

    function _setPendingOwner(address newPendingOwner) internal override {
        emit OwnershipPending(newPendingOwner);
        _set(_pendingOwnerSlot(), newPendingOwner);
    }

    function renounceOwnership() public virtual override onlyOwner returns (bool) {
        if (pendingOwner() != address(0)) {
            _setPendingOwner(address(0));
        }
        _setOwner(address(0));
        return true;
    }

    function transferOwnership(address newOwner) public virtual override onlyOwner returns (bool) {
        if (newOwner == address(0)) {
            revert ZeroAddress();
        }
        _setPendingOwner(newOwner);
        return true;
    }

    function _requirePendingOwner() internal view override {
        if (_msgSender() != pendingOwner()) {
            revert PermissionDenied();
        }
    }

    function acceptOwnership() public onlyPendingOwner returns (bool) {
        _setOwner(_msgSender());
        _setPendingOwner(address(0));
        return true;
    }

    function rejectOwnership() public onlyPendingOwner returns (bool) {
        _setPendingOwner(address(0));
        return true;
    }
}

abstract contract TwoStepOwnable is OwnableStorage, OwnableImpl, TwoStepOwnableStorage, TwoStepOwnableImpl {
    function renounceOwnership() public override(OwnableImpl, TwoStepOwnableImpl) returns (bool) {
        return TwoStepOwnableImpl.renounceOwnership();
    }

    function transferOwnership(address newOwner) public override(OwnableImpl, TwoStepOwnableImpl) returns (bool) {
        return TwoStepOwnableImpl.transferOwnership(newOwner);
    }
}

File 8 of 12 : ERC1967UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {
    AbstractOwnable,
    OwnableImpl,
    OwnableStorageBase,
    TwoStepOwnableImpl,
    TwoStepOwnableStorageBase
} from "../deployer/TwoStepOwnable.sol";

import {Revert} from "../utils/Revert.sol";
import {ItoA} from "../utils/ItoA.sol";
import {Panic} from "../utils/Panic.sol";

interface IERC1967Proxy {
    event Upgraded(address indexed implementation);

    function implementation() external view returns (address);

    function version() external view returns (string memory);

    function upgrade(address newImplementation) external payable returns (bool);

    function upgradeAndCall(address newImplementation, bytes calldata data) external payable returns (bool);
}

abstract contract AbstractUUPSUpgradeable {
    address internal immutable _implementation;
    uint256 internal immutable _implVersion;

    constructor(uint256 newVersion) {
        _implementation = address(this);
        _implVersion = newVersion;
    }

    error OnlyProxy();

    function _requireProxy() private view {
        address impl = _implementation;
        if (implementation() != impl) {
            revert OnlyProxy();
        }
        if (address(this) == impl) {
            revert OnlyProxy();
        }
    }

    modifier onlyProxy() {
        _requireProxy();
        _;
    }

    function implementation() public view virtual returns (address);
}

/// The upgrade mechanism for this proxy is slightly more convoluted than the
/// previously-standard rollback-checking ERC1967 UUPS proxy. The standard
/// rollback check uses the value of the ERC1967 rollback slot to avoid infinite
/// recursion. The old implementation's `upgrade` or `upgradeAndCall` sets the
/// ERC1967 implementation slot to the new implementation, then calls `upgrade`
/// on the new implementation to attempt to set the value of the implementation
/// slot *back to the old implementation*. This is checked, and the value of the
/// implementation slot is re-set to the new implementation.
///
/// This proxy abuses the ERC1967 rollback slot to store a version number which
/// must be incremented on each upgrade. This mechanism follows the same general
/// outline as the previously-standard version. The old implementation's
/// `upgrade` or `upgradeAndCall` sets the ERC1967 implementation slot to the
/// new implementation, then calls `upgrade` on the new implementation. The new
/// implementation's `upgrade` sets the implementation slot back to the old
/// implementation *and* advances the rollback slot to the new version
/// number. The old implementation then checks the value of both the
/// implementation and rollback slots before re-setting the implementation slot
/// to the new implementation.
abstract contract ERC1967UUPSUpgradeable is AbstractOwnable, IERC1967Proxy, AbstractUUPSUpgradeable {
    using Revert for bytes;

    error VersionMismatch(uint256 oldVersion, uint256 newVersion);
    error InterferedWithImplementation(address expected, address actual);
    error InterferedWithVersion(uint256 expected, uint256 actual);
    error DidNotIncrementVersion(uint256 current, uint256 next);
    error IncrementedVersionTooMuch(uint256 current, uint256 next);
    error RollbackFailed(address expected, address actual);
    error InitializationFailed();

    uint256 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    uint256 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;

    // `_initialize` checks that the version number exactly increments, but
    // `upgrade` checks only that the version number increases by at least 1 and
    // no more than `_MAX_VERSION_INCREASE`. This preserves `upgrade` as an
    // escape hatch against botched upgrades.
    uint256 private constant _MAX_VERSION_INCREASE = type(uint64).max;

    constructor(uint256 newVersion) AbstractUUPSUpgradeable(newVersion) {
        assert(_IMPLEMENTATION_SLOT == uint256(keccak256("eip1967.proxy.implementation")) - 1);
        assert(_ROLLBACK_SLOT == uint256(keccak256("eip1967.proxy.rollback")) - 1);
        if (newVersion >= type(uint256).max - _MAX_VERSION_INCREASE) {
            Panic.panic(Panic.ARITHMETIC_OVERFLOW);
        }
    }

    function implementation()
        public
        view
        virtual
        override(IERC1967Proxy, AbstractUUPSUpgradeable)
        returns (address result)
    {
        assembly ("memory-safe") {
            result := sload(_IMPLEMENTATION_SLOT)
        }
    }

    function version() public view virtual override returns (string memory) {
        return ItoA.itoa(_storageVersion());
    }

    function _setImplementation(address newImplementation) private {
        assembly ("memory-safe") {
            sstore(_IMPLEMENTATION_SLOT, and(0xffffffffffffffffffffffffffffffffffffffff, newImplementation))
        }
    }

    function _storageVersion() private view returns (uint256 result) {
        assembly ("memory-safe") {
            result := sload(_ROLLBACK_SLOT)
        }
    }

    function _setVersion(uint256 newVersion) private {
        assembly ("memory-safe") {
            sstore(_ROLLBACK_SLOT, newVersion)
        }
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override onlyProxy returns (bool) {
        return super.supportsInterface(interfaceId);
    }

    // This makes `onlyOwner` imply `onlyProxy`
    function owner() public view virtual override onlyProxy returns (address) {
        return super.owner();
    }

    function _initialize() internal virtual onlyProxy {
        // There is a separate, more lax version of this check in `_checkRollback`.
        if (_storageVersion() + 1 != _implVersion) {
            revert VersionMismatch(_storageVersion(), _implVersion);
        }
    }

    // This hook exists for schemes that append authenticated metadata to calldata
    // (e.g. ERC2771). If msg.sender during the upgrade call is the authenticator,
    // the metadata must be copied from the outer calldata into the delegatecall
    // calldata to ensure that any logic in the new implementation that inspects
    // msg.sender and decodes the authenticated metadata gets the correct result.
    function _encodeDelegateCall(bytes memory callData) internal view virtual returns (bytes memory) {
        return callData;
    }

    function _delegateCall(address impl, bytes memory data, bytes memory err) private returns (bytes memory) {
        (bool success, bytes memory returnData) = impl.delegatecall(_encodeDelegateCall(data));
        if (!success) {
            if (returnData.length > 0) {
                returnData._revert();
            } else {
                err._revert();
            }
        }
        return returnData;
    }

    function _checkRollback(address newImplementation, uint256 oldVersion, uint256 implVersion) private {
        if (oldVersion >= implVersion) {
            _delegateCall(
                newImplementation,
                abi.encodeCall(IERC1967Proxy.upgrade, (_implementation)),
                abi.encodeWithSelector(RollbackFailed.selector, _implementation, newImplementation)
            );
            if (implementation() != _implementation) {
                revert RollbackFailed(_implementation, implementation());
            }
            uint256 storageVersion = _storageVersion();
            if (storageVersion <= implVersion) {
                revert DidNotIncrementVersion(implVersion, storageVersion);
            }
            unchecked {
                // There is a separate, stricter version of this check in
                // `_initialize`. This preserves `upgrade` as an escape hatch
                // against botched upgrades.
                if (storageVersion - implVersion > _MAX_VERSION_INCREASE) {
                    revert IncrementedVersionTooMuch(implVersion, storageVersion);
                }
            }
            _setImplementation(newImplementation);
            emit Upgraded(newImplementation);
        }
    }

    /// @notice attempting to upgrade to a new implementation with a version
    ///         number that does not increase will result in infinite recursion
    ///         and a revert
    function upgrade(address newImplementation) public payable virtual override onlyOwner returns (bool) {
        uint256 oldVersion = _storageVersion();
        uint256 implVersion = _implVersion;
        _setImplementation(newImplementation);
        _setVersion(implVersion);
        _checkRollback(newImplementation, oldVersion, implVersion);
        return true;
    }

    /// @notice attempting to upgrade to a new implementation with a version
    ///         number that does not increase will result in infinite recursion
    ///         and a revert
    function upgradeAndCall(address newImplementation, bytes calldata data)
        public
        payable
        virtual
        override
        onlyOwner
        returns (bool)
    {
        uint256 oldVersion = _storageVersion();
        uint256 implVersion = _implVersion;
        _setImplementation(newImplementation);
        _delegateCall(newImplementation, data, abi.encodeWithSelector(InitializationFailed.selector));
        if (implementation() != newImplementation) {
            revert InterferedWithImplementation(newImplementation, implementation());
        }
        if (_storageVersion() != oldVersion) {
            revert InterferedWithVersion(oldVersion, _storageVersion());
        }
        _setVersion(implVersion);
        _checkRollback(newImplementation, oldVersion, implVersion);
        return true;
    }
}

abstract contract ERC1967OwnableStorage is OwnableStorageBase {
    uint256 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    function _ownerSlot() internal pure override returns (AddressSlot r) {
        assembly ("memory-safe") {
            r := _ADMIN_SLOT
        }
    }

    constructor() {
        assert(AddressSlot.unwrap(_ownerSlot()) == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
    }
}

abstract contract ERC1967OwnableImpl is OwnableImpl {
    event AdminChanged(address indexed prev, address indexed curr);

    function _setOwner(address newOwner) internal override {
        emit AdminChanged(owner(), newOwner);
        super._setOwner(newOwner);
    }
}

abstract contract ERC1967Ownable is ERC1967OwnableStorage, ERC1967OwnableImpl {}

abstract contract ERC1967TwoStepOwnableStorage is TwoStepOwnableStorageBase {
    // This slot is nonstandard, but follows a similar pattern to ERC1967
    uint256 private constant _PENDING_ADMIN_SLOT = 0x6ed8ad4e485c433a46d43a225e2ebe6a14259468c9e0ee3a0c38eefca7d49f56;

    function _pendingOwnerSlot() internal pure override returns (AddressSlot r) {
        assembly ("memory-safe") {
            r := _PENDING_ADMIN_SLOT
        }
    }

    constructor() {
        assert(
            AddressSlot.unwrap(_pendingOwnerSlot()) == bytes32(uint256(keccak256("eip1967.proxy.admin.pending")) - 1)
        );
    }
}

abstract contract ERC1967TwoStepOwnable is
    ERC1967OwnableStorage,
    ERC1967OwnableImpl,
    ERC1967TwoStepOwnableStorage,
    TwoStepOwnableImpl
{
    function renounceOwnership() public override(OwnableImpl, TwoStepOwnableImpl) returns (bool) {
        return TwoStepOwnableImpl.renounceOwnership();
    }

    function transferOwnership(address newOwner) public override(OwnableImpl, TwoStepOwnableImpl) returns (bool) {
        return TwoStepOwnableImpl.transferOwnership(newOwner);
    }
}

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

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

library UnsafeArray {
    function unsafeGet(bytes[] calldata datas, uint256 i) internal pure returns (bytes calldata data) {
        assembly ("memory-safe") {
            // helper functions
            function overflow() {
                mstore(0x00, 0x4e487b71) // keccak256("Panic(uint256)")[:4]
                mstore(0x20, 0x11) // 0x11 -> arithmetic under-/over- flow
                revert(0x1c, 0x24)
            }
            function bad_calldata() {
                revert(0x00, 0x00) // empty reason for malformed calldata
            }

            // initially, we set `data.offset` to the pointer to the length. this is 32 bytes before the actual start of data
            data.offset :=
                add(
                    datas.offset,
                    calldataload(
                        add(shl(5, i), datas.offset) // can't overflow; we assume `i` is in-bounds
                    )
                )
            // because the offset to `data` stored in `datas` is arbitrary, we have to check it
            if lt(data.offset, add(shl(5, datas.length), datas.offset)) { overflow() }
            if iszero(lt(data.offset, calldatasize())) { bad_calldata() }
            // now we load `data.length` and set `data.offset` to the start of datas
            data.length := calldataload(data.offset)
            data.offset := add(data.offset, 0x20) // can't overflow; calldata can't be that long
            {
                // check that the end of `data` is in-bounds
                let end := add(data.offset, data.length)
                if lt(end, data.offset) { overflow() }
                if gt(end, calldatasize()) { bad_calldata() }
            }
        }
    }
}

interface IMultiCall {
    function multicall(bytes[] calldata datas) external;
}

abstract contract MultiCallBase is IMultiCall {
    using UnsafeArray for bytes[];

    function _multicall(address target, bytes[] calldata datas) internal {
        uint256 freeMemPtr;
        assembly ("memory-safe") {
            freeMemPtr := mload(0x40)
        }
        unchecked {
            for (uint256 i; i < datas.length; i++) {
                (bool success, bytes memory reason) = target.delegatecall(datas.unsafeGet(i));
                Revert.maybeRevert(success, reason);
                assembly ("memory-safe") {
                    mstore(0x40, freeMemPtr)
                }
            }
        }
    }
}

abstract contract MultiCall is MultiCallBase {
    function multicall(bytes[] calldata datas) external override {
        _multicall(address(this), datas);
    }
}

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

library Panic {
    function panic(uint256 code) internal pure {
        assembly ("memory-safe") {
            mstore(0x00, 0x4e487b71) // selector for `Panic(uint256)`
            mstore(0x20, code)
            revert(0x1c, 0x24)
        }
    }

    // https://docs.soliditylang.org/en/latest/control-structures.html#panic-via-assert-and-error-via-require
    uint8 internal constant GENERIC = 0x00;
    uint8 internal constant ASSERT_FAIL = 0x01;
    uint8 internal constant ARITHMETIC_OVERFLOW = 0x11;
    uint8 internal constant DIVISION_BY_ZERO = 0x12;
    uint8 internal constant ENUM_CAST = 0x21;
    uint8 internal constant CORRUPT_STORAGE_ARRAY = 0x22;
    uint8 internal constant POP_EMPTY_ARRAY = 0x31;
    uint8 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
    uint8 internal constant OUT_OF_MEMORY = 0x41;
    uint8 internal constant ZERO_FUNCTION_POINTER = 0x51;
}

File 11 of 12 : Context.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

abstract contract AbstractContext {
    function _msgSender() internal view virtual returns (address);

    function _msgData() internal view virtual returns (bytes calldata);

    function _isForwarded() internal view virtual returns (bool);
}

abstract contract Context is AbstractContext {
    function _msgSender() internal view virtual override returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual override returns (bytes calldata) {
        return msg.data;
    }

    function _isForwarded() internal view virtual override returns (bool) {
        return false;
    }
}

File 12 of 12 : ItoA.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

library ItoA {
    function itoa(uint256 x) internal pure returns (string memory r) {
        assembly ("memory-safe") {
            mstore(9, 0x30313233343536373839) // lookup table [0..9]

            // we over-allocate memory here because that's cheaper than
            // computing the correct length and allocating exactly that much
            let end := add(mload(0x40), 0x6e)
            mstore(0x40, end)

            for {
                r := sub(end, 0x01)
                mstore8(r, mload(mod(x, 0x0a)))
                x := div(x, 0x0a)
            } x {} {
                r := sub(r, 0x01)
                mstore8(r, mload(mod(x, 0x0a)))
                x := div(x, 0x0a)
            }
            let length := sub(end, r)
            r := sub(r, 0x20)
            mstore(r, length)
        }
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_safe","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"contract IDeployer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"remove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"Feature","name":"","type":"uint128"},{"internalType":"Nonce","name":"","type":"uint32"}],"name":"remove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"Feature","name":"","type":"uint128"}],"name":"removeAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"safe","outputs":[{"internalType":"contract ISafeMinimal","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60a03460ae57601f61058b38819003918201601f19168301916001600160401b0383118484101760b25780849260209460405283398101031260ae57516001600160a01b0381169081900360ae57731cec01dc0ffee5eb5af47dbec1809f2a7c601c303014801560a4575b156090576080526040516104c490816100c782396080518181816101df01526102cf0152f35b634e487b7160e01b5f52600160045260245ffd5b50617a694614606a565b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040908082526004361015610014575f80fd5b5f3560e01c908163186f0354146101975750806329092d0e1461013d578063633a506c146100eb578063ada52c261461009e5763d5f3948814610055575f80fd5b3461009a575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a57602090516d04533fe15556b1e086bb1a72ceae8152f35b5f80fd5b503461009a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a576020906100d9610203565b506100e261029d565b90519015158152f35b503461009a57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a57610122610203565b5060243563ffffffff81160361009a576020906100e261029d565b503461009a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a5760043573ffffffffffffffffffffffffffffffffffffffff81160361009a576020906100e261029d565b3461009a575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a5760209073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b600435906fffffffffffffffffffffffffffffffff8216820361009a57565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761026357604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5190811515820361009a57565b604080517f2f54bf6e0000000000000000000000000000000000000000000000000000000081523360048201526020907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16908281602481855afa9081156104ba575f91610485575b501561009a578251907f5229073f0000000000000000000000000000000000000000000000000000000082526d04533fe15556b1e086bb1a72ceae60048301525f602483015260806044830152366084830152365f60a48401375f60a436840101525f827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092826064830152818360a48287601f36011681010301925af193841561047c575f925f956103f0575b505050156103ea57808280518101031261009a576103e79101610290565b90565b81519101fd5b91945091503d805f833e6104048183610222565b810191808284031261009a5761041982610290565b928483015167ffffffffffffffff9384821161009a57019181601f8401121561009a5782519384116102635785610458915197601f8601160187610222565b82865284838301011161009a57815f92858093018388015e850101525f80806103c9565b513d5f823e3d90fd5b90508281813d83116104b3575b61049c8183610222565b8101031261009a576104ad90610290565b5f61031b565b503d610492565b84513d5f823e3d90fd000000000000000000000000059bd6d6dde3769a7467fe21cc5a2c4c30d3dbfb

Deployed Bytecode

0x60806040908082526004361015610014575f80fd5b5f3560e01c908163186f0354146101975750806329092d0e1461013d578063633a506c146100eb578063ada52c261461009e5763d5f3948814610055575f80fd5b3461009a575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a57602090516d04533fe15556b1e086bb1a72ceae8152f35b5f80fd5b503461009a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a576020906100d9610203565b506100e261029d565b90519015158152f35b503461009a57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a57610122610203565b5060243563ffffffff81160361009a576020906100e261029d565b503461009a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a5760043573ffffffffffffffffffffffffffffffffffffffff81160361009a576020906100e261029d565b3461009a575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261009a5760209073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000059bd6d6dde3769a7467fe21cc5a2c4c30d3dbfb168152f35b600435906fffffffffffffffffffffffffffffffff8216820361009a57565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761026357604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5190811515820361009a57565b604080517f2f54bf6e0000000000000000000000000000000000000000000000000000000081523360048201526020907f000000000000000000000000059bd6d6dde3769a7467fe21cc5a2c4c30d3dbfb73ffffffffffffffffffffffffffffffffffffffff16908281602481855afa9081156104ba575f91610485575b501561009a578251907f5229073f0000000000000000000000000000000000000000000000000000000082526d04533fe15556b1e086bb1a72ceae60048301525f602483015260806044830152366084830152365f60a48401375f60a436840101525f827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe092826064830152818360a48287601f36011681010301925af193841561047c575f925f956103f0575b505050156103ea57808280518101031261009a576103e79101610290565b90565b81519101fd5b91945091503d805f833e6104048183610222565b810191808284031261009a5761041982610290565b928483015167ffffffffffffffff9384821161009a57019181601f8401121561009a5782519384116102635785610458915197601f8601160187610222565b82865284838301011161009a57815f92858093018388015e850101525f80806103c9565b513d5f823e3d90fd5b90508281813d83116104b3575b61049c8183610222565b8101031261009a576104ad90610290565b5f61031b565b503d610492565b84513d5f823e3d90fd

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

000000000000000000000000059bd6d6dde3769a7467fe21cc5a2c4c30d3dbfb

-----Decoded View---------------
Arg [0] : _safe (address): 0x059bD6D6DDE3769A7467fE21cC5a2C4c30D3dbfb

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000059bd6d6dde3769a7467fe21cc5a2c4c30d3dbfb


Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

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.