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>
145 lines
4.4 KiB
Solidity
145 lines
4.4 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
/**
|
|
* @title AddressActivityRegistryV2
|
|
* @notice MT-103 / pacs.008-equivalent attestation on mainnet (indexed instructionId + UETR + payloadHash).
|
|
* @dev Complements V1 registry; does not move mainnet ETH.
|
|
*/
|
|
contract AddressActivityRegistryV2 {
|
|
uint64 public constant CHAIN_ID = 138;
|
|
uint8 public constant MSG_MT103 = 1;
|
|
uint8 public constant MSG_PACS008 = 2;
|
|
uint8 public constant MSG_PAIN001 = 3;
|
|
uint8 public constant MSG_CHAIN138_SYNTH = 4;
|
|
|
|
address public admin;
|
|
bool public paused;
|
|
|
|
struct IsoAttestationRecord {
|
|
bytes32 txHash;
|
|
address from;
|
|
address to;
|
|
uint256 valueWei;
|
|
uint256 blockNumber138;
|
|
uint64 blockTimestamp138;
|
|
uint64 valueUsdE8;
|
|
uint32 logCount;
|
|
bytes32 receiptHash;
|
|
bytes32 instructionId;
|
|
bytes32 endToEndIdHash;
|
|
bytes32 uetr;
|
|
bytes32 payloadHash;
|
|
uint8 msgTypeCode;
|
|
bytes32 debtorRefHash;
|
|
bytes32 creditorRefHash;
|
|
bytes32 purposeHash;
|
|
}
|
|
|
|
mapping(bytes32 => bool) public recorded;
|
|
mapping(bytes32 => IsoAttestationRecord) public attestations;
|
|
mapping(address => bytes32[]) public participantTxHashes;
|
|
mapping(bytes32 => bool) public processedInstructions;
|
|
uint256 public totalRecorded;
|
|
|
|
event AdminChanged(address indexed newAdmin);
|
|
event Paused();
|
|
event Unpaused();
|
|
|
|
/// @param chain138TxHash Chain 138 tx (topic1 on Etherscan)
|
|
/// @param instructionId MT :20 / pacs.008 InstrId (hashed if needed)
|
|
/// @param uetr SWIFT UETR (bytes32; zero if N/A)
|
|
event PaymentAttested(
|
|
bytes32 indexed chain138TxHash,
|
|
bytes32 indexed instructionId,
|
|
address indexed creditor,
|
|
address debtor,
|
|
bytes32 uetr,
|
|
uint64 batchId,
|
|
uint8 msgTypeCode,
|
|
uint256 valueWei,
|
|
uint64 valueUsdE8,
|
|
bytes32 payloadHash,
|
|
bytes32 endToEndIdHash,
|
|
bytes32 debtorRefHash,
|
|
bytes32 creditorRefHash,
|
|
bytes32 purposeHash,
|
|
bytes32 receiptHash,
|
|
uint256 blockNumber138
|
|
);
|
|
|
|
event BatchIsoAttestationRecorded(uint64 indexed batchId, uint256 count, bytes32 batchPayloadRoot);
|
|
|
|
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();
|
|
}
|
|
|
|
function recordBatch(uint64 batchId, IsoAttestationRecord[] calldata records) external onlyAdmin whenNotPaused {
|
|
uint256 n = records.length;
|
|
bytes32 batchRoot;
|
|
for (uint256 i = 0; i < n; i++) {
|
|
IsoAttestationRecord calldata r = records[i];
|
|
require(r.txHash != bytes32(0), "invalid hash");
|
|
require(!recorded[r.txHash], "already recorded");
|
|
require(!processedInstructions[r.instructionId], "instruction used");
|
|
recorded[r.txHash] = true;
|
|
processedInstructions[r.instructionId] = true;
|
|
attestations[r.txHash] = r;
|
|
totalRecorded++;
|
|
participantTxHashes[r.from].push(r.txHash);
|
|
participantTxHashes[r.to].push(r.txHash);
|
|
batchRoot = keccak256(abi.encodePacked(batchRoot, r.payloadHash));
|
|
emit PaymentAttested(
|
|
r.txHash,
|
|
r.instructionId,
|
|
r.to,
|
|
r.from,
|
|
r.uetr,
|
|
batchId,
|
|
r.msgTypeCode,
|
|
r.valueWei,
|
|
r.valueUsdE8,
|
|
r.payloadHash,
|
|
r.endToEndIdHash,
|
|
r.debtorRefHash,
|
|
r.creditorRefHash,
|
|
r.purposeHash,
|
|
r.receiptHash,
|
|
r.blockNumber138
|
|
);
|
|
}
|
|
emit BatchIsoAttestationRecorded(batchId, n, batchRoot);
|
|
}
|
|
|
|
function getAttestation(bytes32 txHash) external view returns (IsoAttestationRecord memory) {
|
|
return attestations[txHash];
|
|
}
|
|
}
|