- Integrated Zod validation schemas across various API routes to ensure input integrity and improve error handling. - Updated `mapping-service`, `orchestrator`, `packet-service`, and `webhook-service` to utilize validation middleware for request parameters and bodies. - Improved error handling in webhook management, packet generation, and compliance routes to provide clearer feedback on request failures. - Added new validation schemas for various endpoints, enhancing overall API robustness and maintainability. - Updated dependencies in `package.json` to include the new validation library.
120 lines
4.5 KiB
Solidity
120 lines
4.5 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
|
import "./interfaces/ITokenFactory138.sol";
|
|
import "./interfaces/IeMoneyToken.sol";
|
|
import "./interfaces/IPolicyManager.sol";
|
|
import "./eMoneyToken.sol";
|
|
import "./errors/FactoryErrors.sol";
|
|
import "./errors/RegistryErrors.sol";
|
|
|
|
/**
|
|
* @title TokenFactory138
|
|
* @notice Factory for deploying new eMoneyToken instances as UUPS upgradeable proxies
|
|
* @dev Deploys ERC1967Proxy instances pointing to a shared implementation contract.
|
|
* Each token is configured with its issuer, lien mode, bridge settings, and registered by code hash.
|
|
*/
|
|
contract TokenFactory138 is ITokenFactory138, AccessControl {
|
|
bytes32 public constant TOKEN_DEPLOYER_ROLE = keccak256("TOKEN_DEPLOYER_ROLE");
|
|
|
|
address public immutable implementation;
|
|
address public immutable policyManager;
|
|
address public immutable debtRegistry;
|
|
address public immutable complianceRegistry;
|
|
|
|
mapping(bytes32 => address) private _tokensByCodeHash;
|
|
|
|
/**
|
|
* @notice Initializes the factory with registry and implementation addresses
|
|
* @param admin Address that will receive DEFAULT_ADMIN_ROLE
|
|
* @param implementation_ Address of the eMoneyToken implementation contract (used for all proxies)
|
|
* @param policyManager_ Address of PolicyManager contract
|
|
* @param debtRegistry_ Address of DebtRegistry contract
|
|
* @param complianceRegistry_ Address of ComplianceRegistry contract
|
|
*/
|
|
constructor(
|
|
address admin,
|
|
address implementation_,
|
|
address policyManager_,
|
|
address debtRegistry_,
|
|
address complianceRegistry_
|
|
) {
|
|
_grantRole(DEFAULT_ADMIN_ROLE, admin);
|
|
implementation = implementation_;
|
|
policyManager = policyManager_;
|
|
debtRegistry = debtRegistry_;
|
|
complianceRegistry = complianceRegistry_;
|
|
}
|
|
|
|
/**
|
|
* @notice Deploys a new eMoneyToken instance as a UUPS proxy
|
|
* @dev Requires TOKEN_DEPLOYER_ROLE. Creates ERC1967Proxy, initializes token, and configures PolicyManager.
|
|
* @param name Token name (e.g., "USD eMoney")
|
|
* @param symbol Token symbol (e.g., "USDe")
|
|
* @param config Token configuration (decimals, issuer, lien mode, bridge settings)
|
|
* @return token Address of the deployed proxy token contract
|
|
*/
|
|
function deployToken(
|
|
string calldata name,
|
|
string calldata symbol,
|
|
TokenConfig calldata config
|
|
) external override onlyRole(TOKEN_DEPLOYER_ROLE) returns (address token) {
|
|
if (config.issuer == address(0)) revert ZeroIssuer();
|
|
if (config.defaultLienMode != 1 && config.defaultLienMode != 2) {
|
|
revert PolicyInvalidLienMode(config.defaultLienMode);
|
|
}
|
|
|
|
// Deploy UUPS proxy
|
|
bytes memory initData = abi.encodeWithSelector(
|
|
IeMoneyToken.initialize.selector,
|
|
name,
|
|
symbol,
|
|
config.decimals,
|
|
config.issuer,
|
|
policyManager,
|
|
debtRegistry,
|
|
complianceRegistry
|
|
);
|
|
|
|
ERC1967Proxy proxy = new ERC1967Proxy(implementation, initData);
|
|
token = address(proxy);
|
|
|
|
// Configure token in PolicyManager
|
|
IPolicyManager(policyManager).setLienMode(token, config.defaultLienMode);
|
|
IPolicyManager(policyManager).setBridgeOnly(token, config.bridgeOnly);
|
|
if (config.bridge != address(0)) {
|
|
IPolicyManager(policyManager).setBridge(token, config.bridge);
|
|
}
|
|
|
|
// Register token by code hash (deterministic based on deployment params)
|
|
// Include token address, timestamp, and block number to prevent collisions
|
|
bytes32 codeHash = keccak256(abi.encodePacked(name, symbol, config.issuer, token, block.timestamp, block.number));
|
|
_tokensByCodeHash[codeHash] = token;
|
|
|
|
emit TokenDeployed(
|
|
token,
|
|
codeHash,
|
|
name,
|
|
symbol,
|
|
config.decimals,
|
|
config.issuer,
|
|
config.defaultLienMode,
|
|
config.bridgeOnly,
|
|
config.bridge
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @notice Returns the token address for a given code hash
|
|
* @dev Code hash is generated deterministically during token deployment
|
|
* @param codeHash The code hash to lookup
|
|
* @return Token address (zero address if not found)
|
|
*/
|
|
function tokenByCodeHash(bytes32 codeHash) external view override returns (address) {
|
|
return _tokensByCodeHash[codeHash];
|
|
}
|
|
}
|
|
|