Skip to content
Merged
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
16 changes: 8 additions & 8 deletions .env.vault

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ force-compile:

.PHONY: test ## run tests
test:
@CI=true && forge test --show-progress --gas-report -vvv --fail-fast
@export CI=true && forge test --show-progress --gas-report -vvvv

.PHONY: coverage ## run tests coverage report
coverage:
Expand Down
37 changes: 36 additions & 1 deletion contracts/access/AccessManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,44 @@ contract AccessManager is Initializable, UUPSUpgradeable, AccessManagerUpgradeab
// return (true, getRoleAdmin(roleId), 0); // => (true, 0, 0)
// }

// Strategic roles for governance classification within the protocol:
//
// Community Governance Role:
// - GOV_ROLE: Represents decentralized community governance.
// Decisions are made through collective voting mechanisms (e.g., token-weighted, quadratic).
//
// Group/Sub-DAO Based Roles:
// - ADMIN_ROLE: Managed by a smart account or sub-DAO.
// Handles protocol upgrades, pause mechanisms, and operational role assignments.
// - MOD_ROLE: Managed by a smart account or sub-DAO.
// Approves policy submissions and moderates hook operations.
// - REF_ROLE: Managed by a smart account or sub-DAO.
// Participates in governance referenda for content curation and distributor selection.
//
// Individual/Contract Based Roles:
// - OPS_ROLE: Internal operational role assigned to protocol-trusted contracts
// for direct module interactions. No human involvement.
// - VER_ROLE: Individual role assigned to trusted creators, enabling
// content uploads without conventional verification.

/*
GOV_ROLE (Community Governance)
├── ADMIN_ROLE (Smart Account / Sub-DAO)
│ │
│ ├── MOD_ROLE (Smart Account / Sub-DAO)
│ │
│ └── OPS_ROLE (Internal Contract Role)
├── REF_ROLE (Smart Account / Sub-DAO)
├── VER_ROLE (Individual Trusted Creator)
*/

_setRoleAdmin(C.VER_ROLE, C.GOV_ROLE);
_setRoleAdmin(C.REF_ROLE, C.GOV_ROLE);
_setRoleAdmin(C.MOD_ROLE, C.ADMIN_ROLE);
_setRoleAdmin(C.OPS_ROLE, C.ADMIN_ROLE);
_setRoleAdmin(C.VER_ROLE, C.GOV_ROLE);
}

// TODO pause protocol based on permission and roles
Expand Down
2 changes: 2 additions & 0 deletions contracts/access/eg.PauseManager
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// pause protocol using:
// pause manager + pausable
5 changes: 3 additions & 2 deletions contracts/assets/AssetOwnership.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ contract AssetOwnership is
/// @dev Emitted when a new asset is registered on the platform.
/// @param owner The address of the creator or owner of the registered asset.
/// @param assetId The unique identifier for the registered asset.
event RegisteredAsset(address indexed owner, uint256 assetId);
event RegisteredAsset(address indexed owner, uint256 indexed assetId);

/// @dev Emitted when an asset is revoked and removed from the platform.
/// @param owner The address of the owner of the revoked asset.
/// @param assetId The unique identifier for the revoked asset.
event RevokedAsset(address indexed owner, uint256 assetId);
event RevokedAsset(address indexed owner, uint256 indexed assetId);

/// @dev Emitted when an asset is transferred from one owner to another.
/// @param from The address of the current owner of the asset.
Expand Down Expand Up @@ -112,6 +112,7 @@ contract AssetOwnership is
}

// TODO: build getURI => from custodian /erc721-metadata
// TODO: Update asset info control version restricted/approved by governance
// TODO: Transfer Ownership Fee: Introducing a fee for transferring
// ownership discourages frequent or unnecessary transfers,
// adding an economic cost to any potential abuse of the system. Like bypassing content
Expand Down
16 changes: 6 additions & 10 deletions contracts/assets/AssetReferendum.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
pragma solidity 0.8.26;

