Initial Meridian Protocol implementation

- Complete MeridianToken standard with compliance & reserve checks
- Multi-custodian ReserveAggregator supporting bank/crypto/fund admin
- Comprehensive Compliance engine with KYC/AML/sanctions
- Full interface definitions and deployment scripts
- Test suite for core functionality
- Ready for GBP launch with Anchorage custody integration
This commit is contained in:
Claude AI
2026-04-16 19:42:26 +00:00
commit 7f001ff5f0
14 changed files with 9906 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title ICompliance
* @dev Interface for KYC, sanctions screening, and AML compliance
*/
interface ICompliance {
struct KYCRecord {
bool isWhitelisted;
uint256 kycLevel; // 1=basic, 2=enhanced, 3=institutional
uint256 whitelistTime;
uint256 expiryTime;
string jurisdiction;
}
struct VelocityLimits {
uint256 dailyLimit;
uint256 monthlyLimit;
uint256 dailySpent;
uint256 monthlySpent;
uint256 lastDayReset;
uint256 lastMonthReset;
}
/**
* @dev Check if address is whitelisted for KYC
* @param account Address to check
* @return isWhitelisted True if account passed KYC
*/
function isWhitelisted(address account) external view returns (bool);
/**
* @dev Check if address is on sanctions list
* @param account Address to check
* @return isSanctioned True if account is sanctioned
*/
function isSanctioned(address account) external view returns (bool);
/**
* @dev Check velocity limits for transaction
* @param account Address making transaction
* @param amount Transaction amount
* @return withinLimits True if transaction is within velocity limits
*/
function checkVelocityLimits(address account, uint256 amount) external view returns (bool withinLimits);
/**
* @dev Get KYC record for address
* @param account Address to query
*/
function getKYCRecord(address account) external view returns (KYCRecord memory);
/**
* @dev Get velocity limits for address
* @param account Address to query
*/
function getVelocityLimits(address account) external view returns (VelocityLimits memory);
/**
* @dev Update velocity tracking after transaction
* @param account Address that made transaction
* @param amount Transaction amount
*/
function updateVelocityTracking(address account, uint256 amount) external;
/**
* @dev Check if transaction should trigger AML reporting
* @param from Sender address
* @param to Recipient address
* @param amount Transaction amount
* @return shouldReport True if transaction exceeds reporting thresholds
* @return reportType Type of report needed (1=CTR, 2=SAR, etc.)
*/
function checkReportingThresholds(
address from,
address to,
uint256 amount
) external view returns (bool shouldReport, uint8 reportType);
// Events
event AccountWhitelisted(address indexed account, uint256 kycLevel, string jurisdiction);
event AccountBlacklisted(address indexed account, string reason);
event SanctionsListUpdated(uint256 newListHash);
event VelocityLimitsUpdated(address indexed account, uint256 dailyLimit, uint256 monthlyLimit);
event ReportingThresholdTriggered(address indexed from, address indexed to, uint256 amount, uint8 reportType);
event VelocityLimitExceeded(address indexed account, uint256 attempted, uint256 remaining);
}

View File

@@ -0,0 +1,66 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title IReserveAggregator
* @dev Interface for reserve aggregation from multiple custodians
*/
interface IReserveAggregator {
struct CustodianInfo {
string name;
address oracle;
uint256 lastUpdateTime;
uint256 heartbeat; // maximum staleness in seconds
bool isActive;
uint8 custodianType; // 0=bank, 1=crypto, 2=fund_admin
}
struct ReserveAttestation {
uint256 balance;
uint256 timestamp;
bytes32 documentHash;
address attestor;
bool isValid;
}
/**
* @dev Get total reserve value across all active custodians
* @return totalValue Total reserve value in token denomination
* @return isValid Whether all required custodian data is current
*/
function getTotalReserveValue() external view returns (uint256 totalValue, bool isValid);
/**
* @dev Get reserve value from specific custodian
* @param custodianId Unique identifier for custodian
* @return value Reserve value from this custodian
* @return isValid Whether this custodian's data is current
*/
function getCustodianReserveValue(bytes32 custodianId) external view returns (uint256 value, bool isValid);
/**
* @dev Get custodian information
* @param custodianId Unique identifier for custodian
*/
function getCustodianInfo(bytes32 custodianId) external view returns (CustodianInfo memory);
/**
* @dev Get latest attestation for a custodian
* @param custodianId Unique identifier for custodian
*/
function getLatestAttestation(bytes32 custodianId) external view returns (ReserveAttestation memory);
/**
* @dev Check if reserve data is stale for any custodian
* @return isStale True if any custodian data exceeds heartbeat
* @return staleCustodians Array of custodian IDs with stale data
*/
function checkDataStaleness() external view returns (bool isStale, bytes32[] memory staleCustodians);
// Events
event CustodianAdded(bytes32 indexed custodianId, string name, address oracle);
event CustodianUpdated(bytes32 indexed custodianId, address newOracle, uint256 newHeartbeat);
event CustodianDeactivated(bytes32 indexed custodianId);
event ReserveAttested(bytes32 indexed custodianId, uint256 balance, bytes32 documentHash);
event StaleDataDetected(bytes32 indexed custodianId, uint256 lastUpdate, uint256 heartbeat);
}