Skip to content

Commit

Permalink
added named distributions (#33)
Browse files Browse the repository at this point in the history
* added named distributions

* happy linter - happy life
  • Loading branch information
peersky authored Dec 5, 2024
1 parent d050103 commit 3ca5234
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/violet-emus-lie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@peeramid-labs/eds": minor
---

added interface to add named distributions
12 changes: 12 additions & 0 deletions src/abstracts/Distributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ abstract contract Distributor is IDistributor, CodeIndexer, ERC165 {
_newDistributionRecord(distributorId, distributionLocation, initializerAddress);
}

function _addDistribution(
bytes32 readableName,
bytes32 id,
address initializerAddress
) internal virtual returns (bytes32 distributorId) {
ICodeIndex codeIndex = getContractsIndex();
address distributionLocation = codeIndex.get(id);
if (distributionLocation == address(0)) revert DistributionNotFound(id);
distributorId = readableName;
_newDistributionRecord(distributorId, distributionLocation, initializerAddress);
}

function _removeDistribution(bytes32 distributorsId) internal virtual {
if (!distributionsSet.contains(distributorsId)) revert DistributionNotFound(distributorsId);
distributionsSet.remove(distributorsId);
Expand Down
18 changes: 18 additions & 0 deletions src/abstracts/TokenizedDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ abstract contract TokenizedDistributor is Distributor {
_setInstantiationCost(distributorsId, defaultInstantiationCost);
}

function _addDistribution(
bytes32 readableName,
bytes32 id,
address initializerAddress
) internal override returns (bytes32 distributorsId) {
distributorsId = super._addDistribution(readableName, id, initializerAddress);
_setInstantiationCost(distributorsId, defaultInstantiationCost);
}

function _addDistribution(
address repository,
address initializer,
LibSemver.VersionRequirement memory requirement
) internal override returns (bytes32 distributorsId) {
distributorsId = super._addDistribution(repository, initializer, requirement);
_setInstantiationCost(distributorsId, defaultInstantiationCost);
}

/**
* @inheritdoc Distributor
*/
Expand Down
4 changes: 4 additions & 0 deletions src/distributors/OwnableDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ contract OwnableDistributor is Distributor, Ownable {
super._addDistribution(address(repository), initializer, requirement);
}

function addNamedDistribution(bytes32 name, bytes32 distributorId, address initializer) external onlyOwner {
super._addDistribution(name, distributorId, initializer);
}

function changeVersion(
bytes32 distributionId,
LibSemver.VersionRequirement memory newRequirement
Expand Down
8 changes: 8 additions & 0 deletions src/interfaces/IDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,12 @@ interface IDistributor is IERC7746, IERC165 {
* @param newRequirement The new version requirement to be set for the distribution.
*/
function changeVersion(bytes32 distributionId, LibSemver.VersionRequirement memory newRequirement) external;

/**
* @notice Adds a new versioned distribution to the repository.
* @param name The name of the distribution.
* @param distributorId The unique identifier of the distributor.
* @param initializer The address that initializes the distribution.
*/
function addNamedDistribution(bytes32 name, bytes32 distributorId, address initializer) external;
}
11 changes: 8 additions & 3 deletions src/mocks/MockTokenizedDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ contract MockTokenizedDistributor is TokenizedDistributor, AccessControlDefaultA
*/
function addDistribution(bytes32 id, address initializer) external onlyRole(DEFAULT_ADMIN_ROLE) {
super._addDistribution(id, initializer);
instantiationCosts[keccak256(abi.encode(id, initializer))] = defaultInstantiationCost;
}

/**
Expand Down Expand Up @@ -87,8 +86,14 @@ contract MockTokenizedDistributor is TokenizedDistributor, AccessControlDefaultA
address initializer,
LibSemver.VersionRequirement memory requirement
) external override onlyRole(DEFAULT_ADMIN_ROLE) {
bytes32 distributorId = keccak256(abi.encode(repository, initializer));
instantiationCosts[distributorId] = defaultInstantiationCost;
super._addDistribution(address(repository), initializer, requirement);
}

function addNamedDistribution(
bytes32 name,
bytes32 distributorId,
address initializer
) external onlyRole(DEFAULT_ADMIN_ROLE) {
super._addDistribution(name, distributorId, initializer);
}
}
32 changes: 32 additions & 0 deletions test/eds/Distributor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,38 @@ describe("Distributor", function () {
).to.be.revertedWithCustomError(distributor, "DistributionNotFound");
});

describe("addNamedDistribution", function () {
it("should allow owner to add a named distribution", async function () {
const name = ethers.utils.formatBytes32String("test-distribution");
const initializer = ethers.constants.AddressZero;

await expect(
distributor.connect(owner).addNamedDistribution(name, cloneDistributionId, initializer)
)
.to.emit(distributor, "DistributionAdded")
.withArgs(name, await codeIndex.get(cloneDistributionId), initializer);
});

it("should revert when non-owner tries to add a named distribution", async function () {
const name = ethers.utils.formatBytes32String("test-distribution");
const initializer = ethers.constants.AddressZero;

await expect(
distributor.connect(deployer).addNamedDistribution(name, cloneDistributionId, initializer)
).to.be.revertedWithCustomError(distributor, "OwnableUnauthorizedAccount");
});

it("should revert when distribution ID does not exist", async function () {
const name = ethers.utils.formatBytes32String("test-distribution");
const initializer = ethers.constants.AddressZero;
const nonExistentId = ethers.utils.formatBytes32String("non-existent");

await expect(
distributor.connect(owner).addNamedDistribution(name, nonExistentId, initializer)
).to.be.revertedWithCustomError(distributor, "DistributionNotFound");
});
});

describe("when distribution is added", function () {
beforeEach(async function () {
await distributor
Expand Down

0 comments on commit 3ca5234

Please sign in to comment.