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>
132 lines
4.1 KiB
Solidity
132 lines
4.1 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
|
|
/**
|
|
* @title GRUVaultIndex
|
|
* @notice Canonical index of GRU vault instances across tiers, tokens, IBAN, and URA policy profiles.
|
|
* @dev Written by VaultFactory (FACTORY_ROLE) or registrar during vault creation.
|
|
*/
|
|
contract GRUVaultIndex is AccessControl {
|
|
bytes32 public constant FACTORY_ROLE = keccak256("FACTORY_ROLE");
|
|
bytes32 public constant REGISTRAR_ROLE = keccak256("REGISTRAR_ROLE");
|
|
|
|
/// @dev GRU monetary tier: 0=M00, 1=M0, 2=M1
|
|
struct VaultRecord {
|
|
address entity;
|
|
address baseToken;
|
|
address depositToken;
|
|
address debtToken;
|
|
uint8 gruTier;
|
|
bytes32 ibanHash;
|
|
bytes32 policyProfileKey;
|
|
uint256 recordedAt;
|
|
bool active;
|
|
}
|
|
|
|
mapping(address => VaultRecord) public vaults;
|
|
address[] public allVaults;
|
|
|
|
event VaultRecorded(
|
|
address indexed vault,
|
|
address indexed entity,
|
|
address baseToken,
|
|
address depositToken,
|
|
address debtToken,
|
|
uint8 gruTier,
|
|
bytes32 ibanHash,
|
|
bytes32 policyProfileKey
|
|
);
|
|
|
|
event PolicyProfileKeyPatched(address indexed vault, bytes32 policyProfileKey);
|
|
|
|
event VaultImported(
|
|
address indexed vault,
|
|
address indexed entity,
|
|
address baseToken,
|
|
bytes32 policyProfileKey
|
|
);
|
|
|
|
constructor(address admin) {
|
|
require(admin != address(0), "GRUVaultIndex: zero admin");
|
|
_grantRole(DEFAULT_ADMIN_ROLE, admin);
|
|
_grantRole(REGISTRAR_ROLE, admin);
|
|
}
|
|
|
|
function grantFactoryRole(address factory) external onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
require(factory != address(0), "GRUVaultIndex: zero factory");
|
|
_grantRole(FACTORY_ROLE, factory);
|
|
}
|
|
|
|
function recordVault(
|
|
address vault,
|
|
address entity,
|
|
address baseToken,
|
|
address depositToken,
|
|
address debtToken,
|
|
uint8 gruTier,
|
|
bytes32 ibanHash,
|
|
bytes32 policyProfileKey
|
|
) external onlyRole(FACTORY_ROLE) {
|
|
require(vault != address(0), "GRUVaultIndex: zero vault");
|
|
require(!vaults[vault].active, "GRUVaultIndex: exists");
|
|
|
|
vaults[vault] = VaultRecord({
|
|
entity: entity,
|
|
baseToken: baseToken,
|
|
depositToken: depositToken,
|
|
debtToken: debtToken,
|
|
gruTier: gruTier,
|
|
ibanHash: ibanHash,
|
|
policyProfileKey: policyProfileKey,
|
|
recordedAt: block.timestamp,
|
|
active: true
|
|
});
|
|
allVaults.push(vault);
|
|
|
|
emit VaultRecorded(vault, entity, baseToken, depositToken, debtToken, gruTier, ibanHash, policyProfileKey);
|
|
}
|
|
|
|
/// @notice Admin backfill when vaults were indexed before policy profile publish.
|
|
function patchPolicyProfileKey(address vault, bytes32 policyProfileKey)
|
|
external
|
|
onlyRole(DEFAULT_ADMIN_ROLE)
|
|
{
|
|
require(vaults[vault].active, "GRUVaultIndex: unknown");
|
|
vaults[vault].policyProfileKey = policyProfileKey;
|
|
emit PolicyProfileKeyPatched(vault, policyProfileKey);
|
|
}
|
|
|
|
/// @notice Registrar migration import (e.g. re-index with policy keys from a prior GRUVaultIndex).
|
|
function importVault(
|
|
address vault,
|
|
address entity,
|
|
address baseToken,
|
|
address depositToken,
|
|
address debtToken,
|
|
uint8 gruTier,
|
|
bytes32 ibanHash,
|
|
bytes32 policyProfileKey,
|
|
uint256 recordedAt
|
|
) external onlyRole(REGISTRAR_ROLE) {
|
|
require(vault != address(0), "GRUVaultIndex: zero vault");
|
|
require(!vaults[vault].active, "GRUVaultIndex: exists");
|
|
|
|
vaults[vault] = VaultRecord({
|
|
entity: entity,
|
|
baseToken: baseToken,
|
|
depositToken: depositToken,
|
|
debtToken: debtToken,
|
|
gruTier: gruTier,
|
|
ibanHash: ibanHash,
|
|
policyProfileKey: policyProfileKey,
|
|
recordedAt: recordedAt,
|
|
active: true
|
|
});
|
|
allVaults.push(vault);
|
|
|
|
emit VaultImported(vault, entity, baseToken, policyProfileKey);
|
|
}
|
|
}
|