Skip to content

Commit cb1a526

Browse files
committed
new hierachy: ServiceManager - ServiceController - Service - Instance
Signed-off-by: Alexander Diemand <codieplusplus@apax.net>
1 parent 216062a commit cb1a526

File tree

7 files changed

+114
-38
lines changed

7 files changed

+114
-38
lines changed

bca-token-solidity/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ npx hardhat node
2323
in the other deploy the contract
2424
```sh
2525
npx hardhat ignition deploy ignition/modules/BCA_Token.ts --network localhost
26-
npx hardhat ignition deploy ignition/modules/BCA_Service.ts --network localhost
26+
npx hardhat ignition deploy ignition/modules/BCA_ServiceManager.ts --network localhost
2727
```
2828

2929
#### Connect metamask to local node
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity ^0.8.24;
3+
4+
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5+
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
6+
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
7+
import "./Iface_ServiceController.sol";
8+
import "./BCA_Service.sol";
9+
10+
// Factory contract that deploys service contracts
11+
contract BCAServiceController is IServiceController, ReentrancyGuard {
12+
using SafeERC20 for IERC20;
13+
14+
IERC20 public immutable tokToken;
15+
address public immutable providerAddress;
16+
address[] public deployedServices;
17+
18+
// Event to notify when a new service is deployed
19+
event ServiceDeployed(address contractAddress);
20+
21+
constructor(address setProviderAddress, address tokAddress) {
22+
require(setProviderAddress != address(0), "Invalid provider address");
23+
require(tokAddress != address(0), "Invalid token address");
24+
25+
tokToken = IERC20(tokAddress);
26+
providerAddress = setProviderAddress;
27+
}
28+
29+
function newService(uint16 maxInstances, uint256 dayPrice) external nonReentrant returns (address) {
30+
// Create a new SimpleContract
31+
BCAService serviceContract = new BCAService(providerAddress, address(tokToken), maxInstances, dayPrice);
32+
33+
// Store the address
34+
deployedServices.push(address(serviceContract));
35+
36+
// Emit event
37+
emit ServiceDeployed(address(serviceContract));
38+
39+
return address(serviceContract);
40+
}
41+
42+
function countServiceContracts() public view returns (uint) {
43+
return deployedServices.length;
44+
}
45+
}

bca-token-solidity/contracts/BCA_ServiceManager.sol

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,56 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
55
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
66
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
77
import "./Iface_ServiceManager.sol";
8-
import "./BCA_Service.sol";
8+
import "./BCA_ServiceController.sol";
99

