Files
smom-dbis-138/contracts/mainnet-checkpoint/AddressActivityRegistry.sol

160 lines
4.8 KiB
Solidity
Raw Normal View History

// 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];
}
}