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

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