Skip to content

Commit 1424330

Browse files
committed
Distributors now use own ids for distributions that are keccak(distributionId,initializerId)
1 parent a4196a7 commit 1424330

File tree

4 files changed

+60
-40
lines changed

4 files changed

+60
-40
lines changed

src/abstracts/Distributor.sol

+30-20
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ import "../interfaces/IDistributor.sol";
66
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
77
import "../interfaces/IInitializer.sol";
88
import "../abstracts/CodeIndexer.sol";
9-
109
abstract contract Distributor is IDistributor, CodeIndexer {
10+
11+
struct DistributionComponent {
12+
bytes32 id;
13+
address initializer;
14+
}
1115
using EnumerableSet for EnumerableSet.Bytes32Set;
1216
EnumerableSet.Bytes32Set private distirbutionsSet;
1317
mapping(bytes32 => IInitializer) private initializers;
1418
mapping(address => bytes32) private distributionOf;
19+
mapping(bytes32 => DistributionComponent) private distributionComponents;
1520

1621
function getDistributions() public view returns (bytes32[] memory) {
1722
return distirbutionsSet.values();
@@ -22,46 +27,50 @@ abstract contract Distributor is IDistributor, CodeIndexer {
2227
return distributionOf[instance];
2328
}
2429

25-
function getDistributionURI(bytes32 id) public view returns (string memory) {
30+
function getDistributionURI(bytes32 distributorsId) public view returns (string memory) {
31+
DistributionComponent memory distributionComponent = distributionComponents[distributorsId];
2632
ICodeIndex codeIndex = getContractsIndex();
27-
return IDistribution(codeIndex.get(id)).getMetadata();
33+
return IDistribution(codeIndex.get(distributionComponent.id)).getMetadata();
2834
}
2935

3036
function _addDistribution(bytes32 id, bytes32 initId) internal virtual {
3137
ICodeIndex codeIndex = getContractsIndex();
3238
address initializerAddress = codeIndex.get(initId);
3339
if (codeIndex.get(id) == address(0)) revert DistributionNotFound(id);
3440
if (initializerAddress == address(0) && initId != bytes32(0)) revert InitializerNotFound(initId);
35-
if (distirbutionsSet.contains(id)) revert DistributionExists(id);
36-
distirbutionsSet.add(id);
37-
initializers[id] = IInitializer(initializerAddress);
41+
bytes32 distributorsId = keccak256(abi.encode(id,initId));
42+
if (distirbutionsSet.contains(distributorsId)) revert DistributionExists(distributorsId);
43+
distirbutionsSet.add(distributorsId);
44+
distributionComponents[distributorsId] = DistributionComponent(id, initializerAddress);
3845
emit DistributionAdded(id, initId);
3946
}
4047

41-
function _removeDistribution(bytes32 id) internal virtual {
42-
if (!distirbutionsSet.contains(id)) revert DistributionNotFound(id);
43-
distirbutionsSet.remove(id);
44-
emit DistributionRemoved(id);
48+
function _removeDistribution(bytes32 distributorsId) internal virtual {
49+
if (!distirbutionsSet.contains(distributorsId)) revert DistributionNotFound(distributorsId);
50+
distirbutionsSet.remove(distributorsId);
51+
initializers[distributorsId] = IInitializer(address(0));
52+
emit DistributionRemoved(distributorsId);
4553
}
4654

47-
function _instantiate(bytes32 id, bytes calldata args) internal virtual returns (address[] memory instances, bytes32 distributionName, uint256 distributionVersion) {
55+
function _instantiate(bytes32 distributorsId, bytes calldata args) internal virtual returns (address[] memory instances, bytes32 distributionName, uint256 distributionVersion) {
4856
ICodeIndex codeIndex = getContractsIndex();
49-
if (!distirbutionsSet.contains(id)) revert DistributionNotFound(id);
50-
(instances, distributionName, distributionVersion) = IDistribution(codeIndex.get(id)).instantiate();
57+
if (!distirbutionsSet.contains(distributorsId)) revert DistributionNotFound(distributorsId);
58+
DistributionComponent memory distributionComponent = distributionComponents[distributorsId];
59+
(instances, distributionName, distributionVersion) = IDistribution(codeIndex.get(distributionComponent.id)).instantiate();
5160
bytes4 selector = IInitializer.initialize.selector;
5261
// This ensures instance owner (distributor) performs initialization.
5362
// It is distirbutor responsibility to make sure calldata and initializer are safe to execute
54-
address initializer = address(initializers[id]);
63+
address initializer = address(initializers[distributionComponent.id]);
5564
if (initializer != address(0)) {
56-
(bool success, bytes memory result) = address(initializers[id]).delegatecall(
65+
(bool success, bytes memory result) = address(distributionComponent.initializer).delegatecall(
5766
abi.encodeWithSelector(selector, instances, args)
5867
);
5968
require(success, string(result));
6069
}
6170
for (uint256 i = 0; i < instances.length; i++) {
62-
distributionOf[instances[i]] = id;
71+
distributionOf[instances[i]] = distributorsId;
6372
}
64-
emit Instantiated(id, args);
73+
emit Instantiated(distributorsId, args);
6574
return (instances, distributionName, distributionVersion);
6675
}
6776

@@ -72,9 +81,10 @@ abstract contract Distributor is IDistributor, CodeIndexer {
7281
uint256,
7382
bytes memory
7483
) public view virtual returns (bytes memory) {
75-
bytes32 id = distributionOf[instance];
76-
if (id != bytes32(0) && distirbutionsSet.contains(id) == true) {
77-
return abi.encode(id, "");
84+
bytes32 distributorsId = distributionOf[instance];
85+
// DistributionComponent memory distributionComponent = distributionComponents[distributorsId];
86+
if (distributorsId != bytes32(0) && distirbutionsSet.contains(distributorsId) == true) {
87+
return abi.encode(distributorsId, "");
7888
} else {
7989
revert InvalidInstance(instance);
8090
}

src/interfaces/IDistributor.sol

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ interface IDistributor is ILayer {
1414

1515
event DistributionAdded(bytes32 indexed id, bytes32 indexed initializerId);
1616

17-
function getDistributions() external view returns (bytes32[] memory ids);
17+
function getDistributions() external view returns (bytes32[] memory distributorIds);
1818

19-
function getDistributionURI(bytes32 id) external view returns (string memory);
19+
function getDistributionURI(bytes32 distributorId) external view returns (string memory);
2020

21-
function instantiate(bytes32 id, bytes calldata args) external returns (address[] memory, bytes32 distributionName, uint256 distributionVersion);
21+
function instantiate(bytes32 distributorId, bytes calldata args) external returns (address[] memory, bytes32 distributionName, uint256 distributionVersion);
2222

23-
function addDistribution(bytes32 id, bytes32 initializer) external;
23+
function addDistribution(bytes32 distributorId, bytes32 initializer) external;
2424

25-
function removeDistribution(bytes32 id) external;
25+
function removeDistribution(bytes32 distributorId) external;
2626
}

test/eds/Distributor.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ describe("Distributor", function () {
1717
let distributor: OwnableDistributor;
1818
let deployer: SignerWithAddress;
1919
let owner: SignerWithAddress;
20+
let distributorsId: any;
2021
let cloneDistributionId: any;
2122

2223
beforeEach(async function () {
@@ -40,6 +41,10 @@ describe("Distributor", function () {
4041
await cloneDistribution.deployed();
4142
const code = await cloneDistribution.provider.getCode(cloneDistribution.address);
4243
cloneDistributionId = ethers.utils.keccak256(code);
44+
distributorsId = ethers.utils.solidityKeccak256(
45+
["bytes32", "bytes32"],
46+
[cloneDistributionId, ethers.utils.formatBytes32String("")]
47+
);
4348
await codeIndex.register(cloneDistribution.address);
4449
});
4550

@@ -83,12 +88,12 @@ describe("Distributor", function () {
8388
expect(
8489
await distributor
8590
.connect(owner)
86-
.instantiate(cloneDistributionId, ethers.utils.formatBytes32String(""))
91+
.instantiate(distributorsId, ethers.utils.formatBytes32String(""))
8792
).to.emit(distributor, "Instantiated");
8893
});
8994

9095
it("Is possible to remove a distribution", async function () {
91-
expect(await distributor.connect(owner).removeDistribution(cloneDistributionId)).to.emit(
96+
expect(await distributor.connect(owner).removeDistribution(distributorsId)).to.emit(
9297
distributor,
9398
"DistributionRemoved"
9499
);
@@ -100,12 +105,12 @@ describe("Distributor", function () {
100105
let receipt = await (
101106
await distributor
102107
.connect(owner)
103-
.instantiate(cloneDistributionId, ethers.utils.formatBytes32String(""))
108+
.instantiate(distributorsId, ethers.utils.formatBytes32String(""))
104109
).wait();
105110
let parsed = utils.getSuperInterface().parseLog(receipt.logs[0]);
106111
instanceAddress = parsed.args.instances[0];
107112
console.log(instanceAddress);
108-
await distributor.connect(owner).removeDistribution(cloneDistributionId);
113+
await distributor.connect(owner).removeDistribution(distributorsId);
109114
});
110115
it("Instance is invalid upon check", async () => {
111116
await expect(

test/eds/Installer.ts

+16-11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ describe("Installer", function () {
2020
let owner: SignerWithAddress;
2121
let target: SignerWithAddress;
2222
let cloneDistributionId: any;
23+
let distributorsId: any;
2324
let installer: MockInstaller;
2425

2526
beforeEach(async function () {
@@ -47,6 +48,10 @@ describe("Installer", function () {
4748
distributor
4849
.connect(owner)
4950
.addDistribution(cloneDistributionId, ethers.utils.formatBytes32String(""));
51+
distributorsId = ethers.utils.solidityKeccak256(
52+
["bytes32", "bytes32"],
53+
[cloneDistributionId, ethers.utils.formatBytes32String("")]
54+
);
5055
const Installer = (await ethers.getContractFactory("MockInstaller")) as MockInstaller__factory;
5156
installer = await Installer.deploy(target.address, owner.address);
5257
});
@@ -78,7 +83,7 @@ describe("Installer", function () {
7883
await installer.connect(owner).whitelistDistributor(distributor.address);
7984

8085
expect(
81-
await installer.connect(deployer).install(distributor.address, cloneDistributionId, "0x")
86+
await installer.connect(deployer).install(distributor.address, distributorsId, "0x")
8287
).to.emit(installer, "Installed");
8388
});
8489
it("can List distributors", async function () {
@@ -89,7 +94,7 @@ describe("Installer", function () {
8994
});
9095
it("Can get instances by id", async function () {
9196
await installer.connect(owner).whitelistDistributor(distributor.address);
92-
await installer.connect(owner).install(distributor.address, cloneDistributionId, "0x");
97+
await installer.connect(owner).install(distributor.address, distributorsId, "0x");
9398
const instanceNum = await installer.connect(owner).getInstancesNum();
9499
expect((await installer.connect(owner).getInstance(instanceNum)).length).to.be.eq(1);
95100
let instanceAddress = (await installer.connect(owner).getInstance(instanceNum))[0];
@@ -103,7 +108,7 @@ describe("Installer", function () {
103108

104109
it("Allows whitelisted distributor only valid instances to call target", async () => {
105110
await installer.connect(owner).whitelistDistributor(distributor.address);
106-
await installer.connect(owner).install(distributor.address, cloneDistributionId, "0x");
111+
await installer.connect(owner).install(distributor.address, distributorsId, "0x");
107112
const instanceNum = await installer.connect(owner).getInstancesNum();
108113
let instanceAddress = (await installer.connect(target).getInstance(instanceNum))[0];
109114
await expect(
@@ -114,15 +119,15 @@ describe("Installer", function () {
114119
installer.connect(target).beforeCall("0x", "0x00000000", instanceAddress, "0", "0x")
115120
).to.be.not.revertedWithCustomError(installer, "NotAnInstance");
116121

117-
await distributor.connect(owner).removeDistribution(cloneDistributionId);
122+
await distributor.connect(owner).removeDistribution(distributorsId);
118123
await expect(
119124
installer.connect(target).beforeCall("0x", "0x00000000", instanceAddress, "0", "0x")
120125
).to.be.revertedWithCustomError(distributor, "InvalidInstance");
121126
});
122127

123128
it("Allows valid distributions added by distributor and distribution id to call target", async () => {
124-
await installer.connect(owner).allowDistribution(distributor.address, cloneDistributionId);
125-
await installer.connect(owner).install(distributor.address, cloneDistributionId, "0x");
129+
await installer.connect(owner).allowDistribution(distributor.address, distributorsId);
130+
await installer.connect(owner).install(distributor.address, distributorsId, "0x");
126131
const instanceNum = await installer.connect(owner).getInstancesNum();
127132
let instanceAddress = (await installer.connect(target).getInstance(instanceNum))[0];
128133
await expect(
@@ -133,19 +138,19 @@ describe("Installer", function () {
133138
installer.connect(target).beforeCall("0x", "0x00000000", instanceAddress, "0", "0x")
134139
).to.be.not.revertedWithCustomError(installer, "NotAnInstance");
135140

136-
await distributor.connect(owner).removeDistribution(cloneDistributionId);
141+
await distributor.connect(owner).removeDistribution(distributorsId);
137142
await expect(
138143
installer.connect(target).beforeCall("0x", "0x00000000", instanceAddress, "0", "0x")
139144
).to.be.revertedWithCustomError(distributor, "InvalidInstance");
140145
});
141146

142147
it("Reverts when valid distributions added by distributor and distribution id were removed", async () => {
143-
await installer.connect(owner).allowDistribution(distributor.address, cloneDistributionId);
144-
await installer.connect(owner).install(distributor.address, cloneDistributionId, "0x");
148+
await installer.connect(owner).allowDistribution(distributor.address, distributorsId);
149+
await installer.connect(owner).install(distributor.address, distributorsId, "0x");
145150
const instanceNum = await installer.connect(owner).getInstancesNum();
146151
let instanceAddress = (await installer.connect(target).getInstance(instanceNum))[0];
147152

148-
await installer.connect(owner).disallowDistribution(distributor.address, cloneDistributionId);
153+
await installer.connect(owner).disallowDistribution(distributor.address, distributorsId);
149154

150155
await expect(
151156
installer.connect(target).beforeCall("0x", "0x00000000", instanceAddress, "0", "0x")
@@ -154,7 +159,7 @@ describe("Installer", function () {
154159

155160
it("Does reverts on invalid target", async () => {
156161
await installer.connect(owner).whitelistDistributor(distributor.address);
157-
await installer.connect(owner).install(distributor.address, cloneDistributionId, "0x");
162+
await installer.connect(owner).install(distributor.address, distributorsId, "0x");
158163
const instanceNum = await installer.connect(owner).getInstancesNum();
159164
let instanceAddress = (await installer.connect(target).getInstance(instanceNum))[0];
160165
await expect(

0 commit comments

Comments
 (0)