diff --git a/src/spotlight-token-factory/ISpotlightTokenFactory.sol b/src/spotlight-token-factory/ISpotlightTokenFactory.sol index 18b4286..a5b45c4 100644 --- a/src/spotlight-token-factory/ISpotlightTokenFactory.sol +++ b/src/spotlight-token-factory/ISpotlightTokenFactory.sol @@ -2,6 +2,13 @@ pragma solidity ^0.8.13; interface ISpotlightTokenFactory { + /** + * @dev Returns the address of the token collection contract + */ + function tokenCollection() external view returns (address); + + /** + */ function calculateTokenAddress(address tokenCreator, string memory tokenName, string memory tokenSymbol) external returns (address); diff --git a/src/spotlight-token-factory/SpotlightTokenFactory.sol b/src/spotlight-token-factory/SpotlightTokenFactory.sol index 35448ab..ee5bc7a 100644 --- a/src/spotlight-token-factory/SpotlightTokenFactory.sol +++ b/src/spotlight-token-factory/SpotlightTokenFactory.sol @@ -3,13 +3,60 @@ pragma solidity ^0.8.13; import {ISpotlightTokenFactory} from "./ISpotlightTokenFactory.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SpotlightToken} from "../spotlight-token/SpotlightToken.sol"; +import {SpotlightTokenCollection} from "../spotlight-token-collection/SpotlightTokenCollection.sol"; contract SpotlightTokenFactory is Ownable, ISpotlightTokenFactory { - uint256 private _CREATE_TOKNE_FEE; + uint256 private _createTokenFee = 0; + address private _feeTokenAddress; + IERC20 private _feeToken; + + SpotlightTokenCollection private _tokenCollection; + address private _tokenCollectionAddress; + mapping(address => uint256) private _numbersOfTokensCreated; - constructor() Ownable(msg.sender) {} + constructor(uint256 createTokenFee_, address feeToken_) Ownable(msg.sender) { + _createTokenFee = createTokenFee_; + _feeTokenAddress = feeToken_; + _feeToken = IERC20(feeToken_); + _tokenCollection = new SpotlightTokenCollection( + msg.sender, // owner + address(this) // token factory + ); + _tokenCollectionAddress = address(_tokenCollection); + } + + function tokenCollection() public view returns (address) { + return _tokenCollectionAddress; + } + + function setTokenCollection(address newTokenCollection) external onlyOwner { + _tokenCollectionAddress = newTokenCollection; + _tokenCollection = SpotlightTokenCollection(newTokenCollection); + } + + function createTokenFee() public returns (uint256) { + return _createTokenFee; + } + + function setCreateTokenFee(uint256 newFee) external onlyOwner { + _createTokenFee = newFee; + } + + function feeToken() public returns (address) { + return _feeTokenAddress; + } + + function setFeeToken(address newToken) external onlyOwner { + _feeTokenAddress = newToken; + _feeToken = IERC20(newToken); + } + + function numberOfTokensCreated(address tokenCreator) external view returns (uint256) { + return _numbersOfTokensCreated[tokenCreator]; + } function calculateTokenAddress(address tokenCreator, string memory tokenName, string memory tokenSymbol) external @@ -22,24 +69,31 @@ contract SpotlightTokenFactory is Ownable, ISpotlightTokenFactory { return address(uint160(uint256(calculatedHash))); } - function numberOfTokensCreated(address tokenCreator) external view returns (uint256) { - return _numbersOfTokensCreated[tokenCreator]; - } - function createToken(string memory tokenName_, string memory tokenSymbol_, address predeployedTokenAddress) external returns (address) { + // todo: charge fee + + // deply spotlight token SpotlightToken token = new SpotlightToken{salt: _slat(msg.sender)}(address(this), msg.sender, tokenName_, tokenSymbol_); if (address(token) != predeployedTokenAddress) { revert("The address of the created token does not match the predeployed address"); } + // mint spotlight token nft + uint256 spotlightTokenNFTId = _tokenCollection.mint(msg.sender); + + // register ip and set meta data + + // return and emit event + _numbersOfTokensCreated[msg.sender] += 1; return address(token); } + // @dev Private functions function _tokenCreateBytecode(address tokenCreator, string memory tokenName, string memory tokenSymbol) internal view diff --git a/test/SpotlightTokenFactoryTest.t.sol b/test/SpotlightTokenFactoryTest.t.sol index a2b5e0a..3c16da9 100644 --- a/test/SpotlightTokenFactoryTest.t.sol +++ b/test/SpotlightTokenFactoryTest.t.sol @@ -2,8 +2,9 @@ pragma solidity ^0.8.13; import "../lib/forge-std/src/Test.sol"; -import {SpotlightTokenFactory} from "../src/spotlight-token-factory/SpotlightTokenFactory.sol"; import {SpotlightToken} from "../src/spotlight-token/SpotlightToken.sol"; +import {SpotlightTokenCollection} from "../src/spotlight-token-collection/SpotlightTokenCollection.sol"; +import {SpotlightTokenFactory} from "../src/spotlight-token-factory/SpotlightTokenFactory.sol"; contract SpotlightTokenFactoryTest is Test { address private _factoryOwner; @@ -11,16 +12,26 @@ contract SpotlightTokenFactoryTest is Test { SpotlightTokenFactory private _factory; address private _factoryAddress; + SpotlightTokenCollection private _tokenCollection; + address private _tokenCollectionAddress; + function setUp() public { _factoryOwner = makeAddr("factoryOwner"); vm.startPrank(_factoryOwner); - _factory = new SpotlightTokenFactory(); + _factory = new SpotlightTokenFactory(0, address(0)); _factoryAddress = address(_factory); vm.stopPrank(); + + _tokenCollectionAddress = _factory.tokenCollection(); + _tokenCollection = SpotlightTokenCollection(_tokenCollectionAddress); + + vm.startPrank(_factoryOwner); + _tokenCollection.setMintEnabled(true); + vm.stopPrank(); } - function testCreateTokneAddress() public { + function testCreateToken() public { address tokenCreator = makeAddr("tokenCreator"); uint256 numberOfTokensCreatedBefore = _factory.numberOfTokensCreated(tokenCreator);