Skip to content

Commit

Permalink
added doc strings, cleaned up unused files
Browse files Browse the repository at this point in the history
  • Loading branch information
peersky committed Sep 29, 2024
1 parent 4facccc commit 7c42d88
Show file tree
Hide file tree
Showing 18 changed files with 376 additions and 82 deletions.
5 changes: 3 additions & 2 deletions src/abstracts/CloneDistribution.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ abstract contract CloneDistribution is IDistribution, CodeIndexer {

function sources() internal view virtual returns (address[] memory, bytes32 name, uint256 version);

// @inheritdoc IDistribution
function instantiate(
bytes memory
) external virtual returns (address[] memory instances, bytes32 distributionName, uint256 distributionVersion) {
Expand All @@ -23,10 +24,10 @@ abstract contract CloneDistribution is IDistribution, CodeIndexer {
emit Distributed(msg.sender, instances);
return (instances, _distributionName, _distributionVersion);
}

// @inheritdoc IDistribution
function get() external view virtual returns (address[] memory src, bytes32 name, uint256 version) {
return sources();
}

// @inheritdoc IDistribution
function getMetadata() external view virtual returns (string memory);
}
4 changes: 2 additions & 2 deletions src/abstracts/CodeIndexer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ abstract contract CodeIndexer {
//Create2 contract
ICodeIndex private constant INDEX_CONTRACT = ICodeIndex(0xc0D31d398c5ee86C5f8a23FA253ee8a586dA03Ce);
constructor() {}

// @inheritdoc ICodeIndex
function getContractsIndex() internal pure returns (ICodeIndex) {
return INDEX_CONTRACT;
}

// @inheritdoc ICodeIndex
function index(address source) internal {
INDEX_CONTRACT.register(source);
}
Expand Down
36 changes: 24 additions & 12 deletions src/abstracts/Distributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "../interfaces/IInitializer.sol";
import "../abstracts/CodeIndexer.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
/**
* @title Distributor
* @notice Abstract contract that implements the IDistributor interface, CodeIndexer, and ERC165.
* This contract serves as a base for creating distributor contracts with specific functionalities.
* It provides the necessary structure and functions to be extended by other contracts.
* @author Peeramid Labs, 2024
*/
abstract contract Distributor is IDistributor, CodeIndexer, ERC165 {
struct DistributionComponent {
bytes32 id;
Expand All @@ -19,19 +26,19 @@ abstract contract Distributor is IDistributor, CodeIndexer, ERC165 {
mapping(uint256 => bytes32) public distributionOf;
mapping(bytes32 => DistributionComponent) public distributionComponents;
uint256 public numInstances;

// @inheritdoc IDistributor
function getDistributions() external view returns (bytes32[] memory) {
return distirbutionsSet.values();
}

// @inheritdoc IDistributor
function getDistributionId(address instance) external view virtual returns (bytes32) {
return distributionOf[getInstanceId(instance)];
}

// @inheritdoc IDistributor
function getInstanceId(address instance) public view virtual returns (uint256) {
return instanceIds[instance];
}

// @inheritdoc IDistributor
function getDistributionURI(bytes32 distributorsId) external view returns (string memory) {
DistributionComponent memory distributionComponent = distributionComponents[distributorsId];
ICodeIndex codeIndex = getContractsIndex();
Expand All @@ -55,6 +62,10 @@ abstract contract Distributor is IDistributor, CodeIndexer, ERC165 {
emit DistributionRemoved(distributorsId);
}

/**
* @notice Internal function to instantiate a new instance.
* @dev This function will DELEGATECALL to initializer. Initializer MUST be trusted contract.
*/
function _instantiate(
bytes32 distributorsId,
bytes memory args
Expand Down Expand Up @@ -92,13 +103,10 @@ abstract contract Distributor is IDistributor, CodeIndexer, ERC165 {
return (instances, distributionName, distributionVersion);
}

/*
* @dev This is ERC7746 implementation
* This hook must be called by instance methods that access scope is
* limited to the same instance or distribution
* it will revert if `msg.sender` is not a valid instance
* it will revert if `maybeInstance` is not a valid instance
* it will revert if instanceId belongs to disactivated distribution
/**
* @inheritdoc IERC7746
* @notice This is ERC7746 hook must be called by instance methods that access scope is limited to the same instance or distribution
* @dev it will revert if: (1) `msg.sender` is not a valid instance; (2) `maybeInstance` is not a valid instance (3) `instanceId` belongs to disactivated distribution
*/
function beforeCall(
bytes memory config,
Expand All @@ -120,7 +128,11 @@ abstract contract Distributor is IDistributor, CodeIndexer, ERC165 {
}
revert InvalidInstance(maybeInstance);
}

/**
* @inheritdoc IERC7746
* @notice This is ERC7746 hook must be called by instance methods that access scope is limited to the same instance or distribution
* @dev it will revert if: (1) `msg.sender` is not a valid instance; (2) `maybeInstance` is not a valid instance (3) `instanceId` belongs to disactivated distribution
*/
function afterCall(
bytes memory config,
bytes4,
Expand Down
20 changes: 20 additions & 0 deletions src/abstracts/ERC7746Middleware.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,33 @@
pragma solidity >=0.8.0 <0.9.0;
import "../libraries/LibMiddleware.sol";

/**
* @title ERC7746Middleware
* @notice Abstract contract that serves as a middleware for ERC7746 standard.
* This contract is intended to be inherited by other contracts that implement
* the ERC7746 functionality. It provides base functionality and structure
* that can be extended and customized by derived contracts.
* @author Peeramid Labs, 2024
*/
abstract contract ERC7746Middleware {
/**
* @notice Modifier to apply custom logic for ERC7746 compliance.
* @param _selector The function selector to be checked.
* @param sender The address of the sender.
* @param data The calldata being passed to the function.
* @param value The value being transferred.
*/
modifier ERC7746C(bytes4 _selector, address sender, bytes calldata data, uint256 value) {
bytes[] memory layerReturns = LibMiddleware.beforeCall(_selector, sender, data, value);
_;
LibMiddleware.afterCall(_selector, sender, data, value, layerReturns);
}

/**
* @notice Modifier to apply ERC7746 specific logic.
* This modifier can be used to enforce certain conditions or
* execute specific code before or after the function it modifies.
*/
modifier ERC7746() {
bytes[] memory layerReturns = LibMiddleware.beforeCall(msg.sig, msg.sender, msg.data, msg.value);
_;
Expand Down
6 changes: 6 additions & 0 deletions src/abstracts/Installer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ pragma solidity >=0.8.0 <0.9.0;
import "../interfaces/IDistributor.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "../interfaces/IInstaller.sol";
/**
* @title Installer
* @notice Abstract contract that implements the IInstaller interface.
* This contract serves as a base for other contracts that require installation functionality.
* @author Peeramid Labs, 2024
*/
abstract contract Installer is IInstaller {
using EnumerableSet for EnumerableSet.AddressSet;
using EnumerableSet for EnumerableSet.Bytes32Set;
Expand Down
31 changes: 20 additions & 11 deletions src/abstracts/InstallerCloneable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,31 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "../interfaces/IInstaller.sol";
import "../libraries/LibInstaller.sol";
/**
* @title InstallerClonable
* @notice Abstract contract that implements the IInstaller interface and is Initializable.
* This contract serves as a base for creating clonable installer contracts.
*/
abstract contract InstallerClonable is IInstaller, Initializable {
using EnumerableSet for EnumerableSet.AddressSet;
using EnumerableSet for EnumerableSet.Bytes32Set;

constructor() {
_disableInitializers();
}

// @inheritdoc IInstaller
function initialize(address targetAddress) public virtual initializer {
LibInstaller.getStorage()._target = targetAddress;
}

// @inheritdoc IInstaller
function isDistributor(IDistributor distributor) public view returns (bool) {
return LibInstaller.getStorage().whitelistedDistributors.contains(address(distributor));
}

// @inheritdoc IInstaller
function getWhitelistedDistributors() public view returns (address[] memory) {
return LibInstaller.getStorage().whitelistedDistributors.values();
}

// @inheritdoc IInstaller
function whitelistedDistributions(IDistributor distributor) public view returns (bytes32[] memory) {
if (LibInstaller.getStorage().whitelistedDistributors.contains(address(distributor))) {
return distributor.getDistributions();
Expand Down Expand Up @@ -98,27 +103,29 @@ abstract contract InstallerClonable is IInstaller, Initializable {
}
strg.instancesNum--;
}

// @inheritdoc IInstaller
function getInstance(uint256 instanceId) public view returns (address[] memory instaneContracts) {
return LibInstaller.getStorage()._instanceEnum[instanceId];
}

// @inheritdoc IInstaller
function getInstancesNum() public view returns (uint256) {
return LibInstaller.getStorage().instancesNum;
}

// @inheritdoc IInstaller
function isInstance(address instance) public view returns (bool) {
return LibInstaller.getStorage()._distributorOf[instance] != address(0);
}

// @inheritdoc IInstaller
function distributorOf(address instance) public view returns (IDistributor) {
return IDistributor(LibInstaller.getStorage()._distributorOf[instance]);
}

// @inheritdoc IInstaller
function target() public view returns (address) {
return LibInstaller.getStorage()._target;
}

// @inheritdoc IERC7746
// @notice this will revert if the sender is not the target or requesting instance is not a valid instance
// @dev it will daisy-chain the call to the distributor, if instance is valid and active distribution
function beforeCall(
bytes memory layerConfig,
bytes4 selector,
Expand All @@ -145,7 +152,9 @@ abstract contract InstallerClonable is IInstaller, Initializable {
}
revert NotAnInstance(requestingInstance);
}

// @inheritdoc IERC7746
// @notice this will revert if the sender is not the target or requesting instance is not a valid instance
// @dev it will daisy-chain the call to the distributor, if instance is valid and active distribution
function afterCall(
bytes memory layerConfig,
bytes4 selector,
Expand Down
5 changes: 3 additions & 2 deletions src/abstracts/MiddlewareProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import "../libraries/LibMiddleware.sol";
/**
* @dev This contract is a modified OpenZeppelin proxy v5.0.0.
* Modification wraps a fallback function within ERC7746.
* Rest is similar to OpenZeppelin Proxy.sol
* Rest is similar to Proxy.sol
*/
contract MiddlewareProxy is ERC7746Middleware {
address private immutable implementationAddress;
Expand Down Expand Up @@ -47,8 +47,9 @@ contract MiddlewareProxy is ERC7746Middleware {
}

/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* @notice Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
* @dev This function is wrapped in ERC7746 middleware pattern
*/
fallback() external payable virtual ERC7746 {
_fallback();
Expand Down
22 changes: 13 additions & 9 deletions src/abstracts/Repository.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
pragma solidity >=0.8.0 <0.9.0;

import "../libraries/LibSemver.sol";
import "../interfaces/IRepository.sol";

/**
* @title Repository
* @notice Abstract contract that implements the IRepository interface. This contract serves as a base for other contracts that require repository functionalities.
*/
abstract contract Repository is IRepository {
bytes32 public immutable repositoryName;
using LibSemver for LibSemver.Version;
Expand All @@ -19,13 +23,6 @@ abstract contract Repository is IRepository {
constructor(bytes32 _repositoryName) {
repositoryName = _repositoryName;
}
// error VersionHashDoesNotExist(uint256 version);
// error ReleaseZeroNotAllowed();
// error AlreadyInPreviousRelease(uint256 version, bytes32 source);
// error EmptyReleaseMetadata();
// error ReleaseDoesNotExist();
// event VersionAdded(uint256 indexed version, bytes32 indexed source, bytes buildMetadata);
// event ReleaseMetadataUpdated(uint256 indexed version, bytes releaseMetadata);

function _updateReleaseMetadata(LibSemver.Version memory version, bytes memory metadata) internal {
uint256 versionFlat = version.toUint256();
Expand Down Expand Up @@ -72,13 +69,15 @@ abstract contract Repository is IRepository {
latestVersion = versionFlat;
emit VersionAdded(versionFlat, sourceId, metadata);
}
// @inheritdoc IRepository
function getLatest() public view returns (Source memory) {
Source memory src;
src.sourceId = versionedSources[latestVersion];
src.version = LibSemver.parse(latestVersion);
src.metadata = releaseMetadata[uint64(latestVersion)];
return src;
}
// @inheritdoc IRepository
function get(
LibSemver.Version memory version,
LibSemver.requirements requirement
Expand Down Expand Up @@ -146,22 +145,27 @@ abstract contract Repository is IRepository {
bytes memory patchMetadata = patchReleaseMetadata[versionFlat];
return bytes.concat(majorMetadata, minorMetadata, patchMetadata);
}

// @inheritdoc IRepository
function getMajorReleaseMetadata(uint64 major) public view returns (bytes memory) {
return releaseMetadata[major];
}
// @inheritdoc IRepository
function getMinorReleaseMetadata(uint64 major, uint64 minor) public view returns (bytes memory) {
return minorReleaseMetadata[(uint128(major) << 64) | uint128(minor)];
}
// @inheritdoc IRepository
function getPatchReleaseMetadata(uint64 major, uint64 minor, uint64 patch) public view returns (bytes memory) {
return patchReleaseMetadata[(uint256(major) << 192) | (uint256(minor) << 128) | uint256(patch)];
}
// @inheritdoc IRepository
function getMajorReleases() public view returns (uint64) {
return majorReleases;
}
// @inheritdoc IRepository
function getMinorReleases(uint64 major) public view returns (uint64) {
return minorReleases[major];
}
// @inheritdoc IRepository
function getPatchReleases(uint64 major, uint64 minor) public view returns (uint128) {
return patchReleases[(uint128(major) << 64) | uint128(minor)];
}
Expand Down
16 changes: 14 additions & 2 deletions src/distributions/CodeHashDistribution.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,24 @@ pragma solidity >=0.8.0 <0.9.0;

import "../abstracts/CloneDistribution.sol";

/**
* @title CodeHashDistribution
* @notice This contract creates immutable. It allows to add metadata to the distribution as well as specify name and version for EIP712 compatability reasons.
* @dev This contract is a base for creating distributions that are identified by a deployed functionality (byte code hash).
*/
contract CodeHashDistribution is CloneDistribution {
bytes32 private immutable metadata;
address private immutable _reference;
bytes32 public immutable distributionName;
uint256 public immutable distributionVersion;

/**
* @notice Constructor for the CodeHashDistribution contract.
* @param codeHash The hash of the code to be distributed.
* @param _metadata Metadata associated with the code.
* @param name The name of the distribution.
* @param version The version number of the distribution.
*/
constructor(bytes32 codeHash, bytes32 _metadata, bytes32 name, uint256 version) {
distributionName = name;
distributionVersion = version;
Expand All @@ -19,13 +31,13 @@ contract CodeHashDistribution is CloneDistribution {
revert CodeNotFoundInIndex(codeHash);
}
}

// @inheritdoc IDistribution
function sources() internal view virtual override returns (address[] memory, bytes32 name, uint256 version) {
address[] memory _sources = new address[](1);
_sources[0] = _reference;
return (_sources, distributionName, distributionVersion);
}

// @inheritdoc IDistribution
function getMetadata() external view virtual override returns (string memory) {
return string(abi.encodePacked(metadata)); //ToDo: Add IPFS link with readme!
}
Expand Down
Loading

0 comments on commit 7c42d88

Please sign in to comment.