Skip to content

Commit a5e0f21

Browse files
authored
Merge pull request #29 from Synaps3Protocol/registries/hook
Registries/hook
2 parents 1a729b5 + c9cc91a commit a5e0f21

File tree

21 files changed

+1734
-1368
lines changed

21 files changed

+1734
-1368
lines changed

.github/workflows/cov-badge.svg

Lines changed: 1 addition & 1 deletion
Loading

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,22 @@ By replacing discretionary decisions with deterministic smart contract execution
99

1010
## System Overview
1111

12+
<<<<<<< HEAD
13+
The protocol is composed of three hierarchical layers, each with a clear domain of responsibility, from foundational governance to operational logic and enforcement:
14+
=======
1215
The architecture is composed of three modular layers, each with distinct responsibilities:
16+
>>>>>>> origin/main
1317
1418
![image](https://github.com/user-attachments/assets/a1b2ead5-c1ff-48df-b48b-ff5d46762ac1)
1519

1620
### Level 3 — Rights Management
1721
Executes deterministic policy enforcement in real time, ensuring strict compliance with approved access and usage conditions.
1822

23+
<<<<<<< HEAD
24+
- **Rights**: A module that manages policies authorization, defines usage conditions, and validates content custody. It ensures that only authorized entities can access or manage content, while enforcing predefined rules for usage and custody validation.
25+
=======
1926
- **Rights:** Enforces access and custody conditions at runtime by resolving permissions and validating compliance against approved policies.
27+
>>>>>>> origin/main
2028
2129
### Level 2 — Operational Layer: Assets, Policies, Custody & Finance
2230
Coordinates asset lifecycle, programmable policies, decentralized custody, and financial execution under governance-defined logic.

contracts/core/interfaces/rights/IRightsAssetCustodianVerifiable.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ pragma solidity 0.8.26;
88
interface IRightsAssetCustodianVerifiable {
99
/// @notice Checks whether a custodian is currently assigned to a holder.
1010
/// @dev Returns true only if the custodian is active and listed for the specified holder.
11-
/// @param holder The address of the asset rights holder.
1211
/// @param custodian The address of the custodian to verify.
12+
/// @param holder The address of the asset rights holder.
1313
/// @return True if `custodian` is valid and assigned to `holder`, false otherwise.
14-
function isCustodian(address holder, address custodian) external view returns (bool);
14+
function isCustodian(address custodian, address holder) external view returns (bool);
1515

1616
/// @notice Returns a custodian selected by a probabilistic balancing algorithm.
1717
/// @dev The selection is based on priority, demand and economic weight (balance).
@@ -28,9 +28,9 @@ interface IRightsAssetCustodianVerifiable {
2828

2929
/// @notice Calculates the weighted score of a custodian for a specific holder and currency.
3030
/// @dev Used to externally query the score that influences custodian selection.
31-
/// @param holder The address of the rights holder.
3231
/// @param custodian The address of the custodian.
32+
/// @param holder The address of the rights holder.
3333
/// @param currency The token used to evaluate economic backing.
3434
/// @return The computed weight used in the balancing algorithm.
35-
function calcWeight(address holder, address custodian, address currency) external view returns (uint256);
35+
function calcWeight(address custodian, address holder, address currency) external view returns (uint256);
3636
}

contracts/economics/MMC.sol

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { ERC20Votes } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20
1010

1111
// https://eips.ethereum.org/EIPS/eip-2612 - permit
1212
// https://eips.ethereum.org/EIPS/eip-1363 - payable
13+
// TODO upgradeable feature + DAO
1314

1415
/// @title Multimedia Coin (MMC)
1516
/// @notice ERC20 token with governance and permit functionality.
@@ -22,7 +23,9 @@ contract MMC is ERC20, ERC20Permit, ERC20Votes {
2223
_mint(initialHolder, totalSupply * (10 ** 18));
2324
}
2425

25-
// TODO allowed restricted burn by treasury
26+
function burn(uint256 amount) public virtual {
27+
_burn(msg.sender, amount);
28+
}
2629

2730
/// @inheritdoc IERC20Permit
2831
function nonces(address owner) public view override(ERC20Permit, Nonces) returns (uint256) {

contracts/economics/Tollgate.sol

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ contract Tollgate is Initializable, UUPSUpgradeable, AccessControlledUpgradeable
4141
/// @param currency The address of the unsupported currency.
4242
error UnsupportedCurrency(address target, address currency);
4343

44-
/// @notice Error for invalid target contexts.
44+
/// @notice Error for invalid target scheme.
4545
/// @param target The address of the invalid target context.
46-
error InvalidTargetContext(address target);
46+
error InvalidTargetScheme(address target);
4747

4848
/// @notice Error for invalid basis point fees.
4949
/// @param bps The provided basis point value.
@@ -64,19 +64,24 @@ contract Tollgate is Initializable, UUPSUpgradeable, AccessControlledUpgradeable
6464

6565
/// @notice Allows execution if the scheme is accepted or if support cannot be determined.
6666
/// @dev This modifier checks whether the `target` contract explicitly supports the scheme.
67-
/// If `isFeeSchemeSupported` exists and returns `false`, the call is reverted with InvalidTargetContext.
67+
/// If `isFeeSchemeSupported` exists and returns `false`, the call is reverted with InvalidTargetScheme.
6868
/// If the call to `v` fails (e.g., target does not implement the function or reverts) allowed by default.
6969
/// This enables compatibility with contracts that do not implement scheme validation.
7070
/// @param scheme The scheme to validate.
7171
/// @param target The address of the contract expected to support the scheme.
7272
modifier onlySupportedScheme(T.Scheme scheme, address target) {
73+
// if target is zero address, revert with InvalidTargetScheme error
74+
if (target == address(0) || target.code.length == 0) {
75+
revert InvalidTargetScheme(target);
76+
}
77+
7378
bytes memory callData = abi.encodeCall(IFeeSchemeValidator.isFeeSchemeSupported, (scheme));
7479
(bool success, bytes memory result) = target.call(callData);
7580
// if the call was successful, the target implements the method and returned a result.
7681
// decode the result and validate the scheme acceptance.
7782
if (success) {
7883
bool ok = abi.decode(result, (bool));
79-
if (!ok) revert InvalidTargetContext(target);
84+
if (!ok) revert InvalidTargetScheme(target);
8085
}
8186

8287
// if call fails → by default all schemes are allowed
@@ -144,7 +149,7 @@ contract Tollgate is Initializable, UUPSUpgradeable, AccessControlledUpgradeable
144149
// Example: If the target is the policy manager contract, the currency is MMC (ERC20 token),
145150
// and the scheme is NOMINAL, setting a fee of 10% means:
146151
// "In the policy manager contract, for MMC, using a nominal scheme, the fee is 10%."
147-
if (target == address(0)) revert InvalidTargetContext(target);
152+
if (target == address(0)) revert InvalidTargetScheme(target);
148153
bytes32 composedKey = _computeComposedKey(target, currency, scheme);
149154

150155
_targetScheme[target] = scheme; // eg: rights manager => FLAT

contracts/lifecycle/HookRegistry.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,15 @@ contract HookRegistry is Initializable, UUPSUpgradeable, AccessControlledUpgrade
8484
/// @notice Approves a registered hook contract.
8585
/// @param hook The address of the hook to be approved.
8686
/// Emits a HookApproved event upon success.
87-
function approve(address hook) external onlyValidHook(hook) restricted {
87+
function approve(address hook) external restricted {
8888
_approve(uint160(hook));
8989
emit HookApproved(hook, msg.sender);
9090
}
9191

9292
/// @notice Revokes a previously approved hook contract.
9393
/// @param hook The address of the hook to revoke.
9494
/// Emits a HookRevoked event upon success.
95-
function reject(address hook) external onlyValidHook(hook) restricted {
95+
function reject(address hook) external restricted {
9696
_revoke(uint160(hook));
9797
emit HookRevoked(hook, msg.sender);
9898
}

contracts/policies/PolicyAudit.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,15 @@ contract PolicyAudit is Initializable, UUPSUpgradeable, AccessControlledUpgradea
7575
/// @notice Approves the audit of a given policy by a specified auditor.
7676
/// @param policy The address of the policy to be audited.
7777
/// @dev This function emits the PolicyApproved event upon successful audit approval.
78-
function approve(address policy) external onlyValidPolicy(policy) restricted {
78+
function approve(address policy) external restricted {
7979
_approve(uint160(policy));
8080
emit PolicyApproved(policy, msg.sender);
8181
}
8282

8383
/// @notice Revokes the audit of a given policy by a specified auditor.
8484
/// @param policy The address of the policy whose audit is to be revoked.
8585
/// @dev This function emits the PolicyRevoked event upon successful audit revocation.
86-
function reject(address policy) external onlyValidPolicy(policy) restricted {
86+
function reject(address policy) external restricted {
8787
_revoke(uint160(policy));
8888
emit PolicyRevoked(policy, msg.sender);
8989
}

contracts/rights/RightsAssetCustodian.sol

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ contract RightsAssetCustodian is Initializable, UUPSUpgradeable, AccessControlle
4848
/// @param demand The total number of holders currently assigned to the custodian (under custody).
4949
event CustodialRevoked(address indexed revokedCustody, address indexed rightsHolder, uint256 demand);
5050

51+
/// @notice Emitted when a priority is set or updated for a custodian by a rights holder.
52+
/// @param holder The address of the rights holder.
53+
/// @param custodian The address of the custodian whose priority was updated.
54+
/// @param priority The new priority value set by the holder.
55+
event PrioritySet(address indexed holder, address indexed custodian, uint256 priority);
56+
5157
/// @dev Error that is thrown when a content hash is already registered.
5258
error InvalidInactiveCustodian();
5359

@@ -60,6 +66,10 @@ contract RightsAssetCustodian is Initializable, UUPSUpgradeable, AccessControlle
6066
/// @dev Error when failing to revoke custody from a custodian.
6167
error RevokeCustodyFailed(address custodian, address holder);
6268

69+
/// @dev Error thrown when an invalid priority value is provided.
70+
/// @param priority The invalid priority value provided.
71+
error InvalidPriority(uint256 priority);
72+
6373
/// @dev Modifier to check if the custodian is active and not blocked.
6474
/// @param custodian The custodian address to check.
6575
modifier onlyActiveCustodian(address custodian) {
@@ -158,7 +168,7 @@ contract RightsAssetCustodian is Initializable, UUPSUpgradeable, AccessControlle
158168
/// @notice Checks if the given custodian is a custodian for the specified content holder
159169
/// @param holder The address of the asset holder.
160170
/// @param custodian The address of the custodian to check.
161-
function isCustodian(address holder, address custodian) external view returns (bool) {
171+
function isCustodian(address custodian, address holder) external view returns (bool) {
162172
return _custodians[holder].contains(custodian) && _isValidActiveCustodian(custodian);
163173
}
164174

@@ -288,8 +298,9 @@ contract RightsAssetCustodian is Initializable, UUPSUpgradeable, AccessControlle
288298
/// @param holder The address of the rights holder.
289299
/// @param priority The priority value (minimum 1).
290300
function _setPriority(address custodian, address holder, uint256 priority) private {
291-
bytes32 relation = _computeComposedKey(holder, custodian);
292-
_priority[relation] = priority > 0 ? priority : 1; // default 1
301+
if (priority == 0) revert InvalidPriority(priority);
302+
_priority[_computeComposedKey(holder, custodian)] = priority;
303+
emit PrioritySet(msg.sender, custodian, priority);
293304
}
294305

295306
/// @dev Computes the weight of a custodian using the formula:

0 commit comments

Comments
 (0)