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();
}
}

View File

@@ -18,54 +18,68 @@ import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
* CUSDC_ADDRESS_138 - (optional) Compliant USDC; if set, creates vault → acUSDC + vdcUSDC.
* CUSDT_ADDRESS_138 - (optional) Compliant USDT; if set, creates vault → acUSDT + vdcUSDT.
* COMPLIANT_USDC_ADDRESS, COMPLIANT_USDT_ADDRESS - Fallback env names if CUSDC/CUSDT_138 unset.
* cEURC_ADDRESS_138, cEURT_ADDRESS_138, cGBPC_ADDRESS_138, cGBPT_ADDRESS_138,
* cAUDC_ADDRESS_138, cJPYC_ADDRESS_138, cCHFC_ADDRESS_138, cCADC_ADDRESS_138,
* cXAUC_ADDRESS_138, cXAUT_ADDRESS_138 - Optional additional base tokens (6 decimals).
*/
contract DeployAcVdcSdcVaults is Script {
uint8 constant DECIMALS = 6;
bool constant DEBT_TRANSFERABLE = true;
struct TokenSpec {
string envPrimary;
string envAlt;
string label;
}
TokenSpec[] internal tokens;
function _initTokens() internal {
tokens.push(TokenSpec("CUSDC_ADDRESS_138", "COMPLIANT_USDC_ADDRESS", "USDC"));
tokens.push(TokenSpec("CUSDT_ADDRESS_138", "COMPLIANT_USDT_ADDRESS", "USDT"));
tokens.push(TokenSpec("cEURC_ADDRESS_138", "", "EURC"));
tokens.push(TokenSpec("cEURT_ADDRESS_138", "", "EURT"));
tokens.push(TokenSpec("cGBPC_ADDRESS_138", "", "GBPC"));
tokens.push(TokenSpec("cGBPT_ADDRESS_138", "", "GBPT"));
tokens.push(TokenSpec("cAUDC_ADDRESS_138", "", "AUDC"));
tokens.push(TokenSpec("cJPYC_ADDRESS_138", "", "JPYC"));
tokens.push(TokenSpec("cCHFC_ADDRESS_138", "", "CHFC"));
tokens.push(TokenSpec("cCADC_ADDRESS_138", "", "CADC"));
tokens.push(TokenSpec("cXAUC_ADDRESS_138", "", "XAUC"));
tokens.push(TokenSpec("cXAUT_ADDRESS_138", "", "XAUT"));
}
function run() external {
_initTokens();
uint256 pk = vm.envUint("PRIVATE_KEY");
address deployer = vm.addr(pk);
address owner = vm.envOr("OWNER", deployer);
address entity = vm.envOr("ENTITY", deployer);
address factoryAddr = vm.envAddress("VAULT_FACTORY_ADDRESS");
if (factoryAddr == address(0)) {
factoryAddr = vm.envOr("VAULT_FACTORY", address(0));
}
require(factoryAddr != address(0), "VAULT_FACTORY_ADDRESS required");
VaultFactory factory = VaultFactory(factoryAddr);
address cUsdc = _getToken("CUSDC_ADDRESS_138", "COMPLIANT_USDC_ADDRESS");
address cUsdt = _getToken("CUSDT_ADDRESS_138", "COMPLIANT_USDT_ADDRESS");
vm.startBroadcast(pk);
if (cUsdc != address(0)) {
for (uint256 i = 0; i < tokens.length; i++) {
address base = _getToken(tokens[i].envPrimary, tokens[i].envAlt);
if (base == address(0)) continue;
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimals(
owner,
entity,
cUsdc,
cUsdc,
base,
base,
DECIMALS,
DECIMALS,
DEBT_TRANSFERABLE
);
console.log("USDC vault:", vault);
console.log("acUSDC (deposit):", depositToken);
console.log("vdcUSDC (debt):", debtToken);
}
if (cUsdt != address(0)) {
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimals(
owner,
entity,
cUsdt,
cUsdt,
DECIMALS,
DECIMALS,
DEBT_TRANSFERABLE
);
console.log("USDT vault:", vault);
console.log("acUSDT (deposit):", depositToken);
console.log("vdcUSDT (debt):", debtToken);
console.log(string.concat(tokens[i].label, " vault:"), vault);
console.log(string.concat("ac", tokens[i].label, " (deposit):"), depositToken);
console.log(string.concat("vdc", tokens[i].label, " (debt):"), debtToken);
}
vm.stopBroadcast();

View File

@@ -0,0 +1,56 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console} from "forge-std/Script.sol";
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
/// @notice M1 vault basket for ALL Mainnet (651940): AUSDC, AUSDT, WALL.
contract DeployAcVdcSdcVaults651940 is Script {
uint8 constant DECIMALS = 6;
bool constant DEBT_TRANSFERABLE = true;
uint8 constant GRU_TIER_M1 = 2;
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address deployer = vm.addr(pk);
address owner = vm.envOr("OWNER", deployer);
address entity = vm.envOr("ENTITY", vm.envOr("GRU_OMNL_ENTITY_ADDRESS", deployer));
address factoryAddr = vm.envAddress("VAULT_FACTORY_ADDRESS");
VaultFactory factory = VaultFactory(factoryAddr);
bytes32 ibanHash = vm.envBytes32("GRU_IBAN_HASH");
bytes32 policyProfileKey = vm.envOr("GRU_POLICY_PROFILE_KEY", bytes32(0));
address[] memory bases = new address[](3);
string[] memory labels = new string[](3);
bases[0] = vm.envAddress("CUSDC_ADDRESS_651940");
labels[0] = "AUSDC";
bases[1] = vm.envAddress("AUSDT_ADDRESS_651940");
labels[1] = "AUSDT";
bases[2] = vm.envAddress("WALL_ADDRESS_651940");
labels[2] = "WALL";
uint256 startIdx = vm.envOr("GRU_VAULT_START_INDEX", uint256(0));
uint256 endIdx = vm.envOr("GRU_VAULT_END_INDEX", bases.length);
vm.startBroadcast(pk);
for (uint256 i = startIdx; i < endIdx && i < bases.length; i++) {
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimalsGRU(
owner,
entity,
bases[i],
bases[i],
DECIMALS,
DECIMALS,
DEBT_TRANSFERABLE,
GRU_TIER_M1,
ibanHash,
policyProfileKey
);
console.log(string.concat(labels[i], " vault:"), vault);
console.log(string.concat("ac", labels[i], ":"), depositToken);
console.log(string.concat("vdc", labels[i], ":"), debtToken);
}
vm.stopBroadcast();
}
}

View File

@@ -0,0 +1,85 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console} from "forge-std/Script.sol";
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
/**
* @title DeployAcVdcSdcVaultsGRU
* @notice Create M1 ac/vdc vault pairs with GRU tier + IBAN + policy profile anchors.
*/
contract DeployAcVdcSdcVaultsGRU is Script {
uint8 constant DECIMALS = 6;
bool constant DEBT_TRANSFERABLE = true;
uint8 constant GRU_TIER_M1 = 2;
struct TokenSpec {
string envPrimary;
string envAlt;
string label;
}
TokenSpec[] internal tokens;
function _initTokens() internal {
tokens.push(TokenSpec("CUSDC_ADDRESS_138", "COMPLIANT_USDC_ADDRESS", "USDC"));
tokens.push(TokenSpec("CUSDT_ADDRESS_138", "COMPLIANT_USDT_ADDRESS", "USDT"));
tokens.push(TokenSpec("cEURC_ADDRESS_138", "", "EURC"));
tokens.push(TokenSpec("cEURT_ADDRESS_138", "", "EURT"));
tokens.push(TokenSpec("cGBPC_ADDRESS_138", "", "GBPC"));
tokens.push(TokenSpec("cGBPT_ADDRESS_138", "", "GBPT"));
tokens.push(TokenSpec("cAUDC_ADDRESS_138", "", "AUDC"));
tokens.push(TokenSpec("cJPYC_ADDRESS_138", "", "JPYC"));
tokens.push(TokenSpec("cCHFC_ADDRESS_138", "", "CHFC"));
tokens.push(TokenSpec("cCADC_ADDRESS_138", "", "CADC"));
tokens.push(TokenSpec("cXAUC_ADDRESS_138", "", "XAUC"));
tokens.push(TokenSpec("cXAUT_ADDRESS_138", "", "XAUT"));
}
function run() external {
_initTokens();
uint256 pk = vm.envUint("PRIVATE_KEY");
address deployer = vm.addr(pk);
address owner = vm.envOr("OWNER", deployer);
address entity = vm.envOr("ENTITY", vm.envOr("GRU_OMNL_ENTITY_ADDRESS", deployer));
address factoryAddr = vm.envAddress("VAULT_FACTORY_ADDRESS");
VaultFactory factory = VaultFactory(factoryAddr);
bytes32 ibanHash = vm.envBytes32("GRU_IBAN_HASH");
bytes32 policyProfileKey = vm.envOr("GRU_POLICY_PROFILE_KEY", bytes32(0));
uint256 startIdx = vm.envOr("GRU_VAULT_START_INDEX", uint256(0));
uint256 endIdx = vm.envOr("GRU_VAULT_END_INDEX", tokens.length);
vm.startBroadcast(pk);
for (uint256 i = startIdx; i < endIdx && i < tokens.length; i++) {
address base = _getToken(tokens[i].envPrimary, tokens[i].envAlt);
if (base == address(0)) continue;
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimalsGRU(
owner,
entity,
base,
base,
DECIMALS,
DECIMALS,
DEBT_TRANSFERABLE,
GRU_TIER_M1,
ibanHash,
policyProfileKey
);
console.log(string.concat(tokens[i].label, " vault:"), vault);
console.log(string.concat("ac", tokens[i].label, ":"), depositToken);
console.log(string.concat("vdc", tokens[i].label, ":"), debtToken);
}
vm.stopBroadcast();
}
function _getToken(string memory primary, string memory altKey) internal view returns (address) {
address a = vm.envOr(primary, address(0));
if (a != address(0)) return a;
if (bytes(altKey).length == 0) return address(0);
return vm.envOr(altKey, address(0));
}
}

