Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions script/DeployBrokerTokenFactory.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
pragma solidity ^0.8.24;

import {Script, console} from "forge-std/Script.sol";
import {BrokerTokenFactory} from "../src/BrokerTokenFactory.sol";

contract DeployBrokerTokenFactory is Script {
function run() public {
string memory ownerStr = vm.envString("ERC20_FACTORY_OWNER");
address owner = vm.parseAddress(ownerStr);

vm.startBroadcast(); // start broadcasting transactions to the blockchain
BrokerTokenFactory factory = new BrokerTokenFactory(owner);
vm.stopBroadcast();

console.log("BrokerToken Factory address: %s", address(factory));
}
}
1 change: 1 addition & 0 deletions src/BrokerToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ contract BrokerToken is ERC20Permit {
* Mints the supply to the deployer.
* @param name Name of the Token.
* @param symbol Symbol of the Token.
* @param decimals_ Number of decimals of the Token.
* @param supply Maximum supply of the Token.
*/
constructor(string memory name, string memory symbol, uint8 decimals_, uint256 supply)
Expand Down
56 changes: 56 additions & 0 deletions src/BrokerTokenFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./BrokerToken.sol";

/**
* @title BrokerTokenFactory
* @notice Factory contract to create new instances of BrokerToken.
* Only the owner can create new tokens.
*/
contract BrokerTokenFactory is Ownable {
// Array to store addresses of created tokens
address[] public brokerTokens;

/**
* @notice Event emitted when a new BrokerToken is created.
* @param tokenAddress Address of the newly created BrokerToken.
*/
event BrokerTokenCreated(address indexed tokenAddress);

constructor(address owner) Ownable(owner) {}

/**
* @notice Creates a new BrokerToken and mints the supply to the factory owner.
* @param name Name of the Token.
* @param symbol Symbol of the Token.
* @param supply Maximum supply of the Token.
*/
function createBrokerToken(string memory name, string memory symbol, uint8 decimals, uint256 supply)
external
onlyOwner
{
BrokerToken token = new BrokerToken(name, symbol, decimals, supply);
brokerTokens.push(address(token));
emit BrokerTokenCreated(address(token));
}

/**
* @notice Returns the number of created BrokerTokens.
* @return uint256 Number of created BrokerTokens.
*/
function getBrokerTokensCount() external view returns (uint256) {
return brokerTokens.length;
}

/**
* @notice Returns the address of a created BrokerToken at a given index.
* @param index Index of the token in the brokerTokens array.
* @return address Address of the BrokerToken.
*/
function getBrokerToken(uint256 index) external view returns (address) {
require(index < brokerTokens.length, "Index out of bounds");
return brokerTokens[index];
}
}
88 changes: 88 additions & 0 deletions test/BrokerTokenFactory.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;

import "forge-std/Test.sol";
import "../src/BrokerTokenFactory.sol";
import "../src/BrokerToken.sol";

contract BrokerTokenFactoryTest is Test {
BrokerTokenFactory factory;
address owner;

function setUp() public {
owner = address(this);
vm.deal(owner, 100 ether);
factory = new BrokerTokenFactory(owner);
}

function testCreateBrokerToken() public {
string memory name = "BrokerToken";
string memory symbol = "BTK";
uint8 decimals = 8;
uint256 supply = 1000 * 10 ** 8;

// Ensure only the owner can create tokens
vm.prank(owner);
factory.createBrokerToken(name, symbol, decimals, supply);

// Check if the token was created
assertEq(factory.getBrokerTokensCount(), 1);

address tokenAddress = factory.getBrokerToken(0);
BrokerToken token = BrokerToken(tokenAddress);

// Validate the token's properties
assertEq(token.name(), name);
assertEq(token.symbol(), symbol);
assertEq(token.totalSupply(), supply);
assertEq(token.decimals(), 8);
}

function testFailNonOwnerCannotCreateBrokerToken() public {
string memory name = "BrokerToken";
string memory symbol = "BTK";
uint8 decimals = 8;
uint256 supply = 1000 * 10 ** 8;

// Try to create a token with a different address
vm.prank(address(0x1234));
vm.expectRevert("Ownable: caller is not the owner");
factory.createBrokerToken(name, symbol, decimals, supply);
}

function testGetBrokerToken() public {
string memory name = "BrokerToken";
string memory symbol = "BTK";
uint8 decimals = 8;
uint256 supply = 1000 * 10 ** 8;

vm.prank(owner);
factory.createBrokerToken(name, symbol, decimals, supply);

address tokenAddress = factory.getBrokerToken(0);
BrokerToken token = BrokerToken(tokenAddress);

// Validate the token address
assertEq(address(token), tokenAddress);
}

function testBrokerTokensCount() public {
string memory name1 = "BrokerToken1";
string memory symbol1 = "BTK1";
uint8 decimals1 = 8;
uint256 supply1 = 1000 * 10 ** 8;

string memory name2 = "BrokerToken2";
string memory symbol2 = "BTK2";
uint8 decimals2 = 8;
uint256 supply2 = 2000 * 10 ** 8;

vm.prank(owner);
factory.createBrokerToken(name1, symbol1, decimals1, supply1);
vm.prank(owner);
factory.createBrokerToken(name2, symbol2, decimals2, supply2);

// Validate the number of created tokens
assertEq(factory.getBrokerTokensCount(), 2);
}
}