- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
141 lines
5.0 KiB
Solidity
141 lines
5.0 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
import "./interfaces/IDebtRegistry.sol";
|
|
import "./errors/RegistryErrors.sol";
|
|
|
|
/**
|
|
* @title DebtRegistry
|
|
* @notice Manages liens (encumbrances) on accounts for debt/liability enforcement
|
|
* @dev Supports multiple liens per account with aggregation. Uses hard expiry policy - expiry is informational and requires explicit release.
|
|
* Liens are used by eMoneyToken to enforce transfer restrictions (hard freeze or encumbered modes).
|
|
*/
|
|
contract DebtRegistry is IDebtRegistry, AccessControl {
|
|
bytes32 public constant DEBT_AUTHORITY_ROLE = keccak256("DEBT_AUTHORITY_ROLE");
|
|
|
|
uint256 private _nextLienId;
|
|
mapping(uint256 => Lien) private _liens;
|
|
mapping(address => uint256) private _activeEncumbrance;
|
|
mapping(address => uint256) private _activeLienCount;
|
|
|
|
/**
|
|
* @notice Initializes the DebtRegistry with an admin address
|
|
* @param admin Address that will receive DEFAULT_ADMIN_ROLE
|
|
*/
|
|
constructor(address admin) {
|
|
_grantRole(DEFAULT_ADMIN_ROLE, admin);
|
|
}
|
|
|
|
/**
|
|
* @notice Returns the total active encumbrance (sum of all active lien amounts) for a debtor
|
|
* @param debtor Address to check
|
|
* @return Total amount encumbered across all active liens
|
|
*/
|
|
function activeLienAmount(address debtor) external view override returns (uint256) {
|
|
return _activeEncumbrance[debtor];
|
|
}
|
|
|
|
/**
|
|
* @notice Returns whether a debtor has any active liens
|
|
* @param debtor Address to check
|
|
* @return true if debtor has at least one active lien, false otherwise
|
|
*/
|
|
function hasActiveLien(address debtor) external view override returns (bool) {
|
|
return _activeLienCount[debtor] > 0;
|
|
}
|
|
|
|
/**
|
|
* @notice Returns the number of active liens for a debtor
|
|
* @param debtor Address to check
|
|
* @return Count of active liens
|
|
*/
|
|
function activeLienCount(address debtor) external view override returns (uint256) {
|
|
return _activeLienCount[debtor];
|
|
}
|
|
|
|
/**
|
|
* @notice Returns full lien information for a given lien ID
|
|
* @param lienId The lien identifier
|
|
* @return Lien struct containing all lien details
|
|
*/
|
|
function getLien(uint256 lienId) external view override returns (Lien memory) {
|
|
return _liens[lienId];
|
|
}
|
|
|
|
/**
|
|
* @notice Places a new lien on a debtor account
|
|
* @dev Requires DEBT_AUTHORITY_ROLE. Increments active encumbrance and lien count.
|
|
* @param debtor Address to place lien on
|
|
* @param amount Amount to encumber
|
|
* @param expiry Expiry timestamp (0 = no expiry). Note: expiry is informational; explicit release required.
|
|
* @param priority Priority level (0-255)
|
|
* @param reasonCode Reason code for the lien (e.g., ReasonCodes.LIEN_BLOCK)
|
|
* @return lienId The assigned lien identifier
|
|
*/
|
|
function placeLien(
|
|
address debtor,
|
|
uint256 amount,
|
|
uint64 expiry,
|
|
uint8 priority,
|
|
bytes32 reasonCode
|
|
) external override onlyRole(DEBT_AUTHORITY_ROLE) returns (uint256 lienId) {
|
|
if (debtor == address(0)) revert DebtZeroDebtor();
|
|
if (amount == 0) revert DebtZeroAmount();
|
|
|
|
lienId = _nextLienId++;
|
|
_liens[lienId] = Lien({
|
|
debtor: debtor,
|
|
amount: amount,
|
|
expiry: expiry,
|
|
priority: priority,
|
|
authority: msg.sender,
|
|
reasonCode: reasonCode,
|
|
active: true
|
|
});
|
|
|
|
_activeEncumbrance[debtor] += amount;
|
|
_activeLienCount[debtor]++;
|
|
|
|
emit LienPlaced(lienId, debtor, amount, expiry, priority, msg.sender, reasonCode);
|
|
}
|
|
|
|
/**
|
|
* @notice Reduces the amount of an active lien
|
|
* @dev Requires DEBT_AUTHORITY_ROLE. Updates active encumbrance accordingly.
|
|
* @param lienId The lien identifier
|
|
* @param reduceBy Amount to reduce the lien by (must not exceed current lien amount)
|
|
*/
|
|
function reduceLien(uint256 lienId, uint256 reduceBy) external override onlyRole(DEBT_AUTHORITY_ROLE) {
|
|
Lien storage lien = _liens[lienId];
|
|
if (!lien.active) revert DebtLienNotActive(lienId);
|
|
|
|
uint256 oldAmount = lien.amount;
|
|
if (reduceBy > oldAmount) revert DebtReduceByExceedsAmount(lienId, reduceBy, oldAmount);
|
|
|
|
uint256 newAmount = oldAmount - reduceBy;
|
|
lien.amount = newAmount;
|
|
|
|
_activeEncumbrance[lien.debtor] -= reduceBy;
|
|
|
|
emit LienReduced(lienId, reduceBy, newAmount);
|
|
}
|
|
|
|
/**
|
|
* @notice Releases an active lien, removing it from active tracking
|
|
* @dev Requires DEBT_AUTHORITY_ROLE. Decrements active encumbrance and lien count.
|
|
* @param lienId The lien identifier to release
|
|
*/
|
|
function releaseLien(uint256 lienId) external override onlyRole(DEBT_AUTHORITY_ROLE) {
|
|
Lien storage lien = _liens[lienId];
|
|
if (!lien.active) revert DebtLienNotActive(lienId);
|
|
|
|
lien.active = false;
|
|
_activeEncumbrance[lien.debtor] -= lien.amount;
|
|
_activeLienCount[lien.debtor]--;
|
|
|
|
emit LienReleased(lienId);
|
|
}
|
|
}
|
|
|