View File

@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console2} from "forge-std/Script.sol";
import {CREATE2Factory} from "../../../contracts/utils/CREATE2Factory.sol";
/// @notice Deploy CREATE2Factory when missing on target chain (one-time CREATE).
contract DeployCREATE2FactoryIfNeeded is Script {
function run() external {
address existing = vm.envOr("CREATE2_FACTORY_ADDRESS", address(0));
if (existing != address(0) && existing.code.length > 0) {
console2.log("CREATE2Factory already live:", existing);
return;
}
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
CREATE2Factory factory = new CREATE2Factory();
vm.stopBroadcast();
console2.log("CREATE2Factory deployed:", address(factory));
}
}

View File

@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console2} from "forge-std/Script.sol";
import {GRUEntityIbanRegistry} from "../../../contracts/vault/GRUEntityIbanRegistry.sol";
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
/// @notice Deploy GRU protocol registries and wire an existing or new VaultFactory.
/// @dev Run after DeployVaultSystem or pass VAULT_FACTORY_ADDRESS to wire index on live factory.
contract DeployGRUVaultProtocol is Script {
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address admin = vm.envOr("GRU_VAULT_ADMIN", vm.addr(pk));
vm.startBroadcast(pk);
GRUEntityIbanRegistry ibanRegistry = new GRUEntityIbanRegistry(admin);
GRUVaultIndex vaultIndex = new GRUVaultIndex(admin);
address factoryAddr = vm.envOr("VAULT_FACTORY_ADDRESS", address(0));
if (factoryAddr != address(0)) {
VaultFactory(factoryAddr).setGruVaultIndex(address(vaultIndex));
vaultIndex.grantFactoryRole(factoryAddr);
console2.log("Wired VaultFactory", factoryAddr);
}
vm.stopBroadcast();
console2.log("GRUEntityIbanRegistry", address(ibanRegistry));
console2.log("GRUVaultIndex", address(vaultIndex));
console2.log("admin", admin);
}
}

