Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
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>
This commit is contained in:
defiQUG
2026-05-25 00:30:45 -07:00
parent 9a83aa2034
commit c336809676
326 changed files with 21108 additions and 334 deletions

View File

@@ -0,0 +1,230 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Script.sol";
import {RWATokenRegistry} from "../../../contracts/rwa/RWATokenRegistry.sol";
import {RWATokenFactory} from "../../../contracts/rwa/RWATokenFactory.sol";
import {IRWATokenFactory} from "../../../contracts/rwa/IRWATokenFactory.sol";
import {RWAToken} from "../../../contracts/rwa/RWAToken.sol";
import {UniversalAssetRegistry} from "../../../contracts/registry/UniversalAssetRegistry.sol";
/**
* @title DeployRWATokenFactory138
* @notice Deploy RWATokenRegistry + RWATokenFactory and optionally all five Li* M00 indices on Chain 138.
* @dev Taxonomy: config/rwa-capital-markets-taxonomy.v1.json. Not for c* eMoney (use DeployCompliantFiatTokens).
*
* Env:
* PRIVATE_KEY, OWNER, ADMIN, COMPLIANCE_ADMIN, INDEX_PUBLISHER
* UNIVERSAL_ASSET_REGISTRY (optional; pass address for factory wiring only)
* REGISTER_IN_UAR — default 0; use RegisterRWAIndicesInUAR138.s.sol after REGISTRAR_ROLE grant
* DEPLOY_LI_INDICES=1 to deploy LiXAU, LiPMG, LiBMG13 in one run
* RWA_INITIAL_INDEX_VALUE (default 1e6 = 1.0 at 6 decimals)
* RWA_INITIAL_SUPPLY (default 0 — mint via policy after index committee attestation)
* RWA_METHODOLOGY_HASH (required for DEPLOY_LI_INDICES; default from m00-li-index-methodology-hash.v1.json via cast)
* MULTISIG_ADMIN (optional) — grant factory DEPLOYER + registry/UAR REGISTRAR to multisig
*/
contract DeployRWATokenFactory138 is Script {
uint8 constant DECIMALS = 6;
uint256 constant DEFAULT_INDEX_VALUE = 1_000_000;
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address deployer = vm.addr(pk);
address owner = vm.envOr("OWNER", deployer);
address compliance = vm.envOr("COMPLIANCE_ADMIN", deployer);
address publisher = vm.envOr("INDEX_PUBLISHER", deployer);
address uar = vm.envOr("UNIVERSAL_ASSET_REGISTRY", address(0));
// UAR registration reverts if factory lacks REGISTRAR_ROLE — keep off during one-shot deploy.
bool registerInUar = vm.envOr("REGISTER_IN_UAR", uint256(0)) != 0;
require(
!registerInUar || uar != address(0),
"REGISTER_IN_UAR requires UNIVERSAL_ASSET_REGISTRY"
);
uint256 initialIndexValue = vm.envOr("RWA_INITIAL_INDEX_VALUE", DEFAULT_INDEX_VALUE);
uint256 initialSupply = vm.envOr("RWA_INITIAL_SUPPLY", uint256(0));
address multisig = vm.envOr("MULTISIG_ADMIN", address(0));
address governance = vm.envOr("GOVERNANCE_CONTROLLER", address(0));
vm.startBroadcast(pk);
// Deployer holds DEFAULT_ADMIN during bootstrap so grants succeed in one broadcast.
RWATokenRegistry registry = new RWATokenRegistry(deployer);
RWATokenFactory factory = new RWATokenFactory(deployer, address(registry), uar);
registry.grantRole(registry.REGISTRAR_ROLE(), address(factory));
if (registerInUar && uar != address(0)) {
UniversalAssetRegistry(uar).grantRole(
UniversalAssetRegistry(uar).REGISTRAR_ROLE(),
address(factory)
);
}
if (multisig != address(0)) {
factory.grantRole(factory.DEPLOYER_ROLE(), multisig);
registry.grantRole(registry.REGISTRAR_ROLE(), multisig);
}
if (governance != address(0)) {
factory.grantRole(factory.DEFAULT_ADMIN_ROLE(), governance);
registry.grantRole(registry.DEFAULT_ADMIN_ROLE(), governance);
}
console.log("RWATokenRegistry", address(registry));
console.log("RWATokenFactory", address(factory));
if (vm.envOr("DEPLOY_LI_INDICES", uint256(0)) != 0) {
bytes32 methodologyHash = _resolveMethodologyHash();
_deployAllLi(
factory,
owner,
compliance,
publisher,
initialIndexValue,
initialSupply,
registerInUar,
methodologyHash
);
}
vm.stopBroadcast();
}
function _resolveMethodologyHash() internal view returns (bytes32) {
string memory envHash = vm.envOr("RWA_METHODOLOGY_HASH", string(""));
if (bytes(envHash).length > 0) {
return vm.parseBytes32(envHash);
}
revert("RWA_METHODOLOGY_HASH required when DEPLOY_LI_INDICES=1");
}
function _deployAllLi(
RWATokenFactory factory,
address owner,
address compliance,
address publisher,
uint256 initialIndexValue,
uint256 initialSupply,
bool registerInUar,
bytes32 methodologyHash
) internal {
_deployLi(
factory,
owner,
compliance,
publisher,
"LiXAU",
"XAU Liquidity Index (M00)",
"LiXAU",
"Precious Metals",
"Commodity Index",
"Gold",
initialIndexValue,
initialSupply,
registerInUar,
methodologyHash
);
_deployLi(
factory,
owner,
compliance,
publisher,
"LiPMG",
"Precious Metals Group Index (M00)",
"LiPMG",
"Precious Metals",
"Basket Index",
"Precious Metals",
initialIndexValue,
initialSupply,
registerInUar,
methodologyHash
);
_deployLi(
factory,
owner,
compliance,
publisher,
"LiBMG1",
"Base Metals Group Index 1 (M00)",
"LiBMG1",
"Industrial Metals",
"Basket Index",
"Base Metals",
initialIndexValue,
initialSupply,
registerInUar,
methodologyHash
);
_deployLi(
factory,
owner,
compliance,
publisher,
"LiBMG2",
"Base Metals Group Index 2 (M00)",
"LiBMG2",
"Industrial Metals",
"Basket Index",
"Battery Materials",
initialIndexValue,
initialSupply,
registerInUar,
methodologyHash
);
_deployLi(
factory,
owner,
compliance,
publisher,
"LiBMG3",
"Base Metals Group Index 3 (M00)",
"LiBMG3",
"Industrial Metals",
"Basket Index",
"Building Metals",
initialIndexValue,
initialSupply,
registerInUar,
methodologyHash
);
}
function _deployLi(
RWATokenFactory factory,
address owner,
address compliance,
address publisher,
string memory ticker,
string memory name,
string memory symbol,
string memory assetGroup,
string memory instrumentType,
string memory underlying,
uint256 initialIndexValue,
uint256 initialSupply,
bool registerInUar,
bytes32 methodologyHash
) internal {
address token = factory.deployRWAIndex(
IRWATokenFactory.RWAProductConfig({
indexTicker: ticker,
name: name,
symbol: symbol,
decimals: DECIMALS,
assetClass: "Commodities",
assetGroup: assetGroup,
instrumentType: instrumentType,
underlyingAsset: underlying,
gruLayer: "M00",
jurisdiction: "International",
initialOwner: owner,
complianceAdmin: compliance,
indexPublisher: publisher,
initialIndexValue: initialIndexValue,
initialSupply: initialSupply,
methodologyDocumentHash: methodologyHash,
registerInUniversalAssetRegistry: registerInUar
})
);
console.log(ticker, token);
}
}

