Address Contract Verified
Address
0x4EC7b668BAF70d4A4b0FC7941a7708A07b6d45Be
Balance
0 ETH
Nonce
208
Code Size
2997 bytes
Creator
Create2 Deployer at tx 0x8f16cc80...47207a
Indexed Transactions
0
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