View File

@@ -0,0 +1,50 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console2} from "forge-std/Script.sol";
import {CREATE2Factory} from "../../../contracts/utils/CREATE2Factory.sol";
import {GRUEntityIbanRegistry} from "../../../contracts/vault/GRUEntityIbanRegistry.sol";
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
/// @notice Deterministic GRU registry deploy via CREATE2Factory (cross-chain parity).
contract DeployGRUVaultRegistriesCreate2 is Script {
uint256 constant SALT_IBAN = uint256(keccak256("GRUEntityIbanRegistry"));
uint256 constant SALT_INDEX = uint256(keccak256("GRUVaultIndex"));
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address admin = vm.envOr("GRU_VAULT_ADMIN", vm.addr(pk));
address factoryAddr = vm.envAddress("CREATE2_FACTORY_ADDRESS");
CREATE2Factory factory = CREATE2Factory(factoryAddr);
bytes memory ibanInit = abi.encodePacked(type(GRUEntityIbanRegistry).creationCode, abi.encode(admin));
bytes memory indexInit = abi.encodePacked(type(GRUVaultIndex).creationCode, abi.encode(admin));
address predictedIban = factory.computeAddress(ibanInit, SALT_IBAN);
address predictedIndex = factory.computeAddress(indexInit, SALT_INDEX);
vm.startBroadcast(pk);
address ibanReg = predictedIban.code.length > 0
? predictedIban
: factory.deploy(ibanInit, SALT_IBAN);
address vaultIndex = predictedIndex.code.length > 0
? predictedIndex
: factory.deploy(indexInit, SALT_INDEX);
address factoryAddrVault = vm.envOr("VAULT_FACTORY_ADDRESS", address(0));
if (factoryAddrVault != address(0) && factoryAddrVault.code.length > 0) {
VaultFactory(factoryAddrVault).setGruVaultIndex(vaultIndex);
GRUVaultIndex(vaultIndex).grantFactoryRole(factoryAddrVault);
console2.log("Wired VaultFactory", factoryAddrVault);
}
vm.stopBroadcast();
console2.log("CREATE2Factory", factoryAddr);
console2.log("GRUEntityIbanRegistry", ibanReg);
console2.log("GRUVaultIndex", vaultIndex);
}
}

View File

@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console2} from "forge-std/Script.sol";
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
/// @notice Deploy GRUVaultIndex v2 (patch + import support) on hub 138.
contract DeployNewGRUVaultIndex138 is Script {
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address admin = vm.addr(pk);
vm.startBroadcast(pk);
GRUVaultIndex idx = new GRUVaultIndex(admin);
vm.stopBroadcast();
console2.log("GRUVaultIndex:", address(idx));
}
}

View File

@@ -0,0 +1,50 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console} from "forge-std/Script.sol";
import {Vault} from "../../../contracts/vault/Vault.sol";
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
import {DepositToken} from "../../../contracts/vault/tokens/DepositToken.sol";
import {DebtToken} from "../../../contracts/vault/tokens/DebtToken.sol";
import {Ledger} from "../../../contracts/vault/Ledger.sol";
import {RegulatedEntityRegistry} from "../../../contracts/vault/RegulatedEntityRegistry.sol";
/// @notice Deploy VaultFactory on 651940 after core system addresses are live.
contract DeployVaultFactory651940 is Script {
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address admin = vm.addr(pk);
RegulatedEntityRegistry entityRegistry =
RegulatedEntityRegistry(vm.envAddress("REGULATED_ENTITY_REGISTRY"));
Ledger ledger = Ledger(vm.envAddress("LEDGER_ADDRESS"));
address collateralAdapter = vm.envAddress("COLLATERAL_ADAPTER_ADDRESS");
address eMoneyJoinAddr = vm.envAddress("EMONEY_JOIN_ADDRESS");
vm.startBroadcast(pk);
Vault vaultImpl = new Vault(
admin, admin, address(ledger), address(entityRegistry), collateralAdapter, eMoneyJoinAddr
);
DepositToken depositTokenImpl = new DepositToken();
DebtToken debtTokenImpl = new DebtToken();
VaultFactory vaultFactory = new VaultFactory(
admin,
address(vaultImpl),
address(depositTokenImpl),
address(debtTokenImpl),
address(ledger),
address(entityRegistry),
collateralAdapter,
eMoneyJoinAddr
);
console.log("Vault Factory:", address(vaultFactory));
ledger.grantRole(ledger.VAULT_FACTORY_ROLE(), address(vaultFactory));
entityRegistry.grantRole(entityRegistry.REGISTRAR_ROLE(), address(vaultFactory));
vm.stopBroadcast();
console.log("=== [651940] VaultFactory wired ===");
}
}

View File