View File

@@ -0,0 +1,68 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Script.sol";
import {RWATokenRegistry} from "../../../contracts/rwa/RWATokenRegistry.sol";
import {UniversalAssetRegistry} from "../../../contracts/registry/UniversalAssetRegistry.sol";
import {IRWAToken} from "../../../contracts/rwa/IRWAToken.sol";
/**
* @title RegisterRWAIndicesInUAR138
* @notice Register deployed Li* tokens in UniversalAssetRegistry (run after factory deploy + REGISTRAR_ROLE grant).
* @dev Requires RWA_TOKEN_REGISTRY and UNIVERSAL_ASSET_REGISTRY. Broadcaster must hold UAR REGISTRAR_ROLE
* or factory must have been granted REGISTRAR_ROLE and this script calls via factory (not implemented — direct UAR calls).
*
* Env: PRIVATE_KEY, RWA_TOKEN_REGISTRY, UNIVERSAL_ASSET_REGISTRY
* Optional: LI_TICKERS=LiXAU,LiPMG,LiBMG1,LiBMG2,LiBMG3 (default all five)
*/
contract RegisterRWAIndicesInUAR138 is Script {
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address registryAddr = vm.envAddress("RWA_TOKEN_REGISTRY");
address uarAddr = vm.envAddress("UNIVERSAL_ASSET_REGISTRY");
RWATokenRegistry registry = RWATokenRegistry(registryAddr);
UniversalAssetRegistry uar = UniversalAssetRegistry(uarAddr);
vm.startBroadcast(pk);
string memory tickersEnv = vm.envOr("LI_TICKERS", string(""));
if (bytes(tickersEnv).length > 0) {
string[] memory parts = vm.split(tickersEnv, ",");
for (uint256 i = 0; i < parts.length; i++) {
_registerOne(registry, uar, parts[i]);
}
} else {
_registerOne(registry, uar, "LiXAU");
_registerOne(registry, uar, "LiPMG");
_registerOne(registry, uar, "LiBMG1");
_registerOne(registry, uar, "LiBMG2");
_registerOne(registry, uar, "LiBMG3");
}
vm.stopBroadcast();
}
function _registerOne(RWATokenRegistry registry, UniversalAssetRegistry uar, string memory ticker) internal {
address token = registry.getToken(ticker);
require(token != address(0), "token missing");
IRWAToken rwa = IRWAToken(token);
uar.registerRWAIndexAsset(
token,
_nameFor(ticker),
ticker,
6,
"International"
);
console.log("UAR registered", ticker, token);
}
function _nameFor(string memory ticker) internal pure returns (string memory) {
if (keccak256(bytes(ticker)) == keccak256("LiXAU")) return "XAU Liquidity Index (M00)";
if (keccak256(bytes(ticker)) == keccak256("LiPMG")) return "Precious Metals Group Index (M00)";
if (keccak256(bytes(ticker)) == keccak256("LiBMG1")) return "Base Metals Group Index 1 (M00)";
if (keccak256(bytes(ticker)) == keccak256("LiBMG2")) return "Base Metals Group Index 2 (M00)";
if (keccak256(bytes(ticker)) == keccak256("LiBMG3")) return "Base Metals Group Index 3 (M00)";
return ticker;
}
}

View File

@@ -0,0 +1,70 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Script.sol";
import {RWATokenFactory} from "../../../contracts/rwa/RWATokenFactory.sol";
import {RWATokenRegistry} from "../../../contracts/rwa/RWATokenRegistry.sol";
import {PolicyProfileRegistry} from "../../../contracts/universal-resource/PolicyProfileRegistry.sol";
import {OMNLJurisdictionPolicyRegistry} from "../../../contracts/hybx-omnl/OMNLJurisdictionPolicyRegistry.sol";
/**
* @title WireRWATokenFactoryWeb3Controls138
* @notice Post-deploy: C-W3-01 jurisdiction policy, C-W3-08 profile hash, C-W3-04 multisig roles, C-W3-07 governance admin.
* Env: RWA_TOKEN_FACTORY, RWA_TOKEN_REGISTRY, POLICY_PROFILE_REGISTRY, OMNL_JURISDICTION_REGISTRY,
* ID_JURISDICTION_POLICY_HASH, M00_PROFILE_CONTENT_HASH, OMNL_COMPLIANCE_MULTISIG, GOVERNANCE_CONTROLLER
*/
contract WireRWATokenFactoryWeb3Controls138 is Script {
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address factoryAddr = vm.envAddress("RWA_TOKEN_FACTORY");
address multisig = vm.envOr("OMNL_COMPLIANCE_MULTISIG", vm.envOr("MULTISIG_ADMIN", address(0)));
address governance = vm.envOr("GOVERNANCE_CONTROLLER", address(0));
vm.startBroadcast(pk);
RWATokenFactory factory = RWATokenFactory(factoryAddr);
if (multisig != address(0)) {
if (!factory.hasRole(factory.DEPLOYER_ROLE(), multisig)) {
factory.grantRole(factory.DEPLOYER_ROLE(), multisig);
}
console.log("DEPLOYER_ROLE ->", multisig);
}
if (governance != address(0)) {
if (!factory.hasRole(factory.DEFAULT_ADMIN_ROLE(), governance)) {
factory.grantRole(factory.DEFAULT_ADMIN_ROLE(), governance);
}
console.log("DEFAULT_ADMIN_ROLE ->", governance);
}
address pprAddr = vm.envOr("POLICY_PROFILE_REGISTRY", address(0));
if (pprAddr != address(0)) {
bytes32 profileHash = vm.envBytes32("M00_PROFILE_CONTENT_HASH");
PolicyProfileRegistry(pprAddr).publishProfile(
"m00_commodity_index_v1",
profileHash,
1,
block.timestamp
);
console.log("Published m00_commodity_index_v1 on PolicyProfileRegistry");
}
address jurAddr = vm.envOr("OMNL_JURISDICTION_REGISTRY", address(0));
if (jurAddr != address(0)) {
bytes32 idPolicyHash = vm.envBytes32("ID_JURISDICTION_POLICY_HASH");
bytes32 jurisdictionId = keccak256("ID");
OMNLJurisdictionPolicyRegistry(jurAddr).publishPolicy(
jurisdictionId,
idPolicyHash,
3,
2,
2,
true
);
console.log("Published ID jurisdiction policy");
}
vm.stopBroadcast();
}
}