Blockchain / Global / Address
Contract
0x2F96D7dD813b8e17071188791B78ea3FAb5c109C
- Balance
- 0 SOMI
- Transactions sent
- 214
- Type
- Contract · 2,799 bytes of code
DeployFactory Verified
- Compiler
- solc 0.8.20+commit.a1b79de6
- Language
- Solidity
- Optimization
- Yes, 200 runs
- EVM version
- london
- License
- —
- Verified
- 2026-10-12
contracts/DeployFactory_flattened.sol
Solidity
// SPDX-License-Identifier: MIT
// File: contracts/BasicContract.sol
pragma solidity ^0.8.20;
contract BasicContract {
address public owner;
constructor(address _owner) {
owner = _owner;
}
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: contracts/DeployFactory.sol
pragma solidity ^0.8.20;
contract DeployFactory is Ownable {
address public treasury;
uint256 public fee;
uint256 public referralFees;
uint256 public constant BASIS_POINTS = 10000;
struct DeploymentInfo {
address contractAddress;
uint256 deployedAt;
}
uint256 public totalDeployments;
mapping(address => DeploymentInfo[]) private userDeployments;
error InsufficientETH();
error ReferralTransferFailed();
error FeeTransferFailed();
error SelfReferral();
event ContractDeployed(address contractAddress, address owner);
constructor(address _treasury, uint256 _fee, uint256 _referralFees)
Ownable(msg.sender)
{
treasury = _treasury;
fee = _fee;
referralFees = _referralFees;
}
function deploy(address referral) external payable {
if (msg.value < fee) {
revert InsufficientETH();
}
if (referral == msg.sender) {
revert SelfReferral();
}
BasicContract newContract = new BasicContract(msg.sender);
DeploymentInfo memory info = DeploymentInfo({
contractAddress: address(newContract),
deployedAt: block.timestamp
});
userDeployments[msg.sender].push(info);
totalDeployments++;
uint256 referralAmount = 0;
if (referral != address(0)) {
referralAmount = (msg.value * referralFees) / BASIS_POINTS;
(bool refSuccess, ) = referral.call{value: referralAmount}("");
if (!refSuccess) {
revert ReferralTransferFailed();
}
}
uint256 remaining = msg.value - referralAmount;
(bool success, ) = treasury.call{value: remaining}("");
if (!success) {
revert FeeTransferFailed();
}
emit ContractDeployed(address(newContract), msg.sender);
}
/**
* @dev Returns all deployment information for a specific user
* @param user The address of the user whose deployments to fetch
* @return DeploymentInfo[] Array of deployment information
*/
function getUserDeployments(
address user
) external view returns (DeploymentInfo[] memory) {
return userDeployments[user];
}
/**
* @dev Returns the timestamp of the user's latest deployment or 0 if none exists
* @param user The address of the user
* @return uint256 Timestamp of the last deployment
*/
function getLastDeploymentTime(
address user
) external view returns (uint256) {
DeploymentInfo[] memory userDeploys = userDeployments[user];
if (userDeploys.length == 0) {
return 0;
}
return userDeploys[userDeploys.length - 1].deployedAt;
}
function setTreasury(address _treasury) external onlyOwner {
require(_treasury != address(0), "Invalid treasury address");
treasury = _treasury;
}
function setFee(uint256 _fee) external onlyOwner {
require(_fee > 0, "Invalid fee");
fee = _fee;
}
function setReferralFees(uint256 _referralFees) external onlyOwner {
require(_referralFees < BASIS_POINTS, "Invalid referral fees");
referralFees = _referralFees;
}
}
ABI · 23 entries
json
[
{
"type": "constructor",
"inputs": [
{
"name": "_treasury",
"type": "address",
"internalType": "address"
},
{
"name": "_fee",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_referralFees",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "FeeTransferFailed",
"type": "error",
"inputs": []
},
{
"name": "InsufficientETH",
"type": "error",
"inputs": []
},
{
"name": "OwnableInvalidOwner",
"type": "error",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "OwnableUnauthorizedAccount",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ReferralTransferFailed",
"type": "error",
"inputs": []
},
{
"name": "SelfReferral",
"type": "error",
"inputs": []
},
{
"name": "ContractDeployed",
"type": "event",
"inputs": [
{
"name": "contractAddress",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "owner",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "BASIS_POINTS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "deploy",
"type": "function",
"inputs": [
{
"name": "referral",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "fee",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "getLastDeploymentTime",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "getUserDeployments",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "tuple[]",
"components": [
{
"name": "contractAddress",
"type": "address",
"internalType": "address"
},
{
"name": "deployedAt",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct DeployFactory.DeploymentInfo[]"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "referralFees",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setFee",
"type": "function",
"inputs": [
{
"name": "_fee",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setReferralFees",
"type": "function",
"inputs": [
{
"name": "_referralFees",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setTreasury",
"type": "function",
"inputs": [
{
"name": "_treasury",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "totalDeployments",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "treasury",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
}
]