@@ -126,8 +126,8 @@ contract DeployVaultSystem is Script {
// Step 10: Grant roles and configure
console.log("\n10. Configuring roles and parameters...");
// Grant factory vault role
ledger.grantVaultRole(address(vaultFactory));
// Grant factory permission to register vaults on ledger
ledger.grantRole(ledger.VAULT_FACTORY_ROLE(), address(vaultFactory));
// Set risk parameters (registers assets and sets params)
ledger.setRiskParameters(
@@ -146,7 +146,7 @@ contract DeployVaultSystem is Script {
}
// Grant factory role to create vaults
entityRegistry.grantRole(keccak256("ENTITY_REGISTRAR_ROLE"), address(vaultFactory));
entityRegistry.grantRole(entityRegistry.REGISTRAR_ROLE(), address(vaultFactory));
vm.stopBroadcast();

View File

@@ -0,0 +1,71 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console} from "forge-std/Script.sol";
import {RegulatedEntityRegistry} from "../../../contracts/vault/RegulatedEntityRegistry.sol";
import {XAUOracle} from "../../../contracts/vault/XAUOracle.sol";
import {RateAccrual} from "../../../contracts/vault/RateAccrual.sol";
import {Ledger} from "../../../contracts/vault/Ledger.sol";
import {Liquidation} from "../../../contracts/vault/Liquidation.sol";
import {CollateralAdapter} from "../../../contracts/vault/adapters/CollateralAdapter.sol";
import {eMoneyJoin} from "../../../contracts/vault/adapters/eMoneyJoin.sol";
import {Aggregator} from "../../../contracts/oracle/Aggregator.sol";
/// @notice Deploy vault system core on ALL Mainnet (651940) without VaultFactory (forge broadcast workaround).
contract DeployVaultSystem651940Core is Script {
uint256 public constant DEFAULT_LIQUIDATION_RATIO = 10000;
uint256 public constant DEFAULT_CREDIT_MULTIPLIER = 50000;
uint256 public constant DEFAULT_DEBT_CEILING = 1000000e18;
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address admin = vm.addr(pk);
address treasury = vm.envOr("TREASURY_ADDRESS", admin);
address ethAddress = address(0);
vm.startBroadcast(pk);
console.log("=== [651940] Vault system core ===");
RegulatedEntityRegistry entityRegistry = new RegulatedEntityRegistry(admin);
console.log("RegulatedEntityRegistry:", address(entityRegistry));
Aggregator ethPriceFeed = new Aggregator("ETH/XAU", admin, 3600, 50);
ethPriceFeed.addTransmitter(admin);
ethPriceFeed.updateAnswer(0.05e18);
console.log("ETH Price Feed:", address(ethPriceFeed));
Aggregator btcPriceFeed = new Aggregator("BTC/XAU", admin, 3600, 50);
btcPriceFeed.addTransmitter(admin);
btcPriceFeed.updateAnswer(0.5e18);
console.log("BTC Price Feed:", address(btcPriceFeed));
XAUOracle xauOracle = new XAUOracle(admin);
xauOracle.addPriceFeed(address(ethPriceFeed), 10000);
xauOracle.addPriceFeed(address(btcPriceFeed), 10000);
xauOracle.updatePrice();
console.log("XAU Oracle:", address(xauOracle));
RateAccrual rateAccrual = new RateAccrual(admin);
rateAccrual.setInterestRate(address(0), 500);
console.log("Rate Accrual:", address(rateAccrual));
Ledger ledger = new Ledger(admin, address(xauOracle), address(rateAccrual));
console.log("Ledger:", address(ledger));
Liquidation liquidation = new Liquidation(admin, address(ledger), address(xauOracle), treasury);
console.log("Liquidation:", address(liquidation));
CollateralAdapter collateralAdapter = new CollateralAdapter(admin, address(ledger));
console.log("Collateral Adapter:", address(collateralAdapter));
eMoneyJoin eMoneyJoinContract = new eMoneyJoin(admin);
console.log("eMoney Join:", address(eMoneyJoinContract));
ledger.setRiskParameters(
ethAddress, DEFAULT_DEBT_CEILING, DEFAULT_LIQUIDATION_RATIO, DEFAULT_CREDIT_MULTIPLIER
);
vm.stopBroadcast();
console.log("=== [651940] core complete (VaultFactory separate) ===");
}
}

View File

