- CCIP/trustless bridge contracts, GRU tokens, DEX/PMM tests, reserve vault. - Token-aggregation service routes, planner, chain config, relay env templates. - Config snapshots and multi-chain deployment markdown updates. - gitignore services/btc-intake/dist/ (tsc output); do not track dist. Run forge build && forge test before deploy (large solc graph). Made-with: Cursor
72 lines
2.5 KiB
Solidity
72 lines
2.5 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
|
|
import "../vendor/openzeppelin/UUPSUpgradeable.sol";
|
|
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
|
|
/**
|
|
* @title ConfigurationRegistry
|
|
* @notice Centralized configuration without hardcoding
|
|
* @dev Eliminates hardcoded addresses, enables runtime configuration
|
|
*/
|
|
contract ConfigurationRegistry is
|
|
Initializable,
|
|
AccessControlUpgradeable,
|
|
UUPSUpgradeable
|
|
{
|
|
bytes32 public constant CONFIG_ADMIN_ROLE = keccak256("CONFIG_ADMIN_ROLE");
|
|
bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");
|
|
|
|
mapping(address => mapping(bytes32 => bytes)) private configs;
|
|
mapping(address => bytes32[]) private configKeys;
|
|
|
|
event ConfigSet(address indexed contractAddr, bytes32 indexed key, bytes value);
|
|
event ConfigDeleted(address indexed contractAddr, bytes32 indexed key);
|
|
|
|
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
constructor() {
|
|
_disableInitializers();
|
|
}
|
|
|
|
function initialize(address admin) external initializer {
|
|
__AccessControl_init();
|
|
__UUPSUpgradeable_init();
|
|
|
|
_grantRole(DEFAULT_ADMIN_ROLE, admin);
|
|
_grantRole(CONFIG_ADMIN_ROLE, admin);
|
|
_grantRole(UPGRADER_ROLE, admin);
|
|
}
|
|
|
|
function _authorizeUpgrade(address newImplementation)
|
|
internal override onlyRole(UPGRADER_ROLE) {}
|
|
|
|
function set(address contractAddr, bytes32 key, bytes calldata value) external onlyRole(CONFIG_ADMIN_ROLE) {
|
|
require(contractAddr != address(0), "Zero address");
|
|
require(key != bytes32(0), "Zero key");
|
|
|
|
if (configs[contractAddr][key].length == 0) {
|
|
configKeys[contractAddr].push(key);
|
|
}
|
|
|
|
configs[contractAddr][key] = value;
|
|
emit ConfigSet(contractAddr, key, value);
|
|
}
|
|
|
|
function get(address contractAddr, bytes32 key) external view returns (bytes memory) {
|
|
return configs[contractAddr][key];
|
|
}
|
|
|
|
function getAddress(address contractAddr, bytes32 key) external view returns (address) {
|
|
bytes memory data = configs[contractAddr][key];
|
|
require(data.length == 32, "Invalid data");
|
|
return abi.decode(data, (address));
|
|
}
|
|
|
|
function getUint256(address contractAddr, bytes32 key) external view returns (uint256) {
|
|
bytes memory data = configs[contractAddr][key];
|
|
require(data.length == 32, "Invalid data");
|
|
return abi.decode(data, (uint256));
|
|
}
|
|
}
|