Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x4EC7b668BAF70d4A4b0FC7941a7708A07b6d45Be
Balance 0 ETH
Nonce 208
Code Size 2997 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

2997 bytes
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063a7e042b31161005b578063a7e042b3146100f6578063aefa7d981461010b578063b9caf9d91461011e578063f2fde38b1461015557600080fd5b8063798133dd146100825780638da5cb5b146100bf578063a09037a9146100df575b600080fd5b6100956100903660046109e7565b610168565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6000546100959073ffffffffffffffffffffffffffffffffffffffff1681565b6100e860025481565b6040519081526020016100b6565b610109610104366004610a7d565b6102d9565b005b610095610119366004610abb565b6103e0565b61014261012c366004610ad4565b60016020526000908152604090205461ffff1681565b60405161ffff90911681526020016100b6565b610109610163366004610ad4565b6103f2565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146101c95733600090815260016020819052604082208054919290916101ae90849061ffff16610b25565b92506101000a81548161ffff021916908361ffff1602179055505b60006002600081546101da90610b47565b918290555090506101ea816103e0565b915061022b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104e392505050565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461028f576040517fd1bf1e2d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051819073ffffffffffffffffffffffffffffffffffffffff8416907f511b2c8f5fa0dbd58000435f9f090fff2fea17afb6a93d4b42269e91fb8122bd90600090a35092915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526001602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff861690811790915590519092917fa31a54a42cb8a0d27fbdc5b388a008e53701c95de4a199f0ff33ac6929cd4e1c91a35050565b60006103ec308361057d565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610356565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b60008151600003610520576040517fd1bf1e2d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151602083016000f0905073ffffffffffffffffffffffffffffffffffffffff8116610578576040517fd1bf1e2d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60006060826000036105935760009150506103ec565b607f831161065c576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b16602282015260f884901b7fff000000000000000000000000000000000000000000000000000000000000001660368201526037015b60405160208183030381529060405290506109d8565b60ff8311610739576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f8100000000000000000000000000000000000000000000000000000000000000603682015260f884901b7fff00000000000000000000000000000000000000000000000000000000000000166037820152603801610646565b61ffff8311610817576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f085901b166037820152603901610646565b62ffffff83116108f6576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e885901b166037820152603a01610646565b6040517fda0000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e085901b166037820152603b0160405160208183030381529060405290505b80516020909101209392505050565b600080602083850312156109fa57600080fd5b823567ffffffffffffffff80821115610a1257600080fd5b818501915085601f830112610a2657600080fd5b813581811115610a3557600080fd5b866020828501011115610a4757600080fd5b60209290920196919550909350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461057857600080fd5b60008060408385031215610a9057600080fd5b610a9983610a59565b9150602083013561ffff81168114610ab057600080fd5b809150509250929050565b600060208284031215610acd57600080fd5b5035919050565b600060208284031215610ae657600080fd5b610aef82610a59565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff828116828216039080821115610b4057610b40610af6565b5092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610b7857610b78610af6565b506001019056fea264697066735822122055bc67eade8dc37e2ad0f7629834c10925fdbd79bff5de6072f4b7eda2400a2164736f6c63430008150033

Verified Source Code Full Match

Compiler: v0.8.21+commit.d9974bed EVM: paris Optimization: Yes (10000000 runs)
Owned.sol 44 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}
main.sol 90 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

import { Owned } from "solmate/src/auth/Owned.sol";

import { AddressCalcs } from "../libraries/addressCalcs.sol";