@@ -0,0 +1,94 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console} from "forge-std/Script.sol";
import {Ledger} from "../../../contracts/vault/Ledger.sol";
import {RegulatedEntityRegistry} from "../../../contracts/vault/RegulatedEntityRegistry.sol";
import {XAUOracle} from "../../../contracts/vault/XAUOracle.sol";
import {RateAccrual} from "../../../contracts/vault/RateAccrual.sol";
import {Liquidation} from "../../../contracts/vault/Liquidation.sol";
import {CollateralAdapter} from "../../../contracts/vault/adapters/CollateralAdapter.sol";
import {eMoneyJoin} from "../../../contracts/vault/adapters/eMoneyJoin.sol";
import {Vault} from "../../../contracts/vault/Vault.sol";
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
import {DepositToken} from "../../../contracts/vault/tokens/DepositToken.sol";
import {DebtToken} from "../../../contracts/vault/tokens/DebtToken.sol";
import {Aggregator} from "../../../contracts/oracle/Aggregator.sol";
/**
* @title DeployVaultSystemFinish
* @notice Resume vault system deploy when DeployVaultSystem broadcast stalled mid-flight.
* @dev Requires env addresses for components already on-chain (see run-gru-vault-protocol-operator.sh).
*/
contract DeployVaultSystemFinish is Script {
uint256 public constant DEFAULT_LIQUIDATION_RATIO = 10000;
uint256 public constant DEFAULT_CREDIT_MULTIPLIER = 50000;
uint256 public constant DEFAULT_DEBT_CEILING = 1000000e18;
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address admin = vm.addr(pk);
address treasury = vm.envOr("TREASURY_ADDRESS", admin);
address ethAddress = address(0);
RegulatedEntityRegistry entityRegistry =
RegulatedEntityRegistry(vm.envAddress("REGULATED_ENTITY_REGISTRY"));
XAUOracle xauOracle = XAUOracle(vm.envAddress("XAU_ORACLE_ADDRESS"));
address ethPriceFeed = vm.envAddress("ETH_PRICE_FEED_ADDRESS");
address btcPriceFeed = vm.envAddress("BTC_PRICE_FEED_ADDRESS");
vm.startBroadcast(pk);
console.log("=== Finishing Vault System (from XAUOracle config) ===");
xauOracle.addPriceFeed(ethPriceFeed, 10000);
xauOracle.addPriceFeed(btcPriceFeed, 10000);
Aggregator(ethPriceFeed).updateAnswer(0.05e18);
Aggregator(btcPriceFeed).updateAnswer(0.5e18);
xauOracle.updatePrice();
console.log("XAUOracle configured");
RateAccrual rateAccrual = new RateAccrual(admin);
rateAccrual.setInterestRate(address(0), 500);
console.log("RateAccrual:", address(rateAccrual));
Ledger ledger = new Ledger(admin, address(xauOracle), address(rateAccrual));
console.log("Ledger:", address(ledger));
Liquidation liquidation = new Liquidation(admin, address(ledger), address(xauOracle), treasury);
console.log("Liquidation:", address(liquidation));
CollateralAdapter collateralAdapter = new CollateralAdapter(admin, address(ledger));
console.log("Collateral Adapter:", address(collateralAdapter));
eMoneyJoin eMoneyJoinContract = new eMoneyJoin(admin);
console.log("eMoney Join:", address(eMoneyJoinContract));
Vault vaultImpl = new Vault(
admin, admin, address(ledger), address(entityRegistry), address(collateralAdapter), address(eMoneyJoinContract)
);
DepositToken depositTokenImpl = new DepositToken();
DebtToken debtTokenImpl = new DebtToken();
VaultFactory vaultFactory = new VaultFactory(
admin,
address(vaultImpl),
address(depositTokenImpl),
address(debtTokenImpl),
address(ledger),
address(entityRegistry),
address(collateralAdapter),
address(eMoneyJoinContract)
);
console.log("Vault Factory:", address(vaultFactory));
ledger.grantRole(ledger.VAULT_FACTORY_ROLE(), address(vaultFactory));
ledger.setRiskParameters(ethAddress, DEFAULT_DEBT_CEILING, DEFAULT_LIQUIDATION_RATIO, DEFAULT_CREDIT_MULTIPLIER);
entityRegistry.grantRole(entityRegistry.REGISTRAR_ROLE(), address(vaultFactory));
vm.stopBroadcast();
console.log("\n=== Vault System Finish Complete ===");
}
}

View File

