Skip to content

Instantly share code, notes, and snippets.

@0xSachinK
Last active February 19, 2026 08:59
Show Gist options
  • Select an option

  • Save 0xSachinK/dc24a4f1d23d0527c546639188800f8f to your computer and use it in GitHub Desktop.

Select an option

Save 0xSachinK/dc24a4f1d23d0527c546639188800f8f to your computer and use it in GitHub Desktop.
ZKP2P V1 vs V2: Escrow & Orchestrator contract diffs
--- contracts/Escrow.sol 2026-02-19 13:55:27
+++ contracts/EscrowV2.sol 2026-02-19 15:51:47
@@ -1,5 +1,7 @@
//SPDX-License-Identifier: MIT
+pragma solidity ^0.8.18;
+
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
@@ -7,6 +9,7 @@
import { Pausable } from "@openzeppelin/contracts/security/Pausable.sol";
import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
+import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { AddressArrayUtils } from "./external/AddressArrayUtils.sol";
import { Bytes32ArrayUtils } from "./external/Bytes32ArrayUtils.sol";
@@ -14,16 +17,19 @@
import { Uint256ArrayUtils } from "./external/Uint256ArrayUtils.sol";
import { IEscrow } from "./interfaces/IEscrow.sol";
+import { IEscrowV2 } from "./interfaces/IEscrowV2.sol";
+import { IRateManager } from "./interfaces/IRateManager.sol";
import { IOrchestrator } from "./interfaces/IOrchestrator.sol";
+import { IOrchestratorRegistry } from "./interfaces/IOrchestratorRegistry.sol";
+import { IOracleAdapter } from "./interfaces/IOracleAdapter.sol";
import { IPaymentVerifier } from "./interfaces/IPaymentVerifier.sol";
import { IPaymentVerifierRegistry } from "./interfaces/IPaymentVerifierRegistry.sol";
-pragma solidity ^0.8.18;
/**
- * @title Escrow
+ * @title EscrowV2
* @notice Escrows deposits and manages deposit lifecycle.
*/
-contract Escrow is Ownable, Pausable, ReentrancyGuard, IEscrow {
+contract EscrowV2 is Ownable, Pausable, ReentrancyGuard, IEscrowV2 {
using AddressArrayUtils for address[];
using Bytes32ArrayUtils for bytes32[];
@@ -35,13 +41,14 @@
/* ============ Constants ============ */
uint256 internal constant PRECISE_UNIT = 1e18;
+ uint256 internal constant BPS = 10_000;
uint256 internal constant MAX_DUST_THRESHOLD = 1e6; // 1 USDC
uint256 internal constant MAX_TOTAL_INTENT_EXPIRATION_PERIOD = 86400 * 5; // 5 days
uint256 internal constant PRUNE_ALL_EXPIRED_INTENTS = type(uint256).max;
/* ============ State Variables ============ */
- IOrchestrator public orchestrator; // Address of the orchestrator contract
+ IOrchestratorRegistry public orchestratorRegistry; // Registry of authorized orchestrator contracts
IPaymentVerifierRegistry public paymentVerifierRegistry; // Address of the payment verifier registry contract
uint256 immutable public chainId; // chainId of the chain the escrow is deployed on
@@ -63,6 +70,7 @@
// Example: Deposit 1 => Venmo => USD: 1e18
// => Revolut => USD: 1e18, EUR: 1.2e18, SGD: 1.5e18
mapping(uint256 => mapping(bytes32 => mapping(bytes32 => uint256))) internal depositCurrencyMinRate;
+ mapping(uint256 => mapping(bytes32 => mapping(bytes32 => OracleRateConfig))) internal depositOracleRateConfig;
mapping(uint256 => mapping(bytes32 => bytes32[])) internal depositCurrencies; // Handy mapping to get all currencies for a deposit and verifier
// Do not need to track if a currency is active; if it's min rate is 0 then it's not active
// Track if a currency code has ever been listed for this deposit+paymentMethod (avoid contains scans and duplicates in depositCurrencies)
@@ -71,6 +79,8 @@
mapping(uint256 => Deposit) internal deposits; // Mapping of depositIds to deposit structs
mapping(uint256 => bytes32[]) internal depositIntentHashes; // Mapping of depositId to array of intentHashes
mapping(uint256 => mapping(bytes32 => Intent)) internal depositIntents; // Mapping of depositId to intentHash to intent
+ mapping(bytes32 => address) internal intentOrchestrator; // Intent hash to owning orchestrator
+ mapping(uint256 => RateManagerConfig) internal depositRateManagerConfig; // Per-deposit delegated rate manager config
uint256 public depositCounter; // Counter for depositIds
@@ -98,7 +108,9 @@
* @notice Modifier to restrict access to orchestrator-only functions
*/
modifier onlyOrchestrator() {
- if (msg.sender != address(orchestrator)) revert UnauthorizedCaller(msg.sender, address(orchestrator));
+ if (!orchestratorRegistry.isOrchestrator(msg.sender)) {
+ revert UnauthorizedCaller(msg.sender, address(orchestratorRegistry));
+ }
_;
}
@@ -106,6 +118,7 @@
constructor(
address _owner,
uint256 _chainId,
+ address _orchestratorRegistry,
address _paymentVerifierRegistry,
address _dustRecipient,
uint256 _dustThreshold,
@@ -115,6 +128,7 @@
Ownable()
{
chainId = _chainId;
+ orchestratorRegistry = IOrchestratorRegistry(_orchestratorRegistry);
paymentVerifierRegistry = IPaymentVerifierRegistry(_paymentVerifierRegistry);
dustRecipient = _dustRecipient;
dustThreshold = _dustThreshold;
@@ -308,15 +322,12 @@
/* ============ Deposit Owner OR Delegate Only (External Functions) ============ */
/**
- * @notice Only callable by the depositor/delegate for a deposit. Allows depositor/delegate to update the min conversion rate for a
- * currency for a payment verifier provided the currency was previously listed (otherwise use addCurrenciesToDepositPaymentMethod).
- * Since intent's store the conversion rate at the time of intent, changing the min conversion rate will not affect any intents that
- * have already been signaled.
- *
- * @param _depositId The deposit ID
- * @param _paymentMethod The payment method to update the min conversion rate for
- * @param _fiatCurrency The fiat currency code to update the min conversion rate for
- * @param _newMinConversionRate The new min conversion rate. Must be greater than 0.
+ * @notice Sets the fixed floor for a listed (paymentMethod, currency) tuple.
+ * @dev `_newMinConversionRate` may be zero to disable fixed-rate floor while keeping oracle floor active.
+ * @param _depositId The deposit ID.
+ * @param _paymentMethod The payment method key.
+ * @param _fiatCurrency The fiat currency key.
+ * @param _newMinConversionRate New fixed floor in precise units (0 allowed).
*/
function setCurrencyMinRate(
uint256 _depositId,
@@ -332,14 +343,148 @@
if (!depositCurrencyListed[_depositId][_paymentMethod][_fiatCurrency]) {
revert CurrencyNotSupported(_paymentMethod, _fiatCurrency);
}
- if (_newMinConversionRate == 0) revert ZeroConversionRate();
depositCurrencyMinRate[_depositId][_paymentMethod][_fiatCurrency] = _newMinConversionRate;
emit DepositMinConversionRateUpdated(_depositId, _paymentMethod, _fiatCurrency, _newMinConversionRate);
+ }
+
+ /**
+ * @notice Sets oracle spread configuration for a listed (paymentMethod, currency) tuple.
+ * @dev Caller must be the deposit depositor or delegate.
+ * @param _depositId The deposit ID.
+ * @param _paymentMethod The payment method key.
+ * @param _currencyCode The fiat currency key.
+ * @param _config Oracle spread configuration.
+ */
+ function setOracleRateConfig(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode,
+ OracleRateConfig calldata _config
+ )
+ external
+ whenNotPaused
+ onlyDepositorOrDelegate(_depositId)
+ {
+ _setOracleRateConfig(_depositId, _paymentMethod, _currencyCode, _config);
+ }
+
+ /**
+ * @notice Batch sets oracle spread configuration for multiple tuples on one deposit.
+ * @dev For each payment-method index, `_currencyCodes[i].length` must match `_configs[i].length`.
+ * @param _depositId Deposit ID.
+ * @param _paymentMethods Payment method keys.
+ * @param _currencyCodes Currency keys grouped by payment method index.
+ * @param _configs Oracle configs grouped by payment method index.
+ */
+ function setOracleRateConfigBatch(
+ uint256 _depositId,
+ bytes32[] calldata _paymentMethods,
+ bytes32[][] calldata _currencyCodes,
+ OracleRateConfig[][] calldata _configs
+ )
+ external
+ whenNotPaused
+ onlyDepositorOrDelegate(_depositId)
+ {
+ if (_paymentMethods.length != _currencyCodes.length) {
+ revert ArrayLengthMismatch(_paymentMethods.length, _currencyCodes.length);
+ }
+ if (_paymentMethods.length != _configs.length) {
+ revert ArrayLengthMismatch(_paymentMethods.length, _configs.length);
+ }
+
+ for (uint256 i = 0; i < _paymentMethods.length; i++) {
+ if (_currencyCodes[i].length != _configs[i].length) {
+ revert ArrayLengthMismatch(_currencyCodes[i].length, _configs[i].length);
+ }
+ for (uint256 j = 0; j < _currencyCodes[i].length; j++) {
+ _setOracleRateConfig(_depositId, _paymentMethods[i], _currencyCodes[i][j], _configs[i][j]);
+ }
+ }
+ }
+
+ /**
+ * @notice Removes oracle spread configuration for a listed tuple.
+ * @dev Caller must be depositor or delegate.
+ * @param _depositId Deposit ID.
+ * @param _paymentMethod Payment method key.
+ * @param _currencyCode Currency key.
+ */
+ function removeOracleRateConfig(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode
+ )
+ external
+ whenNotPaused
+ onlyDepositorOrDelegate(_depositId)
+ {
+ if (!depositCurrencyListed[_depositId][_paymentMethod][_currencyCode]) {
+ revert CurrencyNotSupported(_paymentMethod, _currencyCode);
+ }
+
+ delete depositOracleRateConfig[_depositId][_paymentMethod][_currencyCode];
+ emit DepositOracleRateConfigRemoved(_depositId, _paymentMethod, _currencyCode);
+ }
+
+ /**
+ * @notice Delegates rate management for a deposit to an external `IRateManager`.
+ * @dev Only the depositor (not delegate) can call this function.
+ * @param _depositId Deposit ID.
+ * @param _rateManager External rate manager contract address.
+ * @param _rateManagerId Manager ID within the external contract.
+ */
+ function setRateManager(
+ uint256 _depositId,
+ address _rateManager,
+ bytes32 _rateManagerId
+ )
+ external
+ whenNotPaused
+ {
+ Deposit storage deposit = deposits[_depositId];
+ if (deposit.depositor == address(0)) revert DepositNotFound(_depositId);
+ if (deposit.depositor != msg.sender) revert UnauthorizedCaller(msg.sender, deposit.depositor);
+ if (_rateManager == address(0)) revert ZeroAddress();
+ if (_rateManager.code.length == 0) revert InvalidRateManager(_rateManager);
+ if (_rateManagerId == bytes32(0)) revert ZeroValue();
+
+ RateManagerConfig memory existing = depositRateManagerConfig[_depositId];
+ if (existing.rateManager != address(0)) revert RateManagerAlreadySet(existing.rateManagerId);
+
+ IRateManager rateManager = IRateManager(_rateManager);
+ if (!rateManager.isRateManager(_rateManagerId)) revert RateManagerNotFound(_rateManagerId);
+
+ rateManager.onDepositOptIn(msg.sender, address(this), _depositId, _rateManagerId);
+
+ depositRateManagerConfig[_depositId] = RateManagerConfig({
+ rateManager: _rateManager,
+ rateManagerId: _rateManagerId
+ });
+
+ emit DepositRateManagerSet(_depositId, _rateManager, _rateManagerId);
}
/**
+ * @notice Clears delegated rate manager config for a deposit.
+ * @dev Only the depositor (not delegate) can call this function.
+ * @param _depositId Deposit ID.
+ */
+ function clearRateManager(uint256 _depositId) external whenNotPaused {
+ Deposit storage deposit = deposits[_depositId];
+ if (deposit.depositor == address(0)) revert DepositNotFound(_depositId);
+ if (deposit.depositor != msg.sender) revert UnauthorizedCaller(msg.sender, deposit.depositor);
+
+ RateManagerConfig memory existing = depositRateManagerConfig[_depositId];
+ if (existing.rateManager == address(0)) revert RateManagerNotSet(_depositId);
+
+ delete depositRateManagerConfig[_depositId];
+ emit DepositRateManagerCleared(_depositId, existing.rateManager, existing.rateManagerId);
+ }
+
+ /**
* @notice Allows depositor to update the intent amount range for a deposit. Since intent's are already created within the
* previous intent amount range, changing the intent amount range will not affect any intents that have already been signaled.
*
@@ -463,9 +608,14 @@
{
if (!depositPaymentMethodActive[_depositId][_paymentMethod]) revert PaymentMethodNotActive(_depositId, _paymentMethod);
if (!depositCurrencyListed[_depositId][_paymentMethod][_currencyCode]) revert CurrencyNotFound(_paymentMethod, _currencyCode);
-
- depositCurrencyMinRate[_depositId][_paymentMethod][_currencyCode] = 0;
+ delete depositCurrencyMinRate[_depositId][_paymentMethod][_currencyCode];
+ bool hadOracleConfig = depositOracleRateConfig[_depositId][_paymentMethod][_currencyCode].adapter != address(0);
+ if (hadOracleConfig) {
+ delete depositOracleRateConfig[_depositId][_paymentMethod][_currencyCode];
+ emit DepositOracleRateConfigRemoved(_depositId, _paymentMethod, _currencyCode);
+ }
+
emit DepositMinConversionRateUpdated(_depositId, _paymentMethod, _currencyCode, 0);
}
@@ -598,6 +748,7 @@
timestamp: block.timestamp,
expiryTime: expiryTime
});
+ intentOrchestrator[_intentHash] = msg.sender;
emit FundsLocked(_depositId, _intentHash, _amount, expiryTime);
@@ -608,9 +759,10 @@
}
/**
- * @notice ORCHESTRATOR ONLY: Unlocks funds from a cancelled intent by removing the specific intent.
+ * @notice ORCHESTRATOR ONLY: Unlocks funds from a cancelled intent by removing the specific intent.
+ * @dev Caller must be the same orchestrator that originally locked the intent.
* Releases the lock on deposit liquidity and adds it back to the deposit.
- *
+ *
* @param _depositId The deposit ID to unlock funds from
* @param _intentHash The intent hash to find and remove the intent for
*/
@@ -625,21 +777,23 @@
if (deposit.depositor == address(0)) revert DepositNotFound(_depositId);
if (intent.intentHash == bytes32(0)) revert IntentNotFound(_intentHash);
+ address intentOwnerOrchestrator = intentOrchestrator[_intentHash];
+ if (intentOwnerOrchestrator != msg.sender) revert UnauthorizedCaller(msg.sender, intentOwnerOrchestrator);
// Effects
deposit.remainingDeposits += intent.amount;
deposit.outstandingIntentAmount -= intent.amount;
- _pruneIntent(_depositId, _intentHash);
+ _pruneIntent(_depositId, _intentHash, true);
emit FundsUnlocked(_depositId, _intentHash, intent.amount);
}
/**
* @notice ORCHESTRATOR ONLY: Unlocks and transfers funds from a fulfilled intent by removing the specific intent.
- * Only callable by orchestrator. Releases the lock on deposlit liquidity and transfers out partial/full locked
- * amount to the given to address.
- *
+ * @dev Caller must be the same orchestrator that originally locked the intent.
+ * Releases the lock on deposit liquidity and transfers out partial/full locked amount to the given to address.
+ *
* @param _depositId The deposit ID to transfer from
* @param _intentHash The intent hash to find and remove the intent for
* @param _transferAmount The amount to actually transfer (may be less than intent amount)
@@ -661,6 +815,8 @@
if (deposit.depositor == address(0)) revert DepositNotFound(_depositId);
if (intent.intentHash == bytes32(0)) revert IntentNotFound(_intentHash);
+ address intentOwnerOrchestrator = intentOrchestrator[_intentHash];
+ if (intentOwnerOrchestrator != msg.sender) revert UnauthorizedCaller(msg.sender, intentOwnerOrchestrator);
if (_transferAmount == 0) revert ZeroValue();
if (_transferAmount > intent.amount) revert AmountExceedsAvailable(_transferAmount, intent.amount);
@@ -672,7 +828,7 @@
deposit.remainingDeposits += (intent.amount - _transferAmount);
}
- _pruneIntent(_depositId, _intentHash);
+ _pruneIntent(_depositId, _intentHash, true);
IERC20 token = deposit.token;
_closeDepositIfNecessary(_depositId, deposit);
@@ -724,15 +880,15 @@
/* ============ Governance Functions ============ */
/**
- * @notice GOVERNANCE ONLY: Sets the orchestrator contract address. Only callable by owner.
- *
- * @param _orchestrator The orchestrator contract address
+ * @notice GOVERNANCE ONLY: Sets the orchestrator registry used for escrow authorization.
+ * @dev Only callable by owner.
+ * @param _orchestratorRegistry New orchestrator registry address.
*/
- function setOrchestrator(address _orchestrator) external onlyOwner {
- if (_orchestrator == address(0)) revert ZeroAddress();
-
- orchestrator = IOrchestrator(_orchestrator);
- emit OrchestratorUpdated(_orchestrator);
+ function setOrchestratorRegistry(address _orchestratorRegistry) external onlyOwner {
+ if (_orchestratorRegistry == address(0)) revert ZeroAddress();
+
+ orchestratorRegistry = IOrchestratorRegistry(_orchestratorRegistry);
+ emit OrchestratorRegistryUpdated(_orchestratorRegistry);
}
/**
@@ -845,9 +1001,60 @@
}
function getDepositCurrencyMinRate(uint256 _depositId, bytes32 _paymentMethod, bytes32 _currencyCode) external view returns (uint256) {
- return depositCurrencyMinRate[_depositId][_paymentMethod][_currencyCode];
+ return _getDepositCurrencyMinRate(_depositId, _paymentMethod, _currencyCode);
}
+ function getEffectiveRate(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode
+ )
+ external
+ view
+ returns (uint256)
+ {
+ RateManagerConfig memory config = depositRateManagerConfig[_depositId];
+ if (config.rateManager != address(0)) {
+ return IRateManager(config.rateManager).getRate(
+ config.rateManagerId,
+ address(this),
+ _depositId,
+ _paymentMethod,
+ _currencyCode
+ );
+ }
+ return _getDepositCurrencyMinRate(_depositId, _paymentMethod, _currencyCode);
+ }
+
+ function getManagerFee(uint256 _depositId) external view returns (address recipient, uint256 fee) {
+ RateManagerConfig memory config = depositRateManagerConfig[_depositId];
+ if (config.rateManager == address(0)) {
+ return (address(0), 0);
+ }
+ return IRateManager(config.rateManager).getFee(config.rateManagerId);
+ }
+
+ function getDepositRateManager(uint256 _depositId)
+ external
+ view
+ returns (address rateManager, bytes32 rateManagerId)
+ {
+ RateManagerConfig memory config = depositRateManagerConfig[_depositId];
+ return (config.rateManager, config.rateManagerId);
+ }
+
+ function getDepositOracleRateConfig(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode
+ )
+ external
+ view
+ returns (OracleRateConfig memory)
+ {
+ return depositOracleRateConfig[_depositId][_paymentMethod][_currencyCode];
+ }
+
function getDepositCurrencyListed(uint256 _depositId, bytes32 _paymentMethod, bytes32 _currencyCode) external view returns (bool) {
return depositCurrencyListed[_depositId][_paymentMethod][_currencyCode];
}
@@ -916,9 +1123,7 @@
/**
* @notice Free up deposit liquidity by reclaiming liquidity from expired intents. Only reclaims if remaining deposits amount
- * is less than the minimum required amount. Returns the expired intents that need to be pruned. Only does local state updates,
- * does not call any external contracts. Whenever this function is called, the calling function should also call _tryOrchestratorPruneIntents
- * with the returned intents to expire the intents on the orchestrator contract.
+ * is less than the minimum required amount. Returns the expired intents that need to be pruned.
*/
function _reclaimLiquidityIfNecessary(
Deposit storage _deposit,
@@ -942,7 +1147,7 @@
// Prune intents locally and emit funds unlocked events
for (uint256 i = 0; i < expiredIntents.length; i++) {
Intent memory intent = depositIntents[_depositId][expiredIntents[i]];
- _pruneIntent(_depositId, intent.intentHash);
+ _pruneIntent(_depositId, intent.intentHash, false);
emit FundsUnlocked(_depositId, intent.intentHash, intent.amount);
}
@@ -952,9 +1157,12 @@
/**
* @notice Prunes an intent from a deposit locally. Does not call orchestrator.
*/
- function _pruneIntent(uint256 _depositId, bytes32 _intentHash) internal {
+ function _pruneIntent(uint256 _depositId, bytes32 _intentHash, bool _clearOrchestrator) internal {
delete depositIntents[_depositId][_intentHash];
depositIntentHashes[_depositId].removeStorage(_intentHash);
+ if (_clearOrchestrator) {
+ delete intentOrchestrator[_intentHash];
+ }
}
/**
@@ -962,7 +1170,19 @@
* Note: If the orchestrator reverts, it is caught and ignored to allow the function to continue execution.
*/
function _tryOrchestratorPruneIntents(bytes32[] memory _intents) internal {
- try IOrchestrator(orchestrator).pruneIntents(_intents) {} catch {}
+ for (uint256 i = 0; i < _intents.length; i++) {
+ bytes32 intentHash = _intents[i];
+ address orchestratorAddress = intentOrchestrator[intentHash];
+ if (orchestratorAddress == address(0)) {
+ continue;
+ }
+
+ bytes32[] memory singleIntent = new bytes32[](1);
+ singleIntent[0] = intentHash;
+
+ try IOrchestrator(orchestratorAddress).pruneIntents(singleIntent) {} catch {}
+ delete intentOrchestrator[intentHash];
+ }
}
/**
@@ -1005,6 +1225,7 @@
function _closeDeposit(uint256 _depositId, Deposit storage _deposit) internal {
address depositor = _deposit.depositor;
accountDeposits[depositor].removeStorage(_depositId);
+ delete depositRateManagerConfig[_depositId];
_deleteDepositPaymentMethodAndCurrencyData(_depositId);
@@ -1028,6 +1249,7 @@
for (uint256 j = 0; j < currencies.length; j++) {
bytes32 currencyCode = currencies[j];
delete depositCurrencyMinRate[_depositId][paymentMethod][currencyCode];
+ delete depositOracleRateConfig[_depositId][paymentMethod][currencyCode];
delete depositCurrencyListed[_depositId][paymentMethod][currencyCode];
}
delete depositCurrencies[_depositId][paymentMethod];
@@ -1095,7 +1317,6 @@
if (!paymentVerifierRegistry.isCurrency(_paymentMethod, _currencyCode)) {
revert CurrencyNotSupported(_paymentMethod, _currencyCode);
}
- if (_minConversionRate == 0) revert ZeroConversionRate();
if (depositCurrencyListed[_depositId][_paymentMethod][_currencyCode]) {
revert CurrencyAlreadyExists(_paymentMethod, _currencyCode);
}
@@ -1107,4 +1328,85 @@
emit DepositCurrencyAdded(_depositId, _paymentMethod, _currencyCode, _minConversionRate);
}
+
+ function _setOracleRateConfig(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode,
+ OracleRateConfig calldata _config
+ ) internal {
+ if (!depositCurrencyListed[_depositId][_paymentMethod][_currencyCode]) {
+ revert CurrencyNotSupported(_paymentMethod, _currencyCode);
+ }
+ if (_config.adapter == address(0)) revert ZeroAddress();
+ if (_config.adapter.code.length == 0) revert InvalidOracleAdapter(_config.adapter);
+ if (_config.spreadBps > BPS) revert InvalidSpread(_config.spreadBps);
+ if (_config.maxStaleness == 0) revert ZeroValue();
+
+ bytes memory normalizedConfig = IOracleAdapter(_config.adapter).validateConfig(_config.adapterConfig);
+
+ depositOracleRateConfig[_depositId][_paymentMethod][_currencyCode] = OracleRateConfig({
+ adapter: _config.adapter,
+ adapterConfig: normalizedConfig,
+ spreadBps: _config.spreadBps,
+ maxStaleness: _config.maxStaleness
+ });
+
+ emit DepositOracleRateConfigSet(
+ _depositId,
+ _paymentMethod,
+ _currencyCode,
+ _config.adapter,
+ normalizedConfig,
+ _config.spreadBps,
+ _config.maxStaleness
+ );
+ }
+
+ function _getDepositCurrencyMinRate(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode
+ )
+ internal
+ view
+ returns (uint256)
+ {
+ uint256 fixedRate = depositCurrencyMinRate[_depositId][_paymentMethod][_currencyCode];
+ OracleRateConfig memory oracleConfig = depositOracleRateConfig[_depositId][_paymentMethod][_currencyCode];
+ uint256 spreadRate = _computeSpreadRate(oracleConfig);
+
+ return fixedRate > spreadRate ? fixedRate : spreadRate;
+ }
+
+ function _computeSpreadRate(OracleRateConfig memory _config) internal view returns (uint256) {
+ if (_config.adapter == address(0)) {
+ return 0;
+ }
+
+ try IOracleAdapter(_config.adapter).getRate(_config.adapterConfig) returns (
+ bool isValidQuote,
+ uint256 marketRate,
+ uint256 rateUpdatedAt
+ ) {
+ if (!isValidQuote || marketRate == 0) {
+ return 0;
+ }
+ if (rateUpdatedAt == 0 || rateUpdatedAt > block.timestamp) {
+ return 0;
+ }
+ if (block.timestamp - rateUpdatedAt > _config.maxStaleness) {
+ return 0;
+ }
+
+ return Math.mulDiv(
+ marketRate,
+ BPS + uint256(_config.spreadBps),
+ BPS,
+ Math.Rounding.Up
+ );
+ } catch {
+ return 0;
+ }
+ }
}
--- contracts/interfaces/IEscrow.sol 2026-02-18 17:54:06
+++ contracts/interfaces/IEscrowV2.sol 2026-02-19 14:01:50
@@ -2,171 +2,118 @@
pragma solidity ^0.8.18;
-import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-import { IPostIntentHook } from "./IPostIntentHook.sol";
+import { IEscrow } from "./IEscrow.sol";
-interface IEscrow {
-
+/**
+ * @title IEscrowV2
+ * @notice Extended escrow interface with native oracle-spread rates and delegated rate managers.
+ */
+interface IEscrowV2 is IEscrow {
/* ============ Structs ============ */
- struct Intent {
- bytes32 intentHash; // Unique identifier for the intent
- uint256 amount; // Amount locked
- uint256 timestamp; // When this intent was created
- uint256 expiryTime; // When this intent expires
+ struct OracleRateConfig {
+ address adapter;
+ bytes adapterConfig;
+ uint16 spreadBps;
+ uint32 maxStaleness;
}
- struct Range {
- uint256 min; // Minimum value
- uint256 max; // Maximum value
+ struct RateManagerConfig {
+ address rateManager;
+ bytes32 rateManagerId;
}
- struct Deposit {
- address depositor; // Address of depositor
- address delegate; // Address that can manage this deposit (address(0) if no delegate)
- IERC20 token; // Address of deposit token
- Range intentAmountRange; // Range of take amount per intent
- // Deposit state
- bool acceptingIntents; // State: True if the deposit is accepting intents, False otherwise
- uint256 remainingDeposits; // State: Amount of liquidity immediately available to lock
- uint256 outstandingIntentAmount; // State: Amount of outstanding intents (may include expired intents)
- // Intent guardian
- address intentGuardian; // Address that can extend intent expiry times (address(0) if no guardian)
- // Retention behavior
- bool retainOnEmpty; // If true, do not auto-close/sweep when empty; keep config for reuse
- }
-
- struct Currency {
- bytes32 code; // Currency code (keccak256 hash of the currency code)
- uint256 minConversionRate; // Minimum rate of deposit token to fiat currency (in preciseUnits)
- }
-
- struct DepositPaymentMethodData {
- address intentGatingService; // Public key of gating service that will be used to verify intents
- bytes32 payeeDetails; // Payee details, has to be hash of payee details
- bytes data; // Verification Data: Additional data used for payment verification; Can hold attester address
- // in case of TLS proofs, domain key hash in case of zkEmail proofs, currency code etc.
- }
-
- struct CreateDepositParams {
- IERC20 token; // The token to be deposited
- uint256 amount; // The amount of token to deposit
- Range intentAmountRange; // The max and min take amount for each intent
- bytes32[] paymentMethods; // The payment methods that deposit supports
- DepositPaymentMethodData[] paymentMethodData;// The payment verification data for each payment method that deposit supports
- Currency[][] currencies; // The currencies for each payment method that deposit supports
- address delegate; // Optional delegate address that can manage this deposit (address(0) for no delegate)
- address intentGuardian; // Optional intent guardian address that can extend intent expiry times (address(0) for no guardian)
- bool retainOnEmpty; // Opt-in: keep deposit and config when empty
- }
-
/* ============ Events ============ */
- event DepositReceived(uint256 indexed depositId, address indexed depositor, IERC20 indexed token, uint256 amount, Range intentAmountRange, address delegate, address intentGuardian);
+ event DepositOracleRateConfigSet(
+ uint256 indexed depositId,
+ bytes32 indexed paymentMethod,
+ bytes32 indexed currencyCode,
+ address adapter,
+ bytes adapterConfig,
+ uint16 spreadBps,
+ uint32 maxStaleness
+ );
- event DepositPaymentMethodAdded(uint256 indexed depositId, bytes32 indexed paymentMethod, bytes32 indexed payeeDetails, address intentGatingService);
- event DepositPaymentMethodActiveUpdated(uint256 indexed depositId, bytes32 indexed paymentMethod, bool active);
+ event DepositOracleRateConfigRemoved(
+ uint256 indexed depositId,
+ bytes32 indexed paymentMethod,
+ bytes32 indexed currencyCode
+ );
- event DepositCurrencyAdded(uint256 indexed depositId, bytes32 indexed paymentMethod, bytes32 indexed currency, uint256 minConversionRate);
- event DepositMinConversionRateUpdated(uint256 indexed depositId, bytes32 indexed paymentMethod, bytes32 indexed currency, uint256 newMinConversionRate);
-
- event DepositFundsAdded(uint256 indexed depositId, address indexed depositor, uint256 amount);
- event DepositWithdrawn(uint256 indexed depositId, address indexed depositor, uint256 amount);
- event DepositClosed(uint256 depositId, address depositor);
- event DepositAcceptingIntentsUpdated(uint256 indexed depositId, bool acceptingIntents);
+ event DepositRateManagerSet(
+ uint256 indexed depositId,
+ address indexed rateManager,
+ bytes32 indexed rateManagerId
+ );
- event DepositIntentAmountRangeUpdated(uint256 indexed depositId, Range intentAmountRange);
- event DepositRetainOnEmptyUpdated(uint256 indexed depositId, bool retainOnEmpty);
+ event DepositRateManagerCleared(
+ uint256 indexed depositId,
+ address indexed rateManager,
+ bytes32 indexed rateManagerId
+ );
- event DepositDelegateSet(uint256 indexed depositId, address indexed depositor, address indexed delegate);
- event DepositDelegateRemoved(uint256 indexed depositId, address indexed depositor);
+ event OrchestratorRegistryUpdated(address indexed orchestratorRegistry);
- event MinDepositAmountSet(uint256 minDepositAmount);
+ /* ============ Custom Errors ============ */
- event OrchestratorUpdated(address indexed orchestrator);
- event PaymentVerifierRegistryUpdated(address indexed paymentVerifierRegistry);
+ error InvalidOracleAdapter(address adapter);
+ error InvalidRateManager(address rateManager);
+ error InvalidSpread(uint256 spreadBps);
+ error RateManagerAlreadySet(bytes32 rateManagerId);
+ error RateManagerNotFound(bytes32 rateManagerId);
+ error RateManagerNotSet(uint256 depositId);
- event FundsLocked(uint256 indexed depositId, bytes32 indexed intentHash, uint256 amount, uint256 expiryTime);
- event FundsUnlocked(uint256 indexed depositId, bytes32 indexed intentHash, uint256 amount);
- event FundsUnlockedAndTransferred(
- uint256 indexed depositId,
- bytes32 indexed intentHash,
- uint256 unlockedAmount,
- uint256 transferredAmount,
- address to
- );
- event IntentExpiryExtended(uint256 indexed depositId, bytes32 indexed intentHash, uint256 newExpiryTime);
+ /* ============ External Functions ============ */
- event DustRecipientUpdated(address indexed dustRecipient);
- event DustCollected(uint256 indexed depositId, uint256 dustAmount, address indexed dustRecipient);
- event DustThresholdUpdated(uint256 dustThreshold);
- event MaxIntentsPerDepositUpdated(uint256 maxIntentsPerDeposit);
- event IntentExpirationPeriodUpdated(uint256 intentExpirationPeriod);
+ function setOracleRateConfig(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode,
+ OracleRateConfig calldata _config
+ ) external;
- /* ============ Standardized Custom Errors ============ */
-
- // Zero value errors
- error ZeroAddress();
- error ZeroValue();
- error ZeroMinValue();
- error ZeroConversionRate();
+ function setOracleRateConfigBatch(
+ uint256 _depositId,
+ bytes32[] calldata _paymentMethods,
+ bytes32[][] calldata _currencyCodes,
+ OracleRateConfig[][] calldata _configs
+ ) external;
- // Authorization errors
- error UnauthorizedCaller(address caller, address authorized);
- error UnauthorizedCallerOrDelegate(address caller, address owner, address delegate);
+ function removeOracleRateConfig(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode
+ ) external;
- // Range and amount errors
- error InvalidRange(uint256 min, uint256 max);
- error AmountBelowMin(uint256 amount, uint256 min);
- error AmountAboveMax(uint256 amount, uint256 max);
- error AmountExceedsAvailable(uint256 requested, uint256 available);
+ function setRateManager(
+ uint256 _depositId,
+ address _rateManager,
+ bytes32 _rateManagerId
+ ) external;
- // Not found errors
- error DepositNotFound(uint256 depositId);
- error IntentNotFound(bytes32 intentHash);
- error PaymentMethodNotActive(uint256 depositId, bytes32 paymentMethod);
- error PaymentMethodNotListed(uint256 depositId, bytes32 paymentMethod);
- error CurrencyNotFound(bytes32 paymentMethod, bytes32 currency);
- error DelegateNotFound(uint256 depositId);
+ function clearRateManager(uint256 _depositId) external;
- // Already exists errors
- error PaymentMethodAlreadyExists(uint256 depositId, bytes32 paymentMethod);
- error CurrencyAlreadyExists(bytes32 paymentMethod, bytes32 currency);
- error IntentAlreadyExists(uint256 depositId, bytes32 intentHash);
+ function setOrchestratorRegistry(address _orchestratorRegistry) external;
- // State errors
- error DepositNotAcceptingIntents(uint256 depositId);
- error DepositAlreadyInState(uint256 depositId, bool currentState);
- error InsufficientDepositLiquidity(uint256 depositId, uint256 available, uint256 required);
- error MaxIntentsExceeded(uint256 depositId, uint256 current, uint256 max);
+ /* ============ View Functions ============ */
- // Validation errors
- error EmptyPayeeDetails();
- error ArrayLengthMismatch(uint256 length1, uint256 length2);
+ function getDepositOracleRateConfig(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode
+ ) external view returns (OracleRateConfig memory);
- // Payment method errors
- error PaymentMethodNotWhitelisted(bytes32 paymentMethod);
- error CurrencyNotSupported(bytes32 paymentMethod, bytes32 currency);
+ function getDepositRateManager(uint256 _depositId)
+ external
+ view
+ returns (address rateManager, bytes32 rateManagerId);
-
- /* ============ External Functions for Orchestrator ============ */
+ function getEffectiveRate(
+ uint256 _depositId,
+ bytes32 _paymentMethod,
+ bytes32 _currencyCode
+ ) external view returns (uint256);
- function lockFunds(uint256 _depositId, bytes32 _intentHash, uint256 _amount) external;
- function unlockFunds(uint256 _depositId, bytes32 _intentHash) external;
- function unlockAndTransferFunds(uint256 _depositId, bytes32 _intentHash, uint256 _transferAmount, address _to) external;
- function extendIntentExpiry(uint256 _depositId, bytes32 _intentHash, uint256 _newExpiryTime) external;
-
- /* ============ View Functions ============ */
-
- function getDeposit(uint256 _depositId) external view returns (Deposit memory);
- function getDepositIntent(uint256 _depositId, bytes32 _intentHash) external view returns (Intent memory);
- function getDepositPaymentMethods(uint256 _depositId) external view returns (bytes32[] memory);
- function getDepositCurrencies(uint256 _depositId, bytes32 _paymentMethod) external view returns (bytes32[] memory);
- function getDepositCurrencyMinRate(uint256 _depositId, bytes32 _paymentMethod, bytes32 _currencyCode) external view returns (uint256);
- function getDepositPaymentMethodData(uint256 _depositId, bytes32 _paymentMethod) external view returns (DepositPaymentMethodData memory);
- function getDepositPaymentMethodActive(uint256 _depositId, bytes32 _paymentMethod) external view returns (bool);
- function getDepositGatingService(uint256 _depositId, bytes32 _paymentMethod) external view returns (address);
- function getAccountDeposits(address _account) external view returns (uint256[] memory);
- function getDepositIntentHashes(uint256 _depositId) external view returns (bytes32[] memory);
- function getExpiredIntents(uint256 _depositId) external view returns (bytes32[] memory expiredIntents, uint256 reclaimableAmount);
+ function getManagerFee(uint256 _depositId) external view returns (address recipient, uint256 fee);
}
--- contracts/interfaces/IOrchestrator.sol 2026-02-19 13:55:27
+++ contracts/interfaces/IOrchestratorV2.sol 2026-02-19 13:58:47
@@ -2,162 +2,11 @@
pragma solidity ^0.8.18;
-import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-import { IPostIntentHook } from "./IPostIntentHook.sol";
-import { IPreIntentHook } from "./IPreIntentHook.sol";
+import { IOrchestrator } from "./IOrchestrator.sol";
-interface IOrchestrator {
-
- /* ============ Structs ============ */
-
- struct Intent {
- address owner; // Address of the intent owner
- address to; // Address to forward funds to (can be same as owner)
- address escrow; // Address of the escrow contract holding the deposit
- uint256 depositId; // ID of the deposit the intent is associated with
- uint256 amount; // Amount of the deposit.token the owner wants to take
- uint256 timestamp; // Timestamp of the intent
- bytes32 paymentMethod; // The payment method to be used for the offchain payment
- bytes32 fiatCurrency; // Currency code that the owner is paying in offchain (keccak256 hash of the currency code)
- uint256 conversionRate; // Conversion rate of deposit token to fiat currency at the time of intent
- bytes32 payeeId; // Hashed payee identifier to whom the owner will pay offchain
- address referrer; // Address of the referrer who brought this intent (if any)
- uint256 referrerFee; // Fee to be paid to the referrer in preciseUnits (1e16 = 1%)
- IPostIntentHook postIntentHook; // Address of the post-intent hook that will execute any post-intent actions
- bytes data; // Additional data to be passed to the post-intent hook contract
- }
-
- struct SignalIntentParams {
- address escrow; // The escrow contract where the deposit is held
- uint256 depositId; // The ID of the deposit the taker intends to use
- uint256 amount; // The amount of deposit.token the user wants to take
- address to; // Address to forward funds to
- bytes32 paymentMethod; // The payment method to be used for the offchain payment
- bytes32 fiatCurrency; // The currency code for offchain payment
- uint256 conversionRate; // The conversion rate agreed offchain
- address referrer; // Address of the referrer (address(0) if no referrer)
- uint256 referrerFee; // Fee to be paid to the referrer
- bytes gatingServiceSignature; // Signature from the deposit's gating service
- uint256 signatureExpiration; // Timestamp when the gating service signature expires
- IPostIntentHook postIntentHook; // Optional post-intent hook (address(0) for no hook)
- bytes preIntentHookData; // Ephemeral data passed only to the pre-intent hook during signalIntent
- bytes data; // Signal data persisted in Intent and forwarded as post-intent hook signalHookData
- }
-
- struct FulfillIntentParams {
- bytes paymentProof; // Payment proof. Can be Groth16 Proof, TLSNotary proof, TLSProxy proof, attestation etc.
- bytes32 intentHash; // Identifier of intent being fulfilled
- bytes verificationData; // Additional data for payment verifier
- bytes postIntentHookData; // Additional data for post intent hook
- }
-
- /* ============ Events ============ */
-
- event IntentSignaled(
- bytes32 indexed intentHash,
- address indexed escrow,
- uint256 indexed depositId,
- bytes32 paymentMethod,
- address owner,
- address to,
- uint256 amount,
- bytes32 fiatCurrency,
- uint256 conversionRate,
- uint256 timestamp
- );
-
- event IntentPruned(
- bytes32 indexed intentHash
- );
-
- event IntentFulfilled(
- bytes32 indexed intentHash,
- address indexed fundsTransferredTo, // Address that funds were transferred to; can be intent.to or postIntentHook address
- uint256 amount,
- bool isManualRelease
- );
-
- event IntentManagerFeeSnapshotted(bytes32 indexed intentHash, address indexed feeRecipient, uint256 fee);
- event DepositPreIntentHookSet(address indexed escrow, uint256 indexed depositId, address indexed hook, address setter);
- event DepositWhitelistHookSet(address indexed escrow, uint256 indexed depositId, address indexed hook, address setter);
-
- event AllowMultipleIntentsUpdated(bool allowMultiple);
-
- event PaymentVerifierRegistryUpdated(address indexed paymentVerifierRegistry);
- event RelayerRegistryUpdated(address indexed relayerRegistry);
- event EscrowRegistryUpdated(address indexed escrowRegistry);
- event DepositRateManagerControllerUpdated(address indexed depositRateManagerController);
-
- event ProtocolFeeUpdated(uint256 protocolFee);
- event ProtocolFeeRecipientUpdated(address indexed protocolFeeRecipient);
- event PartialManualReleaseDelayUpdated(uint256 partialManualReleaseDelay);
-
- /* ============ Standardized Custom Errors ============ */
-
- // Zero value errors
- error ZeroAddress();
- error ZeroValue();
-
- // Authorization errors
- error UnauthorizedEscrowCaller(address caller);
- error UnauthorizedCaller(address caller, address authorized);
- error UnauthorizedCallerOrDelegate(address caller, address owner, address delegate);
-
- // Not found errors
- error IntentNotFound(bytes32 intentHash);
- error PaymentMethodDoesNotExist(bytes32 paymentMethod);
- error PaymentMethodNotSupported(bytes32 paymentMethod);
- error CurrencyNotSupported(bytes32 paymentMethod, bytes32 currency);
-
- // Whitelist errors
- error PaymentMethodNotWhitelisted(bytes32 paymentMethod);
- error EscrowNotWhitelisted(address escrow);
-
- // Amount and fee errors
- error AmountBelowMin(uint256 amount, uint256 min);
- error AmountAboveMax(uint256 amount, uint256 max);
- error AmountExceedsLimit(uint256 amount, uint256 limit);
- error FeeExceedsMaximum(uint256 fee, uint256 maximum);
- error RateBelowMinimum(uint256 rate, uint256 minRate);
-
- // Validation errors
- error AccountHasActiveIntent(address account, bytes32 existingIntent);
- error InvalidReferrerFeeConfiguration();
- error InvalidPostIntentHook(address hook);
- error InvalidPreIntentHook(address hook);
- error InvalidSignature();
- error SignatureExpired(uint256 expiration, uint256 currentTime);
- error PartialReleaseNotAllowedYet(uint256 currentTime, uint256 allowedTime);
- error DepositRateManagerControllerNotSet();
-
- // Verification errors
- error PaymentVerificationFailed();
- error HashMismatch(bytes32 expected, bytes32 actual);
-
- // Transfer errors
- error TransferFailed(address recipient, uint256 amount);
- error EscrowLockFailed();
-
- /* ============ View Functions ============ */
-
- function getIntent(bytes32 intentHash) external view returns (Intent memory);
- function getAccountIntents(address account) external view returns (bytes32[] memory);
- function getDepositPreIntentHook(address escrow, uint256 depositId) external view returns (IPreIntentHook);
- function getDepositWhitelistHook(address escrow, uint256 depositId) external view returns (IPreIntentHook);
-
- /* ============ External Functions for Users ============ */
-
- function signalIntent(SignalIntentParams calldata params) external;
- function setDepositPreIntentHook(address escrow, uint256 depositId, IPreIntentHook hook) external;
- function setDepositWhitelistHook(address escrow, uint256 depositId, IPreIntentHook hook) external;
-
- function cancelIntent(bytes32 intentHash) external;
-
- function fulfillIntent(FulfillIntentParams calldata params) external;
-
- function releaseFundsToPayer(bytes32 intentHash) external;
-
- /* ============ External Functions for Escrow ============ */
-
- function pruneIntents(bytes32[] calldata intentIds) external;
-}
+/**
+ * @title IOrchestratorV2
+ * @notice Marker interface for the EscrowV2-aware orchestrator.
+ * @dev Inherits current orchestrator surface and behavior while changing Escrow rate query routing.
+ */
+interface IOrchestratorV2 is IOrchestrator {}
--- contracts/Orchestrator.sol 2026-02-19 13:55:27
+++ contracts/OrchestratorV2.sol 2026-02-19 14:02:52
@@ -11,22 +11,22 @@
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { AddressArrayUtils } from "./external/AddressArrayUtils.sol";
import { Bytes32ArrayUtils } from "./external/Bytes32ArrayUtils.sol";
-import { IOrchestrator } from "./interfaces/IOrchestrator.sol";
+import { IOrchestratorV2 } from "./interfaces/IOrchestratorV2.sol";
import { IEscrow } from "./interfaces/IEscrow.sol";
+import { IEscrowV2 } from "./interfaces/IEscrowV2.sol";
import { IEscrowRegistry } from "./interfaces/IEscrowRegistry.sol";
import { IPostIntentHook } from "./interfaces/IPostIntentHook.sol";
import { IPreIntentHook } from "./interfaces/IPreIntentHook.sol";
import { IPaymentVerifier } from "./interfaces/IPaymentVerifier.sol";
import { IPaymentVerifierRegistry } from "./interfaces/IPaymentVerifierRegistry.sol";
import { IRelayerRegistry } from "./interfaces/IRelayerRegistry.sol";
-import { IDepositRateManagerController } from "./interfaces/IDepositRateManagerController.sol";
/**
- * @title Orchestrator
+ * @title OrchestratorV2
* @notice Orchestrator contract for the ZKP2P protocol. This contract is responsible for managing the intent (order)
* lifecycle and orchestrating the P2P trading of fiat currency and onchain assets.
*/
-contract Orchestrator is Ownable, Pausable, ReentrancyGuard, IOrchestrator {
+contract OrchestratorV2 is Ownable, Pausable, ReentrancyGuard, IOrchestratorV2 {
using AddressArrayUtils for address[];
using Bytes32ArrayUtils for bytes32[];
@@ -67,7 +67,6 @@
IEscrowRegistry public escrowRegistry; // Registry of escrow contracts
IPaymentVerifierRegistry public paymentVerifierRegistry; // Registry of payment verifiers
IRelayerRegistry public relayerRegistry; // Registry of relayers
- IDepositRateManagerController public depositRateManagerController; // External controller for rate manager config
// Protocol fee configuration
uint256 public protocolFee; // Protocol fee taken from taker (in preciseUnits, 1e16 = 1%)
@@ -127,7 +126,7 @@
_params.paymentMethod
);
- (address managerFeeRecipient, uint256 managerFee) = depositRateManagerController.getManagerFee(_params.escrow, _params.depositId);
+ (address managerFeeRecipient, uint256 managerFee) = IEscrowV2(_params.escrow).getManagerFee(_params.depositId);
// Enforce manager fee cap regardless of registry implementation
if (managerFee > MAX_MANAGER_FEE) revert FeeExceedsMaximum(managerFee, MAX_MANAGER_FEE); // policy cap (e.g., 5%)
intentManagerFeeRecipient[intentHash] = managerFeeRecipient;
@@ -425,18 +424,6 @@
relayerRegistry = IRelayerRegistry(_relayerRegistry);
emit RelayerRegistryUpdated(_relayerRegistry);
- }
-
- /**
- * @notice GOVERNANCE ONLY: Updates the deposit rate manager controller address.
- *
- * @param _depositRateManagerController New controller address
- */
- function setDepositRateManagerController(address _depositRateManagerController) external onlyOwner {
- if (_depositRateManagerController == address(0)) revert ZeroAddress();
-
- depositRateManagerController = IDepositRateManagerController(_depositRateManagerController);
- emit DepositRateManagerControllerUpdated(_depositRateManagerController);
}
/**
@@ -515,8 +502,6 @@
if (!escrowRegistry.isWhitelistedEscrow(_intent.escrow) && !escrowRegistry.isAcceptingAllEscrows()) {
revert EscrowNotWhitelisted(_intent.escrow);
}
-
- if (address(depositRateManagerController) == address(0)) revert DepositRateManagerControllerNotSet();
// Verify payment method is still valid in registry
address verifier = paymentVerifierRegistry.getVerifier(_intent.paymentMethod);
@@ -525,8 +510,7 @@
bool isPaymentMethodActive = IEscrow(_intent.escrow).getDepositPaymentMethodActive(_intent.depositId, _intent.paymentMethod);
if (!isPaymentMethodActive) revert PaymentMethodNotSupported(_intent.paymentMethod);
- uint256 minConversionRate = depositRateManagerController.getEffectiveMinRate(
- _intent.escrow,
+ uint256 minConversionRate = IEscrowV2(_intent.escrow).getEffectiveRate(
_intent.depositId,
_intent.paymentMethod,
_intent.fiatCurrency
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment