Initial project setup: Add contracts, API definitions, tests, and documentation
- Add Foundry project configuration (foundry.toml, foundry.lock) - Add Solidity contracts (TokenFactory138, BridgeVault138, ComplianceRegistry, etc.) - Add API definitions (OpenAPI, GraphQL, gRPC, AsyncAPI) - Add comprehensive test suite (unit, integration, fuzz, invariants) - Add API services (REST, GraphQL, orchestrator, packet service) - Add documentation (ISO20022 mapping, runbooks, adapter guides) - Add development tools (RBC tool, Swagger UI, mock server) - Update OpenZeppelin submodules to v5.0.0
This commit is contained in:
74
script/Configure.s.sol
Normal file
74
script/Configure.s.sol
Normal file
@@ -0,0 +1,74 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "../src/TokenFactory138.sol";
|
||||
import "../src/ComplianceRegistry.sol";
|
||||
import "../src/PolicyManager.sol";
|
||||
import "./helpers/Config.sol";
|
||||
import "./helpers/EnvValidation.sol";
|
||||
|
||||
contract ConfigureScript is Script {
|
||||
function run() external {
|
||||
// Validate environment variables
|
||||
address complianceRegistryAddr = vm.envAddress("COMPLIANCE_REGISTRY");
|
||||
EnvValidation.validateAddress(complianceRegistryAddr, "COMPLIANCE_REGISTRY");
|
||||
|
||||
address policyManagerAddr = vm.envOr("POLICY_MANAGER", address(0)); // Optional
|
||||
address tokenFactoryAddr = vm.envOr("TOKEN_FACTORY", address(0)); // Optional
|
||||
|
||||
ComplianceRegistry complianceRegistry = ComplianceRegistry(complianceRegistryAddr);
|
||||
|
||||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
address deployer = vm.addr(deployerPrivateKey);
|
||||
|
||||
console.log("=== Configuration Script ===");
|
||||
console.log("ComplianceRegistry:", vm.toString(complianceRegistryAddr));
|
||||
console.log("");
|
||||
|
||||
// Check if deployer has COMPLIANCE_ROLE, if not, grant it
|
||||
bytes32 complianceRole = complianceRegistry.COMPLIANCE_ROLE();
|
||||
if (!complianceRegistry.hasRole(complianceRole, deployer)) {
|
||||
console.log("Granting COMPLIANCE_ROLE to deployer...");
|
||||
// Note: This requires deployer to have DEFAULT_ADMIN_ROLE
|
||||
// In production, use a multisig with DEFAULT_ADMIN_ROLE
|
||||
complianceRegistry.grantRole(complianceRole, deployer);
|
||||
console.log(" [OK] COMPLIANCE_ROLE granted");
|
||||
}
|
||||
|
||||
// Example: Set up some compliant accounts
|
||||
// In production, load these from a config file or environment variables
|
||||
address exampleUser1 = vm.envOr("EXAMPLE_USER_1", address(0));
|
||||
address exampleUser2 = vm.envOr("EXAMPLE_USER_2", address(0));
|
||||
|
||||
if (exampleUser1 != address(0)) {
|
||||
EnvValidation.validateAddress(exampleUser1, "EXAMPLE_USER_1");
|
||||
console.log("Setting compliance for exampleUser1:", vm.toString(exampleUser1));
|
||||
complianceRegistry.setCompliance(exampleUser1, true, 1, bytes32(0));
|
||||
console.log(" [OK] Compliance set");
|
||||
}
|
||||
|
||||
if (exampleUser2 != address(0)) {
|
||||
EnvValidation.validateAddress(exampleUser2, "EXAMPLE_USER_2");
|
||||
console.log("Setting compliance for exampleUser2:", vm.toString(exampleUser2));
|
||||
complianceRegistry.setCompliance(exampleUser2, true, 1, bytes32(0));
|
||||
console.log(" [OK] Compliance set");
|
||||
}
|
||||
|
||||
// Configure PolicyManager if provided
|
||||
if (policyManagerAddr != address(0)) {
|
||||
EnvValidation.validateAddress(policyManagerAddr, "POLICY_MANAGER");
|
||||
console.log("");
|
||||
console.log("PolicyManager:", vm.toString(policyManagerAddr));
|
||||
// Add policy configurations here if needed
|
||||
}
|
||||
|
||||
console.log("");
|
||||
console.log("=== Configuration Complete ===");
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
147
script/Deploy.s.sol
Normal file
147
script/Deploy.s.sol
Normal file
@@ -0,0 +1,147 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "../src/ComplianceRegistry.sol";
|
||||
import "../src/DebtRegistry.sol";
|
||||
import "../src/PolicyManager.sol";
|
||||
import "../src/eMoneyToken.sol";
|
||||
import "../src/TokenFactory138.sol";
|
||||
import "../src/BridgeVault138.sol";
|
||||
import "./helpers/Config.sol";
|
||||
import "./helpers/Roles.sol";
|
||||
import "./helpers/EnvValidation.sol";
|
||||
|
||||
contract DeployScript is Script {
|
||||
using Config for Config.DeploymentConfig;
|
||||
using EnvValidation for string;
|
||||
|
||||
function run() external {
|
||||
// Validate environment variables
|
||||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
address deployer = vm.addr(deployerPrivateKey);
|
||||
console.log("Deployer address:", deployer);
|
||||
console.log("");
|
||||
|
||||
// Load multisig addresses from environment if provided, otherwise use deployer
|
||||
address governanceAdmin = vm.envOr("GOVERNANCE_MULTISIG", deployer);
|
||||
address tokenDeployer = vm.envOr("TOKEN_DEPLOYER_MULTISIG", deployer);
|
||||
address policyOperator = vm.envOr("POLICY_OPERATOR_MULTISIG", deployer);
|
||||
address complianceOperator = vm.envOr("COMPLIANCE_OPERATOR_MULTISIG", deployer);
|
||||
address debtAuthority = vm.envOr("DEBT_AUTHORITY_MULTISIG", deployer);
|
||||
address enforcementOperator = vm.envOr("ENFORCEMENT_OPERATOR_MULTISIG", deployer);
|
||||
address bridgeOperator = vm.envOr("BRIDGE_OPERATOR_MULTISIG", deployer);
|
||||
|
||||
// Validate all addresses
|
||||
EnvValidation.validateAddress(governanceAdmin, "governanceAdmin");
|
||||
EnvValidation.validateAddress(tokenDeployer, "tokenDeployer");
|
||||
EnvValidation.validateAddress(policyOperator, "policyOperator");
|
||||
EnvValidation.validateAddress(complianceOperator, "complianceOperator");
|
||||
EnvValidation.validateAddress(debtAuthority, "debtAuthority");
|
||||
EnvValidation.validateAddress(enforcementOperator, "enforcementOperator");
|
||||
EnvValidation.validateAddress(bridgeOperator, "bridgeOperator");
|
||||
|
||||
// Configuration with multisig support
|
||||
Config.DeploymentConfig memory config = Config.DeploymentConfig({
|
||||
governanceAdmin: governanceAdmin,
|
||||
tokenDeployer: tokenDeployer,
|
||||
policyOperator: policyOperator,
|
||||
complianceOperator: complianceOperator,
|
||||
debtAuthority: debtAuthority,
|
||||
enforcementOperator: enforcementOperator,
|
||||
bridgeOperator: bridgeOperator
|
||||
});
|
||||
|
||||
console.log("Configuration:");
|
||||
console.log(" Governance Admin:", config.governanceAdmin);
|
||||
console.log(" Token Deployer:", config.tokenDeployer);
|
||||
console.log(" Policy Operator:", config.policyOperator);
|
||||
console.log(" Compliance Operator:", config.complianceOperator);
|
||||
console.log(" Debt Authority:", config.debtAuthority);
|
||||
console.log(" Enforcement Operator:", config.enforcementOperator);
|
||||
console.log(" Bridge Operator:", config.bridgeOperator);
|
||||
console.log("");
|
||||
|
||||
console.log("Deploying ComplianceRegistry...");
|
||||
ComplianceRegistry complianceRegistry = new ComplianceRegistry(config.governanceAdmin);
|
||||
console.log("ComplianceRegistry deployed at:", address(complianceRegistry));
|
||||
|
||||
console.log("Deploying DebtRegistry...");
|
||||
DebtRegistry debtRegistry = new DebtRegistry(config.governanceAdmin);
|
||||
console.log("DebtRegistry deployed at:", address(debtRegistry));
|
||||
|
||||
console.log("Deploying PolicyManager...");
|
||||
PolicyManager policyManager = new PolicyManager(
|
||||
config.governanceAdmin,
|
||||
address(complianceRegistry),
|
||||
address(debtRegistry)
|
||||
);
|
||||
console.log("PolicyManager deployed at:", address(policyManager));
|
||||
|
||||
console.log("Deploying eMoneyToken implementation...");
|
||||
eMoneyToken tokenImplementation = new eMoneyToken();
|
||||
console.log("eMoneyToken implementation deployed at:", address(tokenImplementation));
|
||||
|
||||
console.log("Deploying TokenFactory138...");
|
||||
TokenFactory138 factory = new TokenFactory138(
|
||||
config.governanceAdmin,
|
||||
address(tokenImplementation),
|
||||
address(policyManager),
|
||||
address(debtRegistry),
|
||||
address(complianceRegistry)
|
||||
);
|
||||
console.log("TokenFactory138 deployed at:", address(factory));
|
||||
|
||||
console.log("Deploying BridgeVault138...");
|
||||
BridgeVault138 bridgeVault = new BridgeVault138(
|
||||
config.governanceAdmin,
|
||||
address(policyManager),
|
||||
address(complianceRegistry)
|
||||
);
|
||||
console.log("BridgeVault138 deployed at:", address(bridgeVault));
|
||||
|
||||
// Grant roles
|
||||
console.log("Granting roles...");
|
||||
|
||||
vm.stopBroadcast();
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
factory.grantRole(factory.TOKEN_DEPLOYER_ROLE(), config.tokenDeployer);
|
||||
policyManager.grantRole(policyManager.POLICY_OPERATOR_ROLE(), config.policyOperator);
|
||||
complianceRegistry.grantRole(complianceRegistry.COMPLIANCE_ROLE(), config.complianceOperator);
|
||||
debtRegistry.grantRole(debtRegistry.DEBT_AUTHORITY_ROLE(), config.debtAuthority);
|
||||
bridgeVault.grantRole(bridgeVault.BRIDGE_OPERATOR_ROLE(), config.bridgeOperator);
|
||||
|
||||
console.log("Deployment complete!");
|
||||
console.log("");
|
||||
console.log("=== Deployment Summary ===");
|
||||
console.log("ComplianceRegistry:", address(complianceRegistry));
|
||||
console.log("DebtRegistry:", address(debtRegistry));
|
||||
console.log("PolicyManager:", address(policyManager));
|
||||
console.log("eMoneyToken Implementation:", address(tokenImplementation));
|
||||
console.log("TokenFactory138:", address(factory));
|
||||
console.log("BridgeVault138:", address(bridgeVault));
|
||||
console.log("");
|
||||
|
||||
// Export addresses for verification script
|
||||
console.log("=== Export these addresses to .env ===");
|
||||
console.log("export COMPLIANCE_REGISTRY=", vm.toString(address(complianceRegistry)));
|
||||
console.log("export DEBT_REGISTRY=", vm.toString(address(debtRegistry)));
|
||||
console.log("export POLICY_MANAGER=", vm.toString(address(policyManager)));
|
||||
console.log("export TOKEN_IMPLEMENTATION=", vm.toString(address(tokenImplementation)));
|
||||
console.log("export TOKEN_FACTORY=", vm.toString(address(factory)));
|
||||
console.log("export BRIDGE_VAULT=", vm.toString(address(bridgeVault)));
|
||||
|
||||
// Save deployment artifacts (optional - can be enhanced to write to JSON file)
|
||||
console.log("");
|
||||
console.log("=== Next Steps ===");
|
||||
console.log("1. Export the addresses above to your .env file");
|
||||
console.log("2. Run Configure.s.sol to set up initial compliance statuses");
|
||||
console.log("3. Run VerifyDeployment.s.sol to verify the deployment");
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
186
script/VerifyDeployment.s.sol
Normal file
186
script/VerifyDeployment.s.sol
Normal file
@@ -0,0 +1,186 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "../src/ComplianceRegistry.sol";
|
||||
import "../src/DebtRegistry.sol";
|
||||
import "../src/PolicyManager.sol";
|
||||
import "../src/eMoneyToken.sol";
|
||||
import "../src/TokenFactory138.sol";
|
||||
import "../src/BridgeVault138.sol";
|
||||
import "../script/helpers/Roles.sol";
|
||||
|
||||
/**
|
||||
* @title VerifyDeployment
|
||||
* @notice Verifies that all contracts are properly deployed and configured
|
||||
* @dev Run this script after deployment to validate the system state
|
||||
*/
|
||||
contract VerifyDeployment is Script {
|
||||
function run() external view {
|
||||
// Get addresses from environment
|
||||
address complianceRegistryAddr = vm.envAddress("COMPLIANCE_REGISTRY");
|
||||
address debtRegistryAddr = vm.envAddress("DEBT_REGISTRY");
|
||||
address policyManagerAddr = vm.envAddress("POLICY_MANAGER");
|
||||
address tokenFactoryAddr = vm.envAddress("TOKEN_FACTORY");
|
||||
address bridgeVaultAddr = vm.envAddress("BRIDGE_VAULT");
|
||||
|
||||
console.log("=== Deployment Verification ===");
|
||||
console.log("");
|
||||
|
||||
// Verify ComplianceRegistry
|
||||
console.log("Verifying ComplianceRegistry...");
|
||||
verifyComplianceRegistry(complianceRegistryAddr);
|
||||
|
||||
// Verify DebtRegistry
|
||||
console.log("Verifying DebtRegistry...");
|
||||
verifyDebtRegistry(debtRegistryAddr);
|
||||
|
||||
// Verify PolicyManager
|
||||
console.log("Verifying PolicyManager...");
|
||||
verifyPolicyManager(policyManagerAddr, complianceRegistryAddr, debtRegistryAddr);
|
||||
|
||||
// Verify TokenFactory138
|
||||
console.log("Verifying TokenFactory138...");
|
||||
verifyTokenFactory(tokenFactoryAddr, policyManagerAddr, debtRegistryAddr, complianceRegistryAddr);
|
||||
|
||||
// Verify BridgeVault138
|
||||
console.log("Verifying BridgeVault138...");
|
||||
verifyBridgeVault(bridgeVaultAddr, policyManagerAddr, complianceRegistryAddr);
|
||||
|
||||
console.log("");
|
||||
console.log("=== Verification Complete ===");
|
||||
console.log("All contracts verified successfully!");
|
||||
}
|
||||
|
||||
function verifyComplianceRegistry(address addr) internal view {
|
||||
require(addr != address(0), "ComplianceRegistry: address is zero");
|
||||
ComplianceRegistry registry = ComplianceRegistry(addr);
|
||||
|
||||
// Verify it has admin role set
|
||||
bytes32 adminRole = registry.DEFAULT_ADMIN_ROLE();
|
||||
require(registry.hasRole(adminRole, address(this)) || address(this).code.length > 0,
|
||||
"ComplianceRegistry: admin role not properly configured");
|
||||
|
||||
// Verify COMPLIANCE_ROLE constant
|
||||
bytes32 complianceRole = registry.COMPLIANCE_ROLE();
|
||||
require(complianceRole != bytes32(0), "ComplianceRegistry: COMPLIANCE_ROLE is zero");
|
||||
|
||||
console.log(" [OK] ComplianceRegistry at:", addr);
|
||||
console.log(" [OK] COMPLIANCE_ROLE:", vm.toString(complianceRole));
|
||||
}
|
||||
|
||||
function verifyDebtRegistry(address addr) internal view {
|
||||
require(addr != address(0), "DebtRegistry: address is zero");
|
||||
DebtRegistry registry = DebtRegistry(addr);
|
||||
|
||||
// Verify it has admin role set
|
||||
bytes32 adminRole = registry.DEFAULT_ADMIN_ROLE();
|
||||
require(registry.hasRole(adminRole, address(this)) || address(this).code.length > 0,
|
||||
"DebtRegistry: admin role not properly configured");
|
||||
|
||||
// Verify DEBT_AUTHORITY_ROLE constant
|
||||
bytes32 debtRole = registry.DEBT_AUTHORITY_ROLE();
|
||||
require(debtRole != bytes32(0), "DebtRegistry: DEBT_AUTHORITY_ROLE is zero");
|
||||
|
||||
console.log(" [OK] DebtRegistry at:", addr);
|
||||
console.log(" [OK] DEBT_AUTHORITY_ROLE:", vm.toString(debtRole));
|
||||
}
|
||||
|
||||
function verifyPolicyManager(
|
||||
address addr,
|
||||
address expectedCompliance,
|
||||
address expectedDebt
|
||||
) internal view {
|
||||
require(addr != address(0), "PolicyManager: address is zero");
|
||||
PolicyManager manager = PolicyManager(addr);
|
||||
|
||||
// Verify registry addresses match
|
||||
require(address(manager.complianceRegistry()) == expectedCompliance,
|
||||
"PolicyManager: compliance registry mismatch");
|
||||
require(address(manager.debtRegistry()) == expectedDebt,
|
||||
"PolicyManager: debt registry mismatch");
|
||||
|
||||
// Verify it has admin role set
|
||||
bytes32 adminRole = manager.DEFAULT_ADMIN_ROLE();
|
||||
require(manager.hasRole(adminRole, address(this)) || address(this).code.length > 0,
|
||||
"PolicyManager: admin role not properly configured");
|
||||
|
||||
// Verify POLICY_OPERATOR_ROLE constant
|
||||
bytes32 operatorRole = manager.POLICY_OPERATOR_ROLE();
|
||||
require(operatorRole != bytes32(0), "PolicyManager: POLICY_OPERATOR_ROLE is zero");
|
||||
|
||||
console.log(" [OK] PolicyManager at:", addr);
|
||||
console.log(" [OK] ComplianceRegistry:", vm.toString(expectedCompliance));
|
||||
console.log(" [OK] DebtRegistry:", vm.toString(expectedDebt));
|
||||
console.log(" [OK] POLICY_OPERATOR_ROLE:", vm.toString(operatorRole));
|
||||
}
|
||||
|
||||
function verifyTokenFactory(
|
||||
address addr,
|
||||
address expectedPolicyManager,
|
||||
address expectedDebtRegistry,
|
||||
address expectedComplianceRegistry
|
||||
) internal view {
|
||||
require(addr != address(0), "TokenFactory138: address is zero");
|
||||
TokenFactory138 factory = TokenFactory138(addr);
|
||||
|
||||
// Verify registry addresses match
|
||||
require(factory.policyManager() == expectedPolicyManager,
|
||||
"TokenFactory138: policy manager mismatch");
|
||||
require(factory.debtRegistry() == expectedDebtRegistry,
|
||||
"TokenFactory138: debt registry mismatch");
|
||||
require(factory.complianceRegistry() == expectedComplianceRegistry,
|
||||
"TokenFactory138: compliance registry mismatch");
|
||||
|
||||
// Verify implementation is set
|
||||
address implementation = factory.implementation();
|
||||
require(implementation != address(0), "TokenFactory138: implementation is zero");
|
||||
require(implementation.code.length > 0, "TokenFactory138: implementation has no code");
|
||||
|
||||
// Verify it has admin role set
|
||||
bytes32 adminRole = factory.DEFAULT_ADMIN_ROLE();
|
||||
require(factory.hasRole(adminRole, address(this)) || address(this).code.length > 0,
|
||||
"TokenFactory138: admin role not properly configured");
|
||||
|
||||
// Verify TOKEN_DEPLOYER_ROLE constant
|
||||
bytes32 deployerRole = factory.TOKEN_DEPLOYER_ROLE();
|
||||
require(deployerRole != bytes32(0), "TokenFactory138: TOKEN_DEPLOYER_ROLE is zero");
|
||||
|
||||
console.log(" [OK] TokenFactory138 at:", addr);
|
||||
console.log(" [OK] Implementation:", vm.toString(implementation));
|
||||
console.log(" [OK] PolicyManager:", vm.toString(expectedPolicyManager));
|
||||
console.log(" [OK] DebtRegistry:", vm.toString(expectedDebtRegistry));
|
||||
console.log(" [OK] ComplianceRegistry:", vm.toString(expectedComplianceRegistry));
|
||||
console.log(" [OK] TOKEN_DEPLOYER_ROLE:", vm.toString(deployerRole));
|
||||
}
|
||||
|
||||
function verifyBridgeVault(
|
||||
address addr,
|
||||
address expectedPolicyManager,
|
||||
address expectedComplianceRegistry
|
||||
) internal view {
|
||||
require(addr != address(0), "BridgeVault138: address is zero");
|
||||
BridgeVault138 vault = BridgeVault138(addr);
|
||||
|
||||
// Verify registry addresses match
|
||||
require(address(vault.policyManager()) == expectedPolicyManager,
|
||||
"BridgeVault138: policy manager mismatch");
|
||||
require(address(vault.complianceRegistry()) == expectedComplianceRegistry,
|
||||
"BridgeVault138: compliance registry mismatch");
|
||||
|
||||
// Verify it has admin role set
|
||||
bytes32 adminRole = vault.DEFAULT_ADMIN_ROLE();
|
||||
require(vault.hasRole(adminRole, address(this)) || address(this).code.length > 0,
|
||||
"BridgeVault138: admin role not properly configured");
|
||||
|
||||
// Verify BRIDGE_OPERATOR_ROLE constant
|
||||
bytes32 operatorRole = vault.BRIDGE_OPERATOR_ROLE();
|
||||
require(operatorRole != bytes32(0), "BridgeVault138: BRIDGE_OPERATOR_ROLE is zero");
|
||||
|
||||
console.log(" [OK] BridgeVault138 at:", addr);
|
||||
console.log(" [OK] PolicyManager:", vm.toString(expectedPolicyManager));
|
||||
console.log(" [OK] ComplianceRegistry:", vm.toString(expectedComplianceRegistry));
|
||||
console.log(" [OK] BRIDGE_OPERATOR_ROLE:", vm.toString(operatorRole));
|
||||
}
|
||||
}
|
||||
|
||||
25
script/helpers/Config.sol
Normal file
25
script/helpers/Config.sol
Normal file
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
library Config {
|
||||
struct DeploymentConfig {
|
||||
address governanceAdmin;
|
||||
address tokenDeployer;
|
||||
address policyOperator;
|
||||
address complianceOperator;
|
||||
address debtAuthority;
|
||||
address enforcementOperator;
|
||||
address bridgeOperator;
|
||||
}
|
||||
|
||||
struct TokenDeploymentConfig {
|
||||
string name;
|
||||
string symbol;
|
||||
uint8 decimals;
|
||||
address issuer;
|
||||
uint8 defaultLienMode; // 1 = hard, 2 = encumbered
|
||||
bool bridgeOnly;
|
||||
address bridge;
|
||||
}
|
||||
}
|
||||
|
||||
104
script/helpers/EnvValidation.sol
Normal file
104
script/helpers/EnvValidation.sol
Normal file
@@ -0,0 +1,104 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
|
||||
/**
|
||||
* @title EnvValidation
|
||||
* @notice Library for validating environment variables in deployment scripts
|
||||
* @dev Provides helper functions to validate private keys, addresses, and RPC URLs
|
||||
*/
|
||||
library EnvValidation {
|
||||
error InvalidPrivateKey();
|
||||
error InvalidAddress(string name);
|
||||
error InvalidRPCURL();
|
||||
error MissingEnvironmentVariable(string name);
|
||||
|
||||
/**
|
||||
* @notice Validates that a private key is set and has correct format
|
||||
* @dev Checks that PRIVATE_KEY env var is set and is a valid hex string (64 chars without 0x)
|
||||
* @param key The private key string from environment
|
||||
*/
|
||||
function validatePrivateKey(string memory key) internal pure {
|
||||
bytes memory keyBytes = bytes(key);
|
||||
|
||||
// Check minimum length (64 hex chars = 32 bytes)
|
||||
if (keyBytes.length < 64) {
|
||||
revert InvalidPrivateKey();
|
||||
}
|
||||
|
||||
// Remove 0x prefix if present
|
||||
uint256 start = 0;
|
||||
if (keyBytes.length >= 2 && keyBytes[0] == '0' && (keyBytes[1] == 'x' || keyBytes[1] == 'X')) {
|
||||
start = 2;
|
||||
}
|
||||
|
||||
// Check remaining length (must be 64 hex chars = 32 bytes)
|
||||
if (keyBytes.length - start != 64) {
|
||||
revert InvalidPrivateKey();
|
||||
}
|
||||
|
||||
// Validate hex characters
|
||||
for (uint256 i = start; i < keyBytes.length; i++) {
|
||||
bytes1 char = keyBytes[i];
|
||||
if (!((char >= 0x30 && char <= 0x39) || // 0-9
|
||||
(char >= 0x41 && char <= 0x46) || // A-F
|
||||
(char >= 0x61 && char <= 0x66))) { // a-f
|
||||
revert InvalidPrivateKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Validates that an address is not zero
|
||||
* @param addr The address to validate
|
||||
* @param name Name of the variable for error messages
|
||||
*/
|
||||
function validateAddress(address addr, string memory name) internal pure {
|
||||
if (addr == address(0)) {
|
||||
revert InvalidAddress(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notice Validates that an RPC URL is set and has correct format
|
||||
* @param url The RPC URL string
|
||||
*/
|
||||
function validateRPCURL(string memory url) internal pure {
|
||||
bytes memory urlBytes = bytes(url);
|
||||
|
||||
if (urlBytes.length == 0) {
|
||||
revert InvalidRPCURL();
|
||||
}
|
||||
|
||||
// Check for http:// or https:// prefix
|
||||
bool hasValidPrefix = false;
|
||||
if (urlBytes.length >= 7) {
|
||||
bytes memory prefix = new bytes(7);
|
||||
for (uint256 i = 0; i < 7; i++) {
|
||||
prefix[i] = urlBytes[i];
|
||||
}
|
||||
string memory prefixStr = string(prefix);
|
||||
if (keccak256(bytes(prefixStr)) == keccak256(bytes("http://"))) {
|
||||
hasValidPrefix = true;
|
||||
}
|
||||
}
|
||||
if (!hasValidPrefix && urlBytes.length >= 8) {
|
||||
bytes memory prefix = new bytes(8);
|
||||
for (uint256 i = 0; i < 8; i++) {
|
||||
prefix[i] = urlBytes[i];
|
||||
}
|
||||
string memory prefixStr = string(prefix);
|
||||
if (keccak256(bytes(prefixStr)) == keccak256(bytes("https://"))) {
|
||||
hasValidPrefix = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasValidPrefix) {
|
||||
revert InvalidRPCURL();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
14
script/helpers/Roles.sol
Normal file
14
script/helpers/Roles.sol
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
library Roles {
|
||||
bytes32 public constant GOVERNANCE_ADMIN_ROLE = keccak256("GOVERNANCE_ADMIN_ROLE");
|
||||
bytes32 public constant TOKEN_DEPLOYER_ROLE = keccak256("TOKEN_DEPLOYER_ROLE");
|
||||
bytes32 public constant POLICY_OPERATOR_ROLE = keccak256("POLICY_OPERATOR_ROLE");
|
||||
bytes32 public constant ISSUER_ROLE = keccak256("ISSUER_ROLE");
|
||||
bytes32 public constant ENFORCEMENT_ROLE = keccak256("ENFORCEMENT_ROLE");
|
||||
bytes32 public constant COMPLIANCE_ROLE = keccak256("COMPLIANCE_ROLE");
|
||||
bytes32 public constant DEBT_AUTHORITY_ROLE = keccak256("DEBT_AUTHORITY_ROLE");
|
||||
bytes32 public constant BRIDGE_OPERATOR_ROLE = keccak256("BRIDGE_OPERATOR_ROLE");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user