@@ -0,0 +1,66 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console2} from "forge-std/Script.sol";
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
interface IGRUVaultIndexLegacy {
function allVaults(uint256 index) external view returns (address);
function vaults(address vault)
external
view
returns (
address entity,
address baseToken,
address depositToken,
address debtToken,
uint8 gruTier,
bytes32 ibanHash,
bytes32 policyProfileKey,
uint256 recordedAt,
bool active
);
}
/// @notice Import one legacy vault record into new GRUVaultIndex (use GRU_MIGRATE_INDEX).
contract ImportGruVaultRecord138 is Script {
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address oldIndex = vm.envAddress("OLD_GRU_VAULT_INDEX");
address newIndex = vm.envAddress("NEW_GRU_VAULT_INDEX");
bytes32 policyKey = vm.envBytes32("GRU_POLICY_PROFILE_KEY");
uint256 idx = vm.envUint("GRU_MIGRATE_INDEX");
IGRUVaultIndexLegacy legacy = IGRUVaultIndexLegacy(oldIndex);
GRUVaultIndex target = GRUVaultIndex(newIndex);
address vault;
try legacy.allVaults(idx) returns (address v) {
vault = v;
} catch {
revert("ImportGruVaultRecord138: index out of range");
}
(
address entity,
address baseToken,
address depositToken,
address debtToken,
uint8 gruTier,
bytes32 ibanHash,
bytes32 existingKey,
uint256 recordedAt,
bool active
) = legacy.vaults(vault);
require(active, "ImportGruVaultRecord138: inactive");
bytes32 key = existingKey == bytes32(0) ? policyKey : existingKey;
vm.startBroadcast(pk);
target.importVault(
vault, entity, baseToken, depositToken, debtToken, gruTier, ibanHash, key, recordedAt
);
vm.stopBroadcast();
console2.log("Imported", vault, "policy", vm.toString(key));
}
}

View File

@@ -0,0 +1,82 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console2} from "forge-std/Script.sol";
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
interface IGRUVaultIndexLegacy {
function allVaults(uint256 index) external view returns (address);
function vaults(address vault)
external
view
returns (
address entity,
address baseToken,
address depositToken,
address debtToken,
uint8 gruTier,
bytes32 ibanHash,
bytes32 policyProfileKey,
uint256 recordedAt,
bool active
);
}
/// @notice Deploy GRUVaultIndex v2 and migrate records from legacy index with policy profile backfill.
contract MigrateGRUVaultIndex138 is Script {
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address admin = vm.addr(pk);
address oldIndex = vm.envAddress("OLD_GRU_VAULT_INDEX");
address factory = vm.envAddress("VAULT_FACTORY_ADDRESS");
bytes32 policyKey = vm.envBytes32("GRU_POLICY_PROFILE_KEY");
vm.startBroadcast(pk);
GRUVaultIndex newIndex = new GRUVaultIndex(admin);
console2.log("New GRUVaultIndex:", address(newIndex));
IGRUVaultIndexLegacy legacy = IGRUVaultIndexLegacy(oldIndex);
uint256 imported;
for (uint256 i = 0; i < 32; i++) {
address vault;
try legacy.allVaults(i) returns (address v) {
vault = v;
} catch {
break;
}
if (vault == address(0)) break;
(
address entity,
address baseToken,
address depositToken,
address debtToken,
uint8 gruTier,
bytes32 ibanHash,
bytes32 existingKey,
uint256 recordedAt,
bool active
) = legacy.vaults(vault);
if (!active) continue;
bytes32 key = existingKey == bytes32(0) ? policyKey : existingKey;
newIndex.importVault(
vault, entity, baseToken, depositToken, debtToken, gruTier, ibanHash, key, recordedAt
);
imported++;
console2.log("Imported vault", vault);
}
newIndex.grantFactoryRole(factory);
VaultFactory(factory).setGruVaultIndex(address(newIndex));
vm.stopBroadcast();
console2.log("Migrated vault count:", imported);
console2.log("Update GRU_VAULT_INDEX to", address(newIndex));
}
}

View File

