Skip to Content
CFPContract ReferenceFactory Source

CrowdFi V1 Factory Source

// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "@openzeppelin/contracts/proxy/Clones.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./CrowdFinancingV1.sol"; /** * * @title Fabric CrowdFinancing Factory Contract * @author Fabric Inc. * * @dev A factory which leverages Clones to deploy Fabric CrowdFinancing contracts * */ contract CrowdFinancingV1Factory is Ownable { modifier feeRequired() { require(msg.value >= _feeDeployMin, "Insufficient ETH to deploy"); _; } /// @dev Emitted upon a successful Campaign deployment event Deployment(address indexed deployment); /// @dev Emitted when the fee collector or schedule changes event FeeScheduleChange(address feeCollector, uint16 upfrontBips, uint16 payoutBips); /// @dev Emitted when the creation fee minium changes event DeployFeeChange(uint256 fee); /// @dev Emitted when the deploy fees are collected by the owner event DeployFeeTransfer(address indexed recipient, uint256 fee); /// @dev The campaign contract implementation address address immutable _implementation; /// @dev The fee collector address (can be 0, no fees are collected) address private _feeCollector; /// @dev The transfer fee (See CrowdFinancingV1) uint16 private _feeTransferBips; /// @dev The yield fee (See CrowdFinancingV1) uint16 private _feeYieldBips; /// @dev Fee to collect upon deployment uint256 private _feeDeployMin; /** * @param implementation the CrowdFinancingV1 implementation address */ constructor(address implementation) Ownable() { _implementation = implementation; _feeCollector = address(0); _feeTransferBips = 0; _feeYieldBips = 0; _feeDeployMin = 0; } /** * @dev Deploys a new CrowdFinancingV1 contract * * @param recipient the address of the recipient, to which funds can be transferred after success * @param minGoal the minimum funding amount acceptable for a successful campaign * @param maxGoal the maximum funding amount accepted for the financing round * @param minContribution the minimum initial contribution an account can make * @param maxContribution the maximum contribution an account can make * @param holdOff the number of seconds to wait until the campaign starts * @param duration the runtime of the campaign, in seconds * @param erc20TokenAddr the address of the ERC20 token used for payments, or the 0 address for native token * * @return the address of the deployed CrowdFinancingV1 contract */ function deployCampaign( address recipient, uint256 minGoal, uint256 maxGoal, uint256 minContribution, uint256 maxContribution, uint32 holdOff, uint32 duration, address erc20TokenAddr ) external payable feeRequired returns (address) { address deployment = Clones.clone(_implementation); uint256 startTimestamp = block.timestamp + holdOff; uint256 endTimestamp = startTimestamp + duration; CrowdFinancingV1(deployment).initialize( recipient, minGoal, maxGoal, minContribution, maxContribution, startTimestamp, endTimestamp, erc20TokenAddr, _feeCollector, _feeTransferBips, _feeYieldBips ); emit Deployment(deployment); return deployment; } /** * @dev Owner Only: Transfer accumulated fees */ function transferDeployFees(address recipient) external onlyOwner { uint256 amount = address(this).balance; require(amount > 0, "No fees to collect"); emit DeployFeeTransfer(recipient, amount); (bool sent,) = payable(recipient).call{value: amount}(""); require(sent, "Failed to transfer Ether"); } /** * @dev Owner Only: Update the fee schedule for future deployments * * @param feeCollector the address of the fee collector, or the 0 address if no fees are collected * @param feeTransferBips the upfront fee in basis points, calculated during processing * @param feeYieldBips the payout fee in basis points. Dilutes the cap table for fee collection */ function updateFeeSchedule(address feeCollector, uint16 feeTransferBips, uint16 feeYieldBips) external onlyOwner { _feeCollector = feeCollector; _feeTransferBips = feeTransferBips; _feeYieldBips = feeYieldBips; emit FeeScheduleChange(feeCollector, feeTransferBips, feeYieldBips); } /** * @dev Owner Only: Update the deploy fee. * * @param minFeeAmount the amount of wei required to deploy a campaign */ function updateMinimumDeployFee(uint256 minFeeAmount) external onlyOwner { _feeDeployMin = minFeeAmount; emit DeployFeeChange(minFeeAmount); } /** * @dev Fetch the fee schedule for campaigns and the deploy fee * * @return collector the address of the fee collector, or the 0 address if no fees are collected * @return transferFee the upfront fee in basis points, calculated during transfer * @return yieldFee the payout fee in basis points. Dilutes the cap table for fee collection * @return deployFee the amount of wei required to deploy a campaign */ function feeSchedule() external view returns (address collector, uint16 transferFee, uint16 yieldFee, uint256 deployFee) { return (_feeCollector, _feeTransferBips, _feeYieldBips, _feeDeployMin); } }
Last updated on