Contract Name:
FabricContract
Contract Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
interface IChildContract {
function mint(address to) external;
function withdraw() external;
function transferOwnership(address newOwner) external;
}
interface ITargetContract {
function mint(uint256 payableAmount, uint256 tokens) external payable;
}
contract FabricContract {
address[] public childContracts;
address public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_;
}
event ChildContractDeployed(address indexed childAddress);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event FundsWithdrawn(address indexed to, uint256 amount);
constructor() {
owner = msg.sender;
}
function createChildContracts(uint256 count) external onlyOwner {
for (uint256 i = 0; i < count; i++) {
ChildContract child = new ChildContract(owner);
childContracts.push(address(child));
emit ChildContractDeployed(address(child));
}
}
function mintFromChildren(address targetContract, uint256 mintCost) external onlyOwner payable {
require(address(this).balance >= mintCost * childContracts.length, "Insufficient funds in FabricContract");
uint256 childMintCost = mintCost;
for (uint256 i = 0; i < childContracts.length; i++) {
address child = childContracts[i];
// Отправляем средства на дочерний контракт
(bool sent, ) = payable(child).call{value: childMintCost}("");
require(sent, "Failed to send funds to child contract");
// Вызываем функцию mint на целевом контракте от имени дочернего контракта
(bool success, ) = child.call(
abi.encodeWithSignature("mint(address)", targetContract)
);
require(success, "Mint failed for one of the child contracts");
// Возвращаем остаток средств на FabricContract
IChildContract(child).withdraw();
}
}
function getChildContracts() external view returns (address[] memory) {
return childContracts;
}
function withdrawFunds() external onlyOwner {
uint256 balance = address(this).balance;
require(balance > 0, "No funds to withdraw");
(bool success, ) = payable(owner).call{value: balance}("");
require(success, "Withdraw failed");
emit FundsWithdrawn(owner, balance);
}
// Функция для получения эфира на контракт
receive() external payable {}
}
contract ChildContract is IChildContract {
address public owner;
uint256 public tokenId;
mapping(uint256 => address) private tokenOwners;
event Mint(address indexed to, uint256 tokenId);
event Transfer(address indexed from, address indexed to, uint256 tokenId);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_;
}
constructor(address _owner) {
owner = _owner;
tokenId = 0;
}
function mint(address to) external onlyOwner override {
tokenId++;
tokenOwners[tokenId] = to;
emit Mint(to, tokenId);
}
function transfer(address to, uint256 _tokenId) external {
require(tokenOwners[_tokenId] == msg.sender, "Not the token owner");
require(to != address(0), "Invalid recipient");
tokenOwners[_tokenId] = to;
emit Transfer(msg.sender, to, _tokenId);
}
function ownerOf(uint256 _tokenId) external view returns (address) {
return tokenOwners[_tokenId];
}
function withdraw() external onlyOwner override {
uint256 balance = address(this).balance;
require(balance > 0, "No funds to withdraw");
(bool success, ) = payable(owner).call{value: balance}("");
require(success, "Transfer failed");
}
function transferOwnership(address newOwner) external onlyOwner override {
require(newOwner != address(0), "New owner is the zero address");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
receive() external payable {}
}