Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m3s
CI/CD Pipeline / Security Scanning (push) Successful in 2m18s
CI/CD Pipeline / Lint and Format (push) Failing after 34s
CI/CD Pipeline / Terraform Validation (push) Failing after 20s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 22s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 40s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 49s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (push) Failing after 21s
Validation / validate-genesis (push) Successful in 25s
Validation / validate-terraform (push) Failing after 21s
Validation / validate-kubernetes (push) Failing after 8s
Validation / validate-smart-contracts (push) Failing after 8s
Validation / validate-security (push) Failing after 1m11s
Validation / validate-documentation (push) Failing after 14s
Verify Deployment / Verify Deployment (push) Failing after 45s
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface, checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services, relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts. Co-authored-by: Cursor <cursoragent@cursor.com>
160 lines
4.8 KiB
Solidity
160 lines
4.8 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
/**
|
|
* @title AddressActivityRegistry
|
|
* @notice Emits Etherscan-indexed Chain 138 payment activity tied to participant addresses (ETH wei + USD e8).
|
|
* @dev Called by checkpoint aggregator after each batch submit and optional v1 TransactionMirror dual-write.
|
|
* Does not move mainnet ETH — attestation / visibility only.
|
|
*/
|
|
contract AddressActivityRegistry {
|
|
uint64 public constant CHAIN_ID = 138;
|
|
uint8 public constant USD_DECIMALS = 8;
|
|
|
|
address public admin;
|
|
bool public paused;
|
|
|
|
struct ActivityRecord {
|
|
bytes32 txHash;
|
|
address from;
|
|
address to;
|
|
uint256 valueWei;
|
|
uint256 blockNumber138;
|
|
uint64 blockTimestamp138;
|
|
uint64 valueUsdE8;
|
|
uint32 logCount;
|
|
bytes32 receiptHash;
|
|
}
|
|
|
|
mapping(bytes32 => bool) public recorded;
|
|
mapping(address => bytes32[]) public participantTxHashes;
|
|
mapping(bytes32 => ActivityRecord) public activities;
|
|
uint256 public totalRecorded;
|
|
|
|
event AdminChanged(address indexed newAdmin);
|
|
event Paused();
|
|
event Unpaused();
|
|
|
|
/// @notice Indexed for Etherscan lookup by participant address (topic2 = participant).
|
|
/// @param chain138TxHash Chain 138 transaction hash (view at explorer.d-bis.org/tx/0x…)
|
|
event ParticipantDebited(
|
|
bytes32 indexed chain138TxHash,
|
|
address indexed counterparty,
|
|
address indexed participant,
|
|
uint64 batchId,
|
|
uint256 valueWei,
|
|
uint64 valueUsdE8,
|
|
uint32 logCount,
|
|
bytes32 receiptHash,
|
|
uint256 blockNumber138
|
|
);
|
|
|
|
/// @param chain138TxHash Chain 138 transaction hash (view at explorer.d-bis.org/tx/0x…)
|
|
event ParticipantCredited(
|
|
bytes32 indexed chain138TxHash,
|
|
address indexed participant,
|
|
address indexed counterparty,
|
|
uint64 batchId,
|
|
uint256 valueWei,
|
|
uint64 valueUsdE8,
|
|
uint32 logCount,
|
|
bytes32 receiptHash,
|
|
uint256 blockNumber138
|
|
);
|
|
|
|
event BatchActivityRecorded(uint64 indexed batchId, uint256 count, uint256 totalValueWei, uint64 totalUsdE8);
|
|
|
|
modifier onlyAdmin() {
|
|
require(msg.sender == admin, "only admin");
|
|
_;
|
|
}
|
|
|
|
modifier whenNotPaused() {
|
|
require(!paused, "paused");
|
|
_;
|
|
}
|
|
|
|
constructor(address _admin) {
|
|
require(_admin != address(0), "zero admin");
|
|
admin = _admin;
|
|
}
|
|
|
|
function setAdmin(address newAdmin) external onlyAdmin {
|
|
require(newAdmin != address(0), "zero admin");
|
|
admin = newAdmin;
|
|
emit AdminChanged(newAdmin);
|
|
}
|
|
|
|
function pause() external onlyAdmin {
|
|
paused = true;
|
|
emit Paused();
|
|
}
|
|
|
|
function unpause() external onlyAdmin {
|
|
paused = false;
|
|
emit Unpaused();
|
|
}
|
|
|
|
/**
|
|
* @notice Record Chain 138 activity for a checkpoint batch (one mainnet tx per batch).
|
|
* @param batchId Checkpoint hub batch id
|
|
* @param records Parallel activity rows (from 138 txs + off-chain USD enrichment)
|
|
*/
|
|
function recordBatch(uint64 batchId, ActivityRecord[] calldata records) external onlyAdmin whenNotPaused {
|
|
uint256 batchValueWei;
|
|
uint64 batchUsdE8;
|
|
uint256 n = records.length;
|
|
for (uint256 i = 0; i < n; i++) {
|
|
ActivityRecord calldata r = records[i];
|
|
require(r.txHash != bytes32(0), "invalid hash");
|
|
require(!recorded[r.txHash], "already recorded");
|
|
|
|
recorded[r.txHash] = true;
|
|
activities[r.txHash] = r;
|
|
totalRecorded++;
|
|
|
|
batchValueWei += r.valueWei;
|
|
batchUsdE8 += r.valueUsdE8;
|
|
|
|
participantTxHashes[r.from].push(r.txHash);
|
|
participantTxHashes[r.to].push(r.txHash);
|
|
|
|
emit ParticipantDebited(
|
|
r.txHash,
|
|
r.to,
|
|
r.from,
|
|
batchId,
|
|
r.valueWei,
|
|
r.valueUsdE8,
|
|
r.logCount,
|
|
r.receiptHash,
|
|
r.blockNumber138
|
|
);
|
|
emit ParticipantCredited(
|
|
r.txHash,
|
|
r.to,
|
|
r.from,
|
|
batchId,
|
|
r.valueWei,
|
|
r.valueUsdE8,
|
|
r.logCount,
|
|
r.receiptHash,
|
|
r.blockNumber138
|
|
);
|
|
}
|
|
emit BatchActivityRecorded(batchId, n, batchValueWei, batchUsdE8);
|
|
}
|
|
|
|
function getParticipantTxCount(address participant) external view returns (uint256) {
|
|
return participantTxHashes[participant].length;
|
|
}
|
|
|
|
function getParticipantTxHash(address participant, uint256 index) external view returns (bytes32) {
|
|
return participantTxHashes[participant][index];
|
|
}
|
|
|
|
function getActivity(bytes32 txHash) external view returns (ActivityRecord memory) {
|
|
return activities[txHash];
|
|
}
|
|
}
|