1010
// Factory contract that deploys service contracts
1111
contract BCAServiceManager is IServiceManager, ReentrancyGuard {
1212
using SafeERC20 for IERC20;
1313

1414
IERC20 public immutable tokToken;
15-
address public immutable providerAddress;
16-
address[] public deployedServices;
15+
16+
struct ControllerStruct {
17+
address addrContract;
18+
bool isDeployed;
19+
}
20+
mapping (address => ControllerStruct) public deployedControllers;
21+
address[] public addressControllers;
1722

1823
// Event to notify when a new service is deployed
19-
event ServiceDeployed(address contractAddress);
24+
event ControllerDeployed(address contractAddress);
2025

21-
constructor(address setProviderAddress, address tokAddress) {
22-
require(setProviderAddress != address(0), "Invalid provider address");
26+
constructor(address tokAddress) {
2327
require(tokAddress != address(0), "Invalid token address");
2428

2529
tokToken = IERC20(tokAddress);
26-
providerAddress = setProviderAddress;
2730
}
2831

29-
function newService(uint16 maxInstances, uint256 dayPrice) external nonReentrant returns (address) {
32+
function getControllerAddress(address providerAddress) public view returns(address addrController) {
33+
require (deployedControllers[providerAddress].isDeployed == true, "no controller for this provider");
34+
return deployedControllers[providerAddress].addrContract;
35+
}
36+
37+
function isDeployed(address providerAddress) public view returns(bool isdeployed) {
38+
if (addressControllers.length == 0) return false;
39+
return (deployedControllers[providerAddress].isDeployed);
40+
}
41+
42+
function newController(address providerAddress) external nonReentrant {
43+
require(! isDeployed(providerAddress), "already deployed controller for this provider");
44+
3045
// Create a new SimpleContract
31-
BCAService serviceContract = new BCAService(providerAddress, address(tokToken), maxInstances, dayPrice);
46+
BCAServiceController controllerContract = new BCAServiceController(providerAddress, address(tokToken));
3247

3348
// Store the address
34-
deployedServices.push(address(serviceContract));
49+
addressControllers.push(address(controllerContract));
50+
deployedControllers[providerAddress].addrContract = address(controllerContract);
51+
deployedControllers[providerAddress].isDeployed = true;
3552

3653
// Emit event
37-
emit ServiceDeployed(address(serviceContract));
38-
39-
return address(serviceContract);
54+
emit ControllerDeployed(address(controllerContract));
4055
}
41-
42-
function countServiceContracts() public view returns (uint) {
43-
return deployedServices.length;
56+
57+
function countServiceControllers() public view returns (uint) {
58+
return addressControllers.length;
4459
}
4560
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity ^0.8.24;
3+
4+
interface IServiceController {
5+
function newService(uint16 _maxInstances, uint256 _dayPrice) external returns (address);
6+
}

bca-token-solidity/contracts/Iface_ServiceManager.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
pragma solidity ^0.8.24;
33

44
interface IServiceManager {
5-
function newService(uint16 _maxInstances, uint256 _dayPrice) external returns (address);
5+
function newController(address providerAddress) external;
66
}

bca-token-solidity/ignition/modules/BCA_ServiceManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ let provider = "0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199"
1212

1313
const BCAServiceManagerModule = buildModule("BCA_ServiceManager", (m) => {
1414

15-
const bcasrvmgr = m.contract("BCAServiceManager", [provider, deployed_address["BCA_Token#BCAServiceToken"]]);
15+
const bcasrvmgr = m.contract("BCAServiceManager", [deployed_address["BCA_Token#BCAServiceToken"]]);
1616

1717
return { bcasrvmgr };
1818
});

bca-token-solidity/test/BCA_ServiceManager.ts

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ import {
1818
const tokenContract = await Token.deploy("Test token", "TOK1", minter, burner);
1919
const precision: bigint = await tokenContract.decimals().then(d => { if (d == 0n) {return 18n;} else {return d}; });
2020

21-
const Contract1 = await hre.ethers.getContractFactory("BCAServiceManager");
22-
const serviceManager1 = await Contract1.deploy(provider1, tokenContract.getAddress());
21+
const Manager = await hre.ethers.getContractFactory("BCAServiceManager");
22+
const serviceManager = await Manager.deploy(tokenContract.getAddress());
2323

24-
const Contract2 = await hre.ethers.getContractFactory("BCAServiceManager");
25-
const serviceManager2 = await Contract1.deploy(provider2, tokenContract.getAddress());
24+
const addrController1 = await (await serviceManager.connect(owner).newController(provider1)).wait().then(_ => serviceManager.connect(owner).getControllerAddress(provider1));
25+
const serviceController1 = await hre.ethers.getContractAt("BCAServiceController", addrController1)
26+
const addrController2 = await (await serviceManager.connect(owner).newController(provider2)).wait().then(_ => serviceManager.connect(owner).getControllerAddress(provider2));
27+
const serviceController2 = await hre.ethers.getContractAt("BCAServiceController", addrController2)
2628

2729
// minting some tokens to the users
2830
const one_token = 1n * BigInt(10n**precision);
@@ -34,35 +36,43 @@ import {
3436
const startblocktime: bigint = BigInt(await time.increase(30));
3537

3638
return { token: { tokenContract, one_token, owner, minter, burner, user1, user2 },
37-
sm1: { serviceManager1, provider1 },
38-
sm2: { serviceManager2, provider2 } };
39+
sm: { serviceManager, provider1, provider2 },
40+
sc1: { serviceController1, provider1 },
41+
sc2: { serviceController2, provider2 } };
3942
}
4043

4144
describe("Deployment", function () {
42-
it("Funding contract: should set the right provider", async function () {
43-
const { sm1 } = await loadFixture(deployContract);
44-
expect(await sm1.serviceManager1.providerAddress()).to.equal(
45-
sm1.provider1.address
45+
it("Should have already deployed controllers", async function () {
46+
const { sm } = await loadFixture(deployContract);
47+
expect(await sm.serviceManager.countServiceControllers()).to.equal(
48+
2
4649
);
4750
});
4851

49-
it("Funding contract: should set the right provider", async function () {
50-
const { sm2 } = await loadFixture(deployContract);
51-
expect(await sm2.serviceManager2.providerAddress()).to.equal(
52-
sm2.provider2.address
52+
it("Should set the right provider", async function () {
53+
const { sc1 } = await loadFixture(deployContract);
54+
expect(await sc1.serviceController1.providerAddress()).to.equal(
55+
sc1.provider1.address
56+
);
57+
});
58+
59+
it("Should set the right provider", async function () {
60+
const { sc2 } = await loadFixture(deployContract);
61+
expect(await sc2.serviceController2.providerAddress()).to.equal(
62+
sc2.provider2.address
5363
);
5464
});
5565
});
5666

5767
describe("Create new services", function () {
5868
it("Should emit ServiceDeployed on new service creation", async function () {
59-
const { sm1, sm2 } = await loadFixture(deployContract);
69+
const { sc1, sc2 } = await loadFixture(deployContract);
6070

61-
await expect(sm1.serviceManager1.connect(sm1.provider1).newService(3, 1n * 10n**18n))
62-
.to.emit(sm1.serviceManager1, "ServiceDeployed")
71+
await expect(sc1.serviceController1.connect(sc1.provider1).newService(3, 1n * 10n**18n))
72+
.to.emit(sc1.serviceController1, "ServiceDeployed")
6373
.withArgs(anyValue);
64-
await expect(sm2.serviceManager2.connect(sm2.provider2).newService(99, 1n * 10n**18n / 10n))
65-
.to.emit(sm2.serviceManager2, "ServiceDeployed")
74+
await expect(sc2.serviceController2.connect(sc2.provider2).newService(99, 1n * 10n**18n / 10n))
75+
.to.emit(sc2.serviceController2, "ServiceDeployed")
6676
.withArgs(anyValue);
6777
});
6878

0 commit comments

Comments
 (0)