@@ -0,0 +1,44 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console2} from "forge-std/Script.sol";
import {RegulatedEntityRegistry} from "../../../contracts/vault/RegulatedEntityRegistry.sol";
import {GRUEntityIbanRegistry} from "../../../contracts/vault/GRUEntityIbanRegistry.sol";
/// @notice Register OMNL/DBIS entity + IBAN binding for GRU vault operations.
contract RegisterGRUEntityAndIban is Script {
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");
address entity = vm.envOr("GRU_OMNL_ENTITY_ADDRESS", vm.addr(pk));
address entityRegistryAddr = vm.envAddress("REGULATED_ENTITY_REGISTRY");
address ibanRegistryAddr = vm.envAddress("GRU_ENTITY_IBAN_REGISTRY");
bytes32 jurisdictionHash = vm.envOr("GRU_JURISDICTION_HASH", keccak256("OMNL"));
bytes32 ibanHash = vm.envBytes32("GRU_IBAN_HASH");
address directIban = vm.envOr("GRU_DIRECT_IBAN_ADDRESS", entity);
RegulatedEntityRegistry entityRegistry = RegulatedEntityRegistry(entityRegistryAddr);
GRUEntityIbanRegistry ibanRegistry = GRUEntityIbanRegistry(ibanRegistryAddr);
vm.startBroadcast(pk);
if (!entityRegistry.isEligible(entity)) {
address[] memory wallets = new address[](1);
wallets[0] = entity;
entityRegistry.registerEntity(entity, jurisdictionHash, wallets);
console2.log("Registered entity", entity);
} else {
console2.log("Entity already registered", entity);
}
(address existing,,, bool active) = ibanRegistry.getRecord(ibanHash);
if (!active) {
ibanRegistry.registerIban(ibanHash, entity, jurisdictionHash, directIban);
console2.log("Registered IBAN hash", vm.toString(ibanHash));
} else {
console2.log("IBAN already active for entity", existing);
}
vm.stopBroadcast();
}
}

View File

@@ -0,0 +1,44 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console2} from "forge-std/Script.sol";
import {Ledger} from "../../../contracts/vault/Ledger.sol";
/// @notice Register M1 c* tokens as ledger assets with default GRU vault risk parameters.
contract RegisterGruVaultLedgerAssets is Script {
uint256 constant DEFAULT_DEBT_CEILING = 1_000_000e18;
uint256 constant DEFAULT_LIQUIDATION_RATIO = 10_000;
uint256 constant DEFAULT_CREDIT_MULTIPLIER = 50_000;
function run() external {
address ledgerAddr = vm.envAddress("LEDGER_ADDRESS");
Ledger ledger = Ledger(ledgerAddr);
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
_registerIfSet(ledger, vm.envOr("CUSDC_ADDRESS_138", vm.envOr("COMPLIANT_USDC_ADDRESS", address(0))));
_registerIfSet(ledger, vm.envOr("CUSDT_ADDRESS_138", vm.envOr("COMPLIANT_USDT_ADDRESS", address(0))));
_registerIfSet(ledger, vm.envOr("cEURC_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("cEURT_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("cGBPC_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("cGBPT_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("cAUDC_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("cJPYC_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("cCHFC_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("cCADC_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("cXAUC_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("cXAUT_ADDRESS_138", address(0)));
_registerIfSet(ledger, vm.envOr("CUSDC_ADDRESS_651940", vm.envOr("AUSDC_ADDRESS_651940", address(0))));
_registerIfSet(ledger, vm.envOr("AUSDT_ADDRESS_651940", vm.envOr("CUSDT_ADDRESS_651940", address(0))));
_registerIfSet(ledger, vm.envOr("WALL_ADDRESS_651940", address(0)));
vm.stopBroadcast();
}
function _registerIfSet(Ledger ledger, address asset) internal {
if (asset == address(0)) return;
ledger.setRiskParameters(asset, DEFAULT_DEBT_CEILING, DEFAULT_LIQUIDATION_RATIO, DEFAULT_CREDIT_MULTIPLIER);
console2.log("Registered ledger asset", asset);
}
}

View File

@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console2} from "forge-std/Script.sol";
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
/// @notice Wire an existing VaultFactory to an existing GRUVaultIndex (post-deploy on any chain).
contract WireGRUVaultFactoryToIndex is Script {
function run() external {
address factoryAddr = vm.envAddress("VAULT_FACTORY_ADDRESS");
address indexAddr = vm.envAddress("GRU_VAULT_INDEX");
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
VaultFactory(factoryAddr).setGruVaultIndex(indexAddr);
GRUVaultIndex(indexAddr).grantFactoryRole(factoryAddr);
vm.stopBroadcast();
console2.log("Wired VaultFactory", factoryAddr);
console2.log("GRUVaultIndex", indexAddr);
}
}