/// @title FluidContractFactory
/// @notice A contract that allows deployers to deploy any contract by passing the contract data in bytes
/// @dev The main objective of this contract is to avoid storing contract addresses in our protocols which requires 160 bits of storage
///      Instead, we can just store the nonce & deployment of this address to calculate the address realtime using "AddressCalcs" library
contract FluidContractFactory is Owned {
    /// @notice Thrown when an invalid operation is attempted
    error FluidContractFactory__InvalidOperation();

    /// @notice Emitted when a new contract is deployed
    /// @param addr The address of the deployed contract
    /// @param nonce The nonce used for deployment
    event LogContractDeployed(address indexed addr, uint256 indexed nonce);

    /// @notice Emitted when a deployer's count is updated
    /// @param deployer The address of the deployer
    /// @param count The new count for the deployer
    event LogUpdateDeployer(address indexed deployer, uint16 indexed count);

    /// @notice Mapping to store the deployment count for each deployer
    mapping(address => uint16) public deployer;

    /// @notice total number of contracts deployed
    uint256 public totalContracts;

    /// @notice Constructor to initialize the contract
    /// @param owner_ The address of the contract owner
    constructor(address owner_) Owned(owner_) {}

    /// @notice Updates the allowed deployments count for a specific deployer
    /// @param deployer_ The address of the deployer
    /// @param count_ The new count for the deployer
    /// @dev Only callable by the contract owner
    function updateDeployer(address deployer_, uint16 count_) public onlyOwner {
        deployer[deployer_] = count_;
        emit LogUpdateDeployer(deployer_, count_);
    }

    /// @notice Deploys a new contract
    /// @param contractCode_ The bytecode of the contract to deploy
    /// @return contractAddress_ The address of the deployed contract
    /// @dev Decrements the deployer's allowed deployments count if not the owner
    function deployContract(bytes calldata contractCode_) external returns (address contractAddress_) {
        if (msg.sender != owner) {
            // if deployer count is 0 then it'll underflow and hence solidity will throw error
            deployer[msg.sender] -= 1;
        }

        uint256 nonce_ = ++totalContracts;

        // compute contract address for nonce.
        contractAddress_ = getContractAddress(nonce_);

        if (contractAddress_ != _deploy(contractCode_)) {
            revert FluidContractFactory__InvalidOperation();
        }

        emit LogContractDeployed(contractAddress_, nonce_);
    }

    /// @notice Calculates the address of a contract for a given nonce
    /// @param nonce_ The nonce to use for address calculation
    /// @return contractAddress_ The calculated contract address
    function getContractAddress(uint256 nonce_) public view returns (address contractAddress_) {
        return AddressCalcs.addressCalc(address(this), nonce_);
    }

    /// @notice Internal function to deploy a contract
    /// @param bytecode_ The bytecode of the contract to deploy
    /// @return address_ The address of the deployed contract
    /// @dev Uses inline assembly for efficient deployment
    function _deploy(bytes memory bytecode_) internal returns (address address_) {
        if (bytecode_.length == 0) {
            revert FluidContractFactory__InvalidOperation();
        }
        /// @solidity memory-safe-assembly
        assembly {
            address_ := create(0, add(bytecode_, 0x20), mload(bytecode_))
        }
        if (address_ == address(0)) {
            revert FluidContractFactory__InvalidOperation();
        }
    }
}
addressCalcs.sol 35 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

/// @notice implements calculation of address for contracts deployed through CREATE.
/// Accepts contract deployed from which address & nonce
library AddressCalcs {

    /// @notice                         Computes the address of a contract based
    /// @param deployedFrom_            Address from which the contract was deployed
    /// @param nonce_                   Nonce at which the contract was deployed
    /// @return contract_               Address of deployed contract
    function addressCalc(address deployedFrom_, uint nonce_) internal pure returns (address contract_) {
        // @dev based on https://ethereum.stackexchange.com/a/61413

        // nonce of smart contract always starts with 1. so, with nonce 0 there won't be any deployment
        // hence, nonce of vault deployment starts with 1.
        bytes memory data;
        if (nonce_ == 0x00) {
            return address(0);
        } else if (nonce_ <= 0x7f) {
            data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployedFrom_, uint8(nonce_));
        } else if (nonce_ <= 0xff) {
            data = abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployedFrom_, bytes1(0x81), uint8(nonce_));
        } else if (nonce_ <= 0xffff) {
            data = abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployedFrom_, bytes1(0x82), uint16(nonce_));
        } else if (nonce_ <= 0xffffff) {
            data = abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployedFrom_, bytes1(0x83), uint24(nonce_));
        } else {
            data = abi.encodePacked(bytes1(0xda), bytes1(0x94), deployedFrom_, bytes1(0x84), uint32(nonce_));
        }

        return address(uint160(uint256(keccak256(data))));
    }

}

Read Contract

deployer 0xb9caf9d9 → uint16
getContractAddress 0xaefa7d98 → address
owner 0x8da5cb5b → address
totalContracts 0xa09037a9 → uint256

Write Contract 3 functions

These functions modify contract state and require a wallet transaction to execute.

deployContract 0x798133dd
bytes contractCode_
returns: address
transferOwnership 0xf2fde38b
address newOwner
updateDeployer 0xa7e042b3
address deployer_
uint16 count_

Recent Transactions

No transactions found for this address