import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import { EIP712Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol";
import { NoncesUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/NoncesUpgradeable.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import { AccessControlledUpgradeable } from "@synaps3/core/primitives/upgradeable/AccessControlledUpgradeable.sol";
import { QuorumUpgradeable } from "@synaps3/core/primitives/upgradeable/QuorumUpgradeable.sol";
import { IAssetReferendum } from "@synaps3/core/interfaces/assets/IAssetReferendum.sol";
import { T } from "@synaps3/core/primitives/Types.sol";
import { C } from "@synaps3/core/primitives/Constants.sol";

/// @title AssetReferendum
Expand All @@ -20,8 +19,6 @@ contract AssetReferendum is
Initializable,
UUPSUpgradeable,
AccessControlledUpgradeable,
NoncesUpgradeable,
EIP712Upgradeable,
QuorumUpgradeable,
IAssetReferendum
{
Expand All @@ -34,19 +31,19 @@ contract AssetReferendum is
/// @dev Event emitted when a content is submitted for referendum.
/// @param assetId The ID of the asset that has been submitted.
/// @param initiator The address of the initiator who submitted the asset.
event Submitted(address indexed initiator, uint256 assetId);
event Submitted(address indexed initiator, uint256 indexed assetId);

/// @dev Event emitted when a content is approved.
/// @param assetId The ID of the asset that has been approved.
event Approved(uint256 assetId);
event Approved(uint256 indexed assetId);

/// @dev Event emitted when a content is revoked.
/// @param assetId The ID of the asset that has been revoked.
event Revoked(uint256 assetId);
event Revoked(uint256 indexed assetId);

/// @dev Event emitted when a content is rejected.
/// @param assetId The ID of the asset that has been rejected.
event Rejected(uint256 assetId);
event Rejected(uint256 indexed assetId);

/// @dev Error thrown when asset submission fails.
/// @param initiator The address of the user who attempted to submit the asset.
Expand All @@ -66,7 +63,6 @@ contract AssetReferendum is
function initialize(address accessManager) public initializer {
__Quorum_init();
__UUPSUpgradeable_init();
__EIP712_init("Referendum", "1");
__AccessControlled_init(accessManager);
}

Expand Down Expand Up @@ -133,7 +129,7 @@ contract AssetReferendum is
/// @notice Checks if the asset is active nor blocked.
/// @param assetId The ID of the asset.
function isActive(uint256 assetId) public view returns (bool) {
return _status(assetId) == Status.Active;
return _status(assetId) == T.Status.Active;
}

/// @notice Function that should revert when msg.sender is not authorized to upgrade the contract.
Expand Down
1 change: 1 addition & 0 deletions contracts/assets/eg.AssetDisputes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// dispute rights via governance
3 changes: 1 addition & 2 deletions contracts/core/interfaces/assets/IAssetRegistrable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ pragma solidity 0.8.26;

/// @title IAssetRegistrable Interface
/// @notice Defines the essential functions for managing asset registration and governance through a referendum process.
/// @dev Implement this interface in a referendum contract to allow
/// asset proposals, approvals, rejections, and revocations.
/// @dev This interface mirrors the FSM behavior from `IQuorum`, but scoped to asset governance.
interface IAssetRegistrable {
/// @notice Submits a new asset proposition for a referendum.
/// @dev This function should allow entities to propose an asset for approval.
Expand Down
6 changes: 3 additions & 3 deletions contracts/core/interfaces/base/IBalanceOperator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// NatSpec format convention - https://docs.soliditylang.org/en/v0.5.10/natspec-format.html
pragma solidity 0.8.26;

/// @title IBalanceOperator Interface
/// @notice Combines functionalities for verifying, depositing, withdrawing, and transferring balances.
/// @dev This interface aggregates multiple interfaces to standardize balance-related operations.
import { IBalanceDepositor } from "@synaps3/core/interfaces/base/IBalanceDepositor.sol";
import { IBalanceWithdrawable } from "@synaps3/core/interfaces/base/IBalanceWithdrawable.sol";
import { IBalanceTransferable } from "@synaps3/core/interfaces/base/IBalanceTransferable.sol";
import { IBalanceVerifiable } from "@synaps3/core/interfaces/base/IBalanceVerifiable.sol";

/// @title IBalanceOperator Interface
/// @notice Combines functionalities for verifying, depositing, withdrawing, and transferring balances.
/// @dev This interface aggregates multiple interfaces to standardize balance-related operations.
/// @dev The `IBalanceOperator` interface extends multiple interfaces to provide a comprehensive suite of
/// balance-related operations, including deposit, withdrawal, transfer, reserve, and balance verification.
interface IBalanceOperator is IBalanceDepositor, IBalanceWithdrawable, IBalanceTransferable, IBalanceVerifiable {}
12 changes: 12 additions & 0 deletions contracts/core/interfaces/base/IQuorum.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;

import { IQuorumRegistrable } from "@synaps3/core/interfaces/base/IQuorumRegistrable.sol";
import { IQuorumRevokable } from "@synaps3/core/interfaces/base/IQuorumRevokable.sol";
import { IQuorumInspectable } from "@synaps3/core/interfaces/base/IQuorumInspectable.sol";

/// @title IQuorum
/// @notice Aggregates the full lifecycle of an FSM-driven entity registration system.
/// @dev Combines registration, approval, rejection, revocation, and status inspection.
/// Intended for systems that use `QuorumUpgradeable` as FSM logic layer.
interface IQuorum is IQuorumRegistrable, IQuorumRevokable, IQuorumInspectable {}
11 changes: 11 additions & 0 deletions contracts/core/interfaces/base/IQuorumInspectable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;

import { T } from "@synaps3/core/primitives/Types.sol";

/// @title IQuorumInspectable
/// @notice Interface for querying the status of registered entities.
interface IQuorumInspectable {
/// @notice Returns the current FSM status of the entity.
function status(uint256 entry) external view returns (T.Status);
}
22 changes: 22 additions & 0 deletions contracts/core/interfaces/base/IQuorumRegistrable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;

/// @title IQuorumRegistrable
/// @notice FSM interface for entities that go through registration and decision (approve/reject).
interface IQuorumRegistrable {
/// @notice Initiates the registration of an entity.
/// @param entry The generic ID (could be uint160(address) or asset ID).
function register(uint256 entry) external;

/// @notice Approves an entity.
/// @param entry The ID of the entity.
function approve(uint256 entry) external;

/// @notice Blocks or rejects an entity before approval.
/// @param entry The ID of the entity.
function reject(uint256 entry) external;

/// @notice Internal function for an entity to resign.
/// @param entry The ID of the entity.
function quit(uint256 entry) external;
}
10 changes: 10 additions & 0 deletions contracts/core/interfaces/base/IQuorumRevokable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;

/// @title IQuorumRevokable
/// @notice FSM interface for revoking approved entities.
interface IQuorumRevokable {
/// @notice Revokes a previously approved entity.
/// @param entry The ID of the entity.
function revoke(uint256 entry) external;
}
5 changes: 5 additions & 0 deletions contracts/core/interfaces/custody/ICustodianFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ interface ICustodianFactory {
/// @param custodian The address of the custodian contract.
/// @return The address of the entity that created the custodian.
function getCreator(address custodian) external view returns (address);

/// @notice Checks whether a given custodian contract has been registered.
/// @param custodian The address of the custodian contract to check.
/// @return True if the custodian is registered; false otherwise.
function isRegistered(address custodian) external view returns (bool);
}
15 changes: 15 additions & 0 deletions contracts/core/interfaces/custody/ICustodianInspectable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;

/// @title ICustodianInspectable
/// @dev Interface for retrieving custodian enrollment data.
interface ICustodianInspectable {
/// @notice Retrieves the enrollment deadline for a custodian.
/// @param custodian The address of the custodian.
/// @return The enrollment deadline timestamp.
function getEnrollmentDeadline(address custodian) external view returns (uint256);

/// @notice Retrieves the total number of enrollments.
/// @return The number of enrollments.
function getEnrollmentCount() external view returns (uint256);
}
10 changes: 9 additions & 1 deletion contracts/core/interfaces/custody/ICustodianReferendum.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@ pragma solidity 0.8.26;

import { ICustodianExpirable } from "@synaps3/core/interfaces/custody/ICustodianExpirable.sol";
import { ICustodianRegistrable } from "@synaps3/core/interfaces/custody/ICustodianRegistrable.sol";
import { ICustodianInspectable } from "@synaps3/core/interfaces/custody/ICustodianInspectable.sol";
import { ICustodianVerifiable } from "@synaps3/core/interfaces/custody/ICustodianVerifiable.sol";
import { ICustodianRevokable } from "@synaps3/core/interfaces/custody/ICustodianRevokable.sol";

/// @title ICustodianReferendum
/// @notice Interface that defines the necessary operations for managing custodian registration.
interface ICustodianReferendum is ICustodianRegistrable, ICustodianVerifiable, ICustodianExpirable {}
interface ICustodianReferendum is
ICustodianRegistrable,
ICustodianVerifiable,
ICustodianExpirable,
ICustodianInspectable,
ICustodianRevokable
{}
17 changes: 4 additions & 13 deletions contracts/core/interfaces/custody/ICustodianRegistrable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,15 @@ pragma solidity 0.8.26;

/// @title ICustodianRegistrable
/// @dev Interface for managing custodians registration.
/// @dev This interface indirectly implements the FSM defined in `IQuorum` using `QuorumUpgradeable`.
/// Functions here are semantically equivalent to the FSM transitions: register → approve.
interface ICustodianRegistrable {
/// @notice Registers data with a given identifier.
/// @param custodian The address of the custodian to register.
/// @param proof The unique identifier of the agreement to be enforced.
/// @param currency The currency used to pay enrollment.
function register(address custodian, address currency) external;
function register(uint256 proof, address currency) external;

/// @notice Approves the data associated with the given identifier.
/// @param custodian The address of the custodian to approve.
function approve(address custodian) external;

/// @notice Revokes the registration of an entity.
/// @param custodian The address of the custodian to revoke.
function revoke(address custodian) external;

/// @notice Retrieves the enrollment deadline for a custodian.
/// @param custodian The address of the custodian.
function getEnrollmentDeadline(address custodian) external view returns (uint256);

/// @notice Retrieves the total number of enrollments.
function getEnrollmentCount() external view returns (uint256);
}
10 changes: 10 additions & 0 deletions contracts/core/interfaces/custody/ICustodianRevokable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;

/// @title ICustodianRevokable
/// @dev Interface for revoking approved custodians.
interface ICustodianRevokable {
/// @notice Revokes the active status of a custodian.
/// @param custodian The address of the custodian to revoke.
function revoke(address custodian) external;
}
15 changes: 15 additions & 0 deletions contracts/core/interfaces/economics/IFeeSchemeValidator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: BUSL-1.1
// NatSpec format convention - https://docs.soliditylang.org/en/v0.5.10/natspec-format.html
pragma solidity 0.8.26;

import { T } from "@synaps3/core/primitives/Types.sol";

/// @title IFeeSchemeValidator
/// @notice Interface for authorizing which fee schemes are accepted in a protocol context.
/// @dev This contract represents a context-bound authorizer, so no target is passed.
interface IFeeSchemeValidator {
/// @notice Returns true if the fee scheme is supported by this contract.
/// @param scheme The scheme to check.
/// @return True if supported, false if explicitly not supported.
function isFeeSchemeSupported(T.Scheme scheme) external view returns (bool);
}
20 changes: 20 additions & 0 deletions contracts/core/interfaces/lifecycle/IHook.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: BUSL-1.1
// NatSpec format convention - https://docs.soliditylang.org/en/v0.5.10/natspec-format.html
pragma solidity 0.8.26;

interface IHook {
// Chain of responsibility

// pre call to check if the hook its associated with the target
// eg. SubscriptionPolicy its allowed to process this hook
function validate(address caller, address target) external returns (bool);

/// @notice Called by the protocol to signal the use of the hook
/// @param caller The address invoking the hook (e.g., the user or distributor)
/// @param context Optional: bytes data for hook-specific usage
function execute(address caller, bytes calldata context) external returns (bytes memory);

// post call to verify the execution, run logs, etc
// eg. SubscriptionPolicy execution complain well?
function verify(address caller, bytes calldata results) external returns (bool);
}
7 changes: 7 additions & 0 deletions contracts/core/interfaces/lifecycle/IHookRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: BUSL-1.1
// NatSpec format convention - https://docs.soliditylang.org/en/v0.5.10/natspec-format.html
pragma solidity 0.8.26;

interface IHookRegistry {
function lookup(bytes4 interfaceId) external returns (address);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: BUSL-1.1
// NatSpec format convention - https://docs.soliditylang.org/en/v0.5.10/natspec-format.html
pragma solidity 0.8.26;

interface IHookRegistryRegistrable {
function lookup(bytes4 interfaceId) external returns (address);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: BUSL-1.1
// NatSpec format convention - https://docs.soliditylang.org/en/v0.5.10/natspec-format.html
pragma solidity 0.8.26;

interface IHookRegistryVerifiable {
function lookup(bytes4 interfaceId) external returns (address);
}
2 changes: 1 addition & 1 deletion contracts/core/interfaces/policies/IPolicy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface IPolicy {

/// @notice Executes the agreement between the asset holder and the account based on the policy's rules.
/// @dev Rights Policies Manager contract should be the only one allowed to call this method.
/// @param holder The rights holder whose authorization is required for accessing the asset.
/// @param holder The rights holder whose authorization is required for accessing the assets.
/// @param agreement An object containing the terms agreed upon between the asset holder and the user.
function enforce(address holder, T.Agreement calldata agreement) external returns (uint256[] memory);

Expand Down
1 change: 1 addition & 0 deletions contracts/core/primitives/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ library C {
uint64 internal constant MOD_ROLE = 2; // moderator role
uint64 internal constant VER_ROLE = 3; // account verified role
uint64 internal constant OPS_ROLE = 4; // operations roles
uint64 internal constant REF_ROLE = 5; // referendum roles

bytes32 internal constant REFERENDUM_SUBMIT_TYPEHASH =
keccak256("Submission(uint256 assetId, address initiator, uint256 nonce)");
Expand Down
Loading