// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.

package hybrid_with_external_minter_fast_transfer_token_pool

var SolidityStandardInput = "{\"version\":\"0.8.26\",\"language\":\"Solidity\",\"settings\":{\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"appendCBOR\":true,\"bytecodeHash\":\"none\",\"useLiteralContent\":false},\"optimizer\":{\"enabled\":true,\"runs\":500},\"outputSelection\":{\"contracts/stablecoin-governor/HybridTokenPoolAbstract.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"contracts/stablecoin-governor/HybridWithExternalMinterFastTransferTokenPool.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"contracts/stablecoin-governor/interfaces/IExternalMinter.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/applications/CCIPReceiver.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IAny2EVMMessageReceiver.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IFastTransferPool.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IPool.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IRMN.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IRouter.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IRouterClient.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/Client.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/Internal.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/MerkleMultiProof.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/Pool.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/RateLimiter.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/pools/FastTransferTokenPoolAbstract.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/pools/TokenPool.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/shared/access/Ownable2Step.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/shared/access/Ownable2StepMsgSender.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/shared/interfaces/IOwnable.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/Address.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]}},\"remappings\":[\"@chainlink/contracts/=node_modules/@chainlink/contracts/\",\"@chainlink/contracts-ccip/contracts/=node_modules/@chainlink/contracts-ccip/chains/evm/contracts/\",\"forge-std/=node_modules/@chainlink/contracts/src/v0.8/vendor/forge-std/src/\",\"@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\"],\"viaIR\":true},\"sources\":{\"contracts/stablecoin-governor/HybridTokenPoolAbstract.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.24;\\n\\nimport {IExternalMinter} from \\\"./interfaces/IExternalMinter.sol\\\";\\n\\nimport {Pool} from \\\"@chainlink/contracts-ccip/contracts/libraries/Pool.sol\\\";\\nimport {TokenPool} from \\\"@chainlink/contracts-ccip/contracts/pools/TokenPool.sol\\\";\\n\\nimport {IERC20} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol\\\";\\nimport {SafeERC20} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title HybridTokenPoolAbstract\\n/// @notice Base functionality for Hybrid Token Pools\\n/// @dev Contains shared group management, liquidity management, token management and rebalancer functionality.\\nabstract contract HybridTokenPoolAbstract is TokenPool {\\n  using SafeERC20 for IERC20;\\n\\n  error InvalidGroupUpdate(uint64 remoteChainSelector, Group group);\\n  error LiquidityAmountCannotBeZero();\\n  error TokenMismatch(IERC20 expected, IERC20 actual);\\n\\n  event RebalancerSet(address indexed oldRebalancer, address indexed newRebalancer);\\n  event GroupUpdated(uint64 indexed remoteChainSelector, Group indexed group);\\n  event LiquidityAdded(address indexed rebalancer, uint256 amount);\\n  event LiquidityRemoved(address indexed rebalancer, uint256 amount);\\n  event LiquidityMigrated(uint64 indexed remoteChainSelector, Group indexed group, uint256 remoteChainSupply);\\n\\n  /// @dev By default, all chains are in the LOCK_AND_RELEASE group.\\n  enum Group {\\n    LOCK_AND_RELEASE, // 0: Lock tokens on source, release on destination\\n    BURN_AND_MINT // 1: Burn tokens on source, mint on destination\\n\\n  }\\n\\n  /// @dev Struct to hold group update information\\n  struct GroupUpdate {\\n    uint64 remoteChainSelector; // ─╮ Remote chain selector\\n    Group group; // ────────────────╯ New group to set\\n    uint256 remoteChainSupply; // Supply amount to migrate\\n  }\\n\\n  /// @dev The external minter contract instance\\n  address internal immutable i_minter;\\n  /// @dev Address of the rebalancer contract\\n  address internal s_rebalancer;\\n  /// @dev Mapping that stores the operational mode configuration for each remote chain selector.\\n  /// (e.g., LOCK_AND_RELEASE or BURN_AND_MINT). By default, chains are set to LOCK_AND_RELEASE.\\n  mapping(uint64 remoteChainSelector =\\u003e Group) internal s_groups;\\n\\n  /// @notice Returns the locked tokens in the pool.\\n  /// @return The amount of locked tokens in the pool.\\n  function getLockedTokens() external view virtual returns (uint256) {\\n    return getToken().balanceOf(address(this));\\n  }\\n\\n  /// @notice Returns the address of the rebalancer.\\n  /// @return The address of the rebalancer.\\n  function getRebalancer() external view returns (address) {\\n    return s_rebalancer;\\n  }\\n\\n  /// @notice Returns the group of the given remote chain selector.\\n  /// @param remoteChainSelector The remote chain selector.\\n  /// @return The group of the given remote chain selector (0 = LOCK_AND_RELEASE, 1 = BURN_AND_MINT).\\n  function getGroup(\\n    uint64 remoteChainSelector\\n  ) external view returns (Group) {\\n    return s_groups[remoteChainSelector];\\n  }\\n\\n  /// @notice Returns the external minter contract reference for a pool.\\n  /// @return The external minter contract instance.\\n  function getMinter() public view virtual returns (address) {\\n    return i_minter;\\n  }\\n\\n  // ================================================================\\n  // │                      Chain Management                        │\\n  // ================================================================\\n  /// @notice Updates the group of the given list of remote chain selectors. Can only be called by the owner.\\n  /// @param groupUpdates The list of remote chain selectors and their corresponding groups.\\n  function updateGroups(\\n    GroupUpdate[] calldata groupUpdates\\n  ) public virtual onlyOwner {\\n    for (uint256 i = 0; i \\u003c groupUpdates.length; ++i) {\\n      GroupUpdate calldata groupUpdate = groupUpdates[i];\\n      Group group = s_groups[groupUpdate.remoteChainSelector];\\n\\n      if (group == groupUpdate.group || !isSupportedChain(groupUpdate.remoteChainSelector)) {\\n        revert InvalidGroupUpdate(groupUpdate.remoteChainSelector, groupUpdate.group);\\n      }\\n\\n      s_groups[groupUpdate.remoteChainSelector] = groupUpdate.group;\\n\\n      // LIQUIDITY MIGRATION: Handle token backing changes when supply exists\\n      if (groupUpdate.remoteChainSupply \\u003e 0) {\\n        if (groupUpdate.group == Group.LOCK_AND_RELEASE) {\\n          // SWITCHING TO LOCK_AND_RELEASE: Mint backing tokens to this pool\\n          //\\n          // Migration Logic: If the remote chain has X tokens in circulation and is\\n          // switching to LOCK_AND_RELEASE, this pool must mint X tokens to itself\\n          // to provide the backing liquidity.\\n          //\\n          // CRITICAL: remoteChainSupply must include ALL tokens that need backing:\\n          // Tokens held by users on the remote chain\\n          // In-flight messages (tokens being transferred but not yet delivered)\\n          // The migration process should: 1) Pause bridge, 2) Resolve in-flight messages,\\n          // 3) Use totalSupply() which now includes all resolved transfers\\n          IExternalMinter(getMinter()).mint(address(this), groupUpdate.remoteChainSupply);\\n        } else {\\n          // SWITCHING TO BURN_AND_MINT: Burn backing tokens from this pool\\n          //\\n          // Migration Logic: If the remote chain is switching FROM LOCK_AND_RELEASE\\n          // TO BURN_AND_MINT, this pool no longer needs to hold backing tokens\\n          // for that chain's supply, so it burns them.\\n          //\\n          // CRITICAL: remoteChainSupply represents the total tokens this pool was backing,\\n          // which should equal the remote chain's total supply (including any resolved\\n          // in-flight messages that were delivered before the migration).\\n          getToken().safeApprove(address(getMinter()), groupUpdate.remoteChainSupply);\\n          IExternalMinter(getMinter()).burn(groupUpdate.remoteChainSupply);\\n        }\\n        emit LiquidityMigrated(groupUpdate.remoteChainSelector, groupUpdate.group, groupUpdate.remoteChainSupply);\\n      }\\n      emit GroupUpdated(groupUpdate.remoteChainSelector, groupUpdate.group);\\n    }\\n  }\\n\\n  // ================================================================\\n  // │                    Liquidity Management                      │\\n  // ================================================================\\n  /// @notice Checks if the caller is the rebalancer.\\n  function _validateRebalancer() internal view {\\n    if (s_rebalancer != msg.sender) revert Unauthorized(msg.sender);\\n  }\\n\\n  /// @notice Adds liquidity to the LOCK_AND_RELEASE group.\\n  /// @param amount The amount of tokens to add to the pool.\\n  function provideLiquidity(\\n    uint256 amount\\n  ) external {\\n    if (amount == 0) revert LiquidityAmountCannotBeZero();\\n    _validateRebalancer();\\n    IERC20(getToken()).safeTransferFrom(msg.sender, address(this), amount);\\n    emit LiquidityAdded(msg.sender, amount);\\n  }\\n\\n  /// @notice Removes liquidity from the LOCK_AND_RELEASE group.\\n  /// @param amount The amount of tokens to remove from the pool.\\n  function withdrawLiquidity(\\n    uint256 amount\\n  ) external virtual {\\n    if (amount == 0) revert LiquidityAmountCannotBeZero();\\n    _validateRebalancer();\\n    IERC20(getToken()).safeTransfer(msg.sender, amount);\\n    emit LiquidityRemoved(msg.sender, amount);\\n  }\\n\\n  // ================================================================\\n  // │                     Token Management                         │\\n  // ================================================================\\n  /// @notice Burns or locks tokens in the pool depending on the group configuration.\\n  /// @param lockOrBurnIn The lock or burn input parameters.\\n  /// @return The lock or burn output parameters.\\n  function lockOrBurn(\\n    Pool.LockOrBurnInV1 calldata lockOrBurnIn\\n  ) public virtual override returns (Pool.LockOrBurnOutV1 memory) {\\n    _validateLockOrBurn(lockOrBurnIn);\\n    _lockOrBurn(s_groups[lockOrBurnIn.remoteChainSelector], lockOrBurnIn.amount);\\n    emit TokenPool.LockedOrBurned({\\n      remoteChainSelector: lockOrBurnIn.remoteChainSelector,\\n      token: address(getToken()),\\n      sender: msg.sender,\\n      amount: lockOrBurnIn.amount\\n    });\\n    return Pool.LockOrBurnOutV1({\\n      destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector),\\n      destPoolData: _encodeLocalDecimals()\\n    });\\n  }\\n\\n  /// @notice Mints or releases tokens from the pool to the recipient.\\n  /// @param releaseOrMintIn The release or mint input parameters.\\n  /// @return The release or mint output parameters.\\n  function releaseOrMint(\\n    Pool.ReleaseOrMintInV1 calldata releaseOrMintIn\\n  ) public virtual override returns (Pool.ReleaseOrMintOutV1 memory) {\\n    uint256 localAmount = _calculateLocalAmount(\\n      releaseOrMintIn.sourceDenominatedAmount, _parseRemoteDecimals(releaseOrMintIn.sourcePoolData)\\n    );\\n    _validateReleaseOrMint(releaseOrMintIn, localAmount);\\n    _releaseOrMint(s_groups[releaseOrMintIn.remoteChainSelector], releaseOrMintIn.receiver, localAmount);\\n    emit TokenPool.ReleasedOrMinted({\\n      remoteChainSelector: releaseOrMintIn.remoteChainSelector,\\n      token: address(getToken()),\\n      sender: msg.sender,\\n      recipient: releaseOrMintIn.receiver,\\n      amount: localAmount\\n    });\\n    return Pool.ReleaseOrMintOutV1({destinationAmount: localAmount});\\n  }\\n\\n  /// @notice Locks or burns the amount of ERC20 tokens depending on the group.\\n  /// @param group The group to use for the operation.\\n  /// @param amount The amount of tokens to lock or burn.\\n  function _lockOrBurn(Group group, uint256 amount) internal {\\n    if (group == Group.BURN_AND_MINT) {\\n      IERC20(getToken()).safeApprove(address(getMinter()), amount);\\n      IExternalMinter(getMinter()).burn(amount);\\n    }\\n  }\\n\\n  /// @notice Releases or mints the amount of ERC20 tokens depending on the group.\\n  /// @param group The group to use for the operation.\\n  /// @param receiver The address to receive the tokens.\\n  /// @param amount The amount of tokens to release or mint.\\n  function _releaseOrMint(Group group, address receiver, uint256 amount) internal {\\n    if (group == Group.LOCK_AND_RELEASE) {\\n      IERC20(getToken()).safeTransfer(receiver, amount);\\n    } else {\\n      IExternalMinter(getMinter()).mint(receiver, amount);\\n    }\\n  }\\n\\n  // ================================================================\\n  // │                    Rebalancer Management                     │\\n  // ================================================================\\n  /// @notice Sets the rebalancer address.\\n  /// @dev Address(0) can be used to disable the rebalancer.\\n  /// @param rebalancer The address of the rebalancer.\\n  function setRebalancer(\\n    address rebalancer\\n  ) external onlyOwner {\\n    address oldRebalancer = s_rebalancer;\\n    s_rebalancer = rebalancer;\\n    emit RebalancerSet(oldRebalancer, rebalancer);\\n  }\\n\\n  /// @notice Validate that the token matches the one from the external minter.\\n  /// @param token The token to validate\\n  function _validateTokenFromExternalMinter(\\n    IERC20 token\\n  ) internal view virtual {\\n    IERC20 minterToken = IERC20(IExternalMinter(getMinter()).getToken());\\n    if (token != minterToken) {\\n      revert TokenMismatch(token, minterToken);\\n    }\\n  }\\n}\\n\"},\"contracts/stablecoin-governor/HybridWithExternalMinterFastTransferTokenPool.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.24;\\n\\nimport {HybridTokenPoolAbstract} from \\\"./HybridTokenPoolAbstract.sol\\\";\\nimport {Pool} from \\\"@chainlink/contracts-ccip/contracts/libraries/Pool.sol\\\";\\nimport {FastTransferTokenPoolAbstract} from\\n  \\\"@chainlink/contracts-ccip/contracts/pools/FastTransferTokenPoolAbstract.sol\\\";\\nimport {TokenPool} from \\\"@chainlink/contracts-ccip/contracts/pools/TokenPool.sol\\\";\\n\\nimport {IERC20} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol\\\";\\nimport {SafeERC20} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title HybridWithExternalMinterFastTransferTokenPool\\n/// @notice Hybrid Token Pool with Fast Transfer support for tokens owned by an ExternalMinter contract.\\n/// @dev Combines hybrid lock/release and burn/mint functionality with fast transfer capabilities.\\ncontract HybridWithExternalMinterFastTransferTokenPool is FastTransferTokenPoolAbstract, HybridTokenPoolAbstract {\\n  using SafeERC20 for IERC20;\\n\\n  error InsufficientLiquidity(uint256 available, uint256 required);\\n  error InsufficientLiquidityForGroupUpdate(\\n    uint256 balanceBeforeMigration, uint256 balanceAfterMigration, uint256 accumulatedPoolFees\\n  );\\n\\n  /// @dev Tracks the total accumulated fees in the pool, represented in token units.\\n  uint256 internal s_accumulatedPoolFees;\\n\\n  /// @notice Constructor for the hybrid pool with fast transfer support.\\n  /// @param minter The address of the minter contract.\\n  /// @param localTokenDecimals The decimals of the local token.\\n  /// @param allowlist The allowlist of addresses.\\n  /// @param rmnProxy The RMN proxy address.\\n  /// @param router The address of the CCIP router.\\n  constructor(\\n    address minter,\\n    IERC20 token,\\n    uint8 localTokenDecimals,\\n    address[] memory allowlist,\\n    address rmnProxy,\\n    address router\\n  ) FastTransferTokenPoolAbstract(token, localTokenDecimals, allowlist, rmnProxy, router) {\\n    i_minter = minter;\\n    // The token supplied to this constructor must match the token\\n    // returned by the minter, otherwise the deployment parameters are inconsistent.\\n    _validateTokenFromExternalMinter(token);\\n  }\\n\\n  /// @notice Returns the type and version of this contract.\\n  /// @return The type and version string.\\n  function typeAndVersion() public pure virtual returns (string memory) {\\n    return \\\"HybridWithExternalMinterFastTransferTokenPool 1.6.0\\\";\\n  }\\n\\n  /// @notice Signals which version of the pool interface is supported.\\n  function supportsInterface(\\n    bytes4 interfaceId\\n  ) public pure virtual override(TokenPool, FastTransferTokenPoolAbstract) returns (bool) {\\n    return FastTransferTokenPoolAbstract.supportsInterface(interfaceId);\\n  }\\n\\n  /// @notice Returns the router address.\\n  function getRouter() public view virtual override(TokenPool, FastTransferTokenPoolAbstract) returns (address) {\\n    return TokenPool.getRouter();\\n  }\\n\\n  /// @notice Returns the locked tokens in the pool.\\n  /// @return The amount of locked tokens in the pool.\\n  function getLockedTokens() external view override returns (uint256) {\\n    return getToken().balanceOf(address(this)) - getAccumulatedPoolFees();\\n  }\\n\\n  // ================================================================\\n  // │                      Group Management                        │\\n  // ================================================================\\n  /// @notice Updates remote chain groups while preserving accumulated pool fees.\\n  /// @dev Ensures fees are not lost. When switching from LOCK_AND_RELEASE to BURN_AND_MINT, burns the required tokens but retains at least the accumulated fees in the pool.\\n  /// @param groupUpdates Array of updates, each with a remote chain selector, the new group, and the supply amount to migrate.\\n  function updateGroups(\\n    GroupUpdate[] calldata groupUpdates\\n  ) public override {\\n    uint256 balanceBeforeMigration = getToken().balanceOf(address(this));\\n    super.updateGroups(groupUpdates);\\n    uint256 balanceAfterMigration = getToken().balanceOf(address(this));\\n    uint256 accumulatedFees = getAccumulatedPoolFees();\\n    if (balanceAfterMigration \\u003c accumulatedFees) {\\n      revert InsufficientLiquidityForGroupUpdate(balanceBeforeMigration, balanceAfterMigration, accumulatedFees);\\n    }\\n  }\\n\\n  // ================================================================\\n  // │                    Liquidity Management                      │\\n  // ================================================================\\n  /// @notice Removes liquidity from the LOCK_AND_RELEASE group.\\n  /// @dev Can only be called by the rebalancer. The pool must retain at least the accumulated pool fees amount.\\n  /// @param amount The amount of tokens to remove from the pool.\\n  function withdrawLiquidity(\\n    uint256 amount\\n  ) external override {\\n    if (amount == 0) revert LiquidityAmountCannotBeZero();\\n    _validateRebalancer();\\n    IERC20 token = getToken();\\n    uint256 currentBalance = token.balanceOf(address(this));\\n    uint256 accumulatedFees = s_accumulatedPoolFees;\\n    if (currentBalance \\u003c amount + accumulatedFees) {\\n      revert InsufficientLiquidity(currentBalance, amount + accumulatedFees);\\n    }\\n    token.safeTransfer(msg.sender, amount);\\n    emit LiquidityRemoved(msg.sender, amount);\\n  }\\n\\n  // ================================================================\\n  // │                      Fee Management                          │\\n  // ================================================================\\n  /// @notice Gets the accumulated pool fees.\\n  /// @return The accumulated pool fees in token units.\\n  function getAccumulatedPoolFees() public view override returns (uint256) {\\n    return s_accumulatedPoolFees;\\n  }\\n\\n  /// @notice Withdraws all accumulated pool fees to the specified recipient.\\n  /// @dev Transfers the accumulated fees and resets the internal counter.\\n  /// @param recipient The address to receive the withdrawn fees.\\n  function withdrawPoolFees(\\n    address recipient\\n  ) external override onlyOwner {\\n    uint256 amount = s_accumulatedPoolFees;\\n    if (amount \\u003e 0) {\\n      s_accumulatedPoolFees = 0;\\n      IERC20(getToken()).safeTransfer(recipient, amount);\\n      emit PoolFeeWithdrawn(recipient, amount);\\n    }\\n  }\\n\\n  // ================================================================\\n  // │                     Token Management                         │\\n  // ================================================================\\n  /// @notice Lock or burn tokens depending on group configuration.\\n  function lockOrBurn(\\n    Pool.LockOrBurnInV1 calldata lockOrBurnIn\\n  ) public virtual override(HybridTokenPoolAbstract, TokenPool) returns (Pool.LockOrBurnOutV1 memory) {\\n    return HybridTokenPoolAbstract.lockOrBurn(lockOrBurnIn);\\n  }\\n\\n  /// @notice Release or mint tokens depending on group configuration.\\n  function releaseOrMint(\\n    Pool.ReleaseOrMintInV1 calldata releaseOrMintIn\\n  ) public virtual override(HybridTokenPoolAbstract, TokenPool) returns (Pool.ReleaseOrMintOutV1 memory) {\\n    return HybridTokenPoolAbstract.releaseOrMint(releaseOrMintIn);\\n  }\\n\\n  // ================================================================\\n  // │                      Fast Transfer Hooks                     │\\n  // ================================================================\\n  /// @notice Handles the token transfer on fast fill request at source chain.\\n  /// @param destChainSelector The chain selector for the destination chain of fast transfer request.\\n  /// @param sender The sender address.\\n  /// @param amount The amount to transfer.\\n  function _handleFastTransferLockOrBurn(\\n    uint64 destChainSelector,\\n    address sender,\\n    uint256 amount\\n  ) internal virtual override {\\n    IERC20 token = getToken();\\n    token.safeTransferFrom(sender, address(this), amount);\\n    _lockOrBurn(s_groups[destChainSelector], amount);\\n  }\\n\\n  /// @notice Handles settlement when the request was not fast-filled.\\n  /// @param sourceChainSelector The chain selector for the source chain of fast transfer request.\\n  /// @param localSettlementAmount The amount to settle in local token.\\n  /// @param receiver The receiver address.\\n  function _handleSlowFill(\\n    bytes32,\\n    uint64 sourceChainSelector,\\n    uint256 localSettlementAmount,\\n    address receiver\\n  ) internal virtual override {\\n    _releaseOrMint(s_groups[sourceChainSelector], receiver, localSettlementAmount);\\n  }\\n\\n  /// @notice Handles reimbursement when the request was fast-filled.\\n  /// @param sourceChainSelector The chain selector for the source chain of fast transfer request.\\n  /// @param filler The filler address to reimburse.\\n  /// @param fillerReimbursementAmount The amount to reimburse (what they provided + their fee).\\n  /// @param poolReimbursementAmount The amount to reimburse to the pool (the pool fee).\\n  function _handleFastFillReimbursement(\\n    bytes32,\\n    uint64 sourceChainSelector,\\n    address filler,\\n    uint256 fillerReimbursementAmount,\\n    uint256 poolReimbursementAmount\\n  ) internal virtual override {\\n    _releaseOrMint(s_groups[sourceChainSelector], address(this), fillerReimbursementAmount + poolReimbursementAmount);\\n    s_accumulatedPoolFees += poolReimbursementAmount;\\n    if (fillerReimbursementAmount \\u003e 0) {\\n      IERC20(getToken()).safeTransfer(filler, fillerReimbursementAmount);\\n    }\\n  }\\n}\\n\"},\"contracts/stablecoin-governor/interfaces/IExternalMinter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IExternalMinter {\\n  function getToken() external view returns (address);\\n  function mint(address recipient, uint256 amount) external returns (bool);\\n  function burn(\\n    uint256 amount\\n  ) external returns (bool);\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/applications/CCIPReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {IAny2EVMMessageReceiver} from \\\"../interfaces/IAny2EVMMessageReceiver.sol\\\";\\n\\nimport {Client} from \\\"../libraries/Client.sol\\\";\\n\\nimport {IERC165} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\\\";\\n\\n/// @title CCIPReceiver - Base contract for CCIP applications that can receive messages.\\nabstract contract CCIPReceiver is IAny2EVMMessageReceiver, IERC165 {\\n  address internal immutable i_ccipRouter;\\n\\n  constructor(\\n    address router\\n  ) {\\n    if (router == address(0)) revert InvalidRouter(address(0));\\n    i_ccipRouter = router;\\n  }\\n\\n  /// @notice IERC165 supports an interfaceId.\\n  /// @param interfaceId The interfaceId to check.\\n  /// @return true if the interfaceId is supported.\\n  /// @dev Should indicate whether the contract implements IAny2EVMMessageReceiver.\\n  /// e.g. return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || interfaceId == type(IERC165).interfaceId\\n  /// This allows CCIP to check if ccipReceive is available before calling it.\\n  /// - If this returns false or reverts, only tokens are transferred to the receiver.\\n  /// - If this returns true, tokens are transferred and ccipReceive is called atomically.\\n  /// Additionally, if the receiver address does not have code associated with it at the time of\\n  /// execution (EXTCODESIZE returns 0), only tokens will be transferred.\\n  function supportsInterface(\\n    bytes4 interfaceId\\n  ) public pure virtual override returns (bool) {\\n    return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || interfaceId == type(IERC165).interfaceId;\\n  }\\n\\n  /// @inheritdoc IAny2EVMMessageReceiver\\n  function ccipReceive(\\n    Client.Any2EVMMessage calldata message\\n  ) external virtual override onlyRouter {\\n    _ccipReceive(message);\\n  }\\n\\n  /// @notice Override this function in your implementation.\\n  /// @param message Any2EVMMessage.\\n  function _ccipReceive(\\n    Client.Any2EVMMessage memory message\\n  ) internal virtual;\\n\\n  /// @notice Return the current router\\n  /// @return CCIP router address\\n  function getRouter() public view virtual returns (address) {\\n    return address(i_ccipRouter);\\n  }\\n\\n  error InvalidRouter(address router);\\n\\n  /// @dev only calls from the set router are accepted.\\n  modifier onlyRouter() {\\n    if (msg.sender != getRouter()) revert InvalidRouter(msg.sender);\\n    _;\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IAny2EVMMessageReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Client} from \\\"../libraries/Client.sol\\\";\\n\\n/// @notice Application contracts that intend to receive messages from  the router should implement this interface.\\ninterface IAny2EVMMessageReceiver {\\n  /// @notice Called by the Router to deliver a message. If this reverts, any token transfers also revert.\\n  /// The message will move to a FAILED state and become available for manual execution.\\n  /// @param message CCIP Message.\\n  /// @dev Note ensure you check the msg.sender is the OffRampRouter.\\n  function ccipReceive(\\n    Client.Any2EVMMessage calldata message\\n  ) external;\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IFastTransferPool.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.4;\\n\\n/// @title IFastTransferPool\\n/// @notice Interface for the CCIP Fast-Transfer Pool.\\ninterface IFastTransferPool {\\n  /// @notice Enum representing the state of a fill request.\\n  enum FillState {\\n    NOT_FILLED, // Request has not been filled yet.\\n    FILLED, // Request has been filled by a filler.\\n    SETTLED // Request has been settled via CCIP.\\n\\n  }\\n\\n  /// @notice Quote struct containing fee information.\\n  struct Quote {\\n    uint256 ccipSettlementFee; // Fee paid to for CCIP settlement in CCIP supported fee tokens.\\n    uint256 fastTransferFee; // Fee paid to the fast transfer filler in the same asset as requested.\\n  }\\n\\n  error AlreadyFilledOrSettled(bytes32 fillId);\\n  error AlreadySettled(bytes32 fillId);\\n\\n  /// @notice Emitted when a fast transfer is requested.\\n  event FastTransferRequested(\\n    uint64 indexed destinationChainSelector,\\n    bytes32 indexed fillId,\\n    bytes32 indexed settlementId,\\n    /// @param sourceAmountNetFee The amount being transferred, excluding the fast fill fee, expressed in source token\\n    /// decimals.\\n    uint256 sourceAmountNetFee,\\n    uint8 sourceDecimals,\\n    uint256 fillerFee,\\n    uint256 poolFee,\\n    /// @param destinationPool The destination chain pool where both the fill and settlement processes occur.\\n    /// @dev Fillers must invoke `fill` on the exact `destinationPool` address specified in the event tied to a fast transfer request.\\n    /// This ensures proper handling, as the active destination pool address can be updated in the token admin registry during token pool upgrades.\\n    /// In such cases, inflight messages are routed to the pool address specified in the event, where settlement takes place.\\n    /// To ensure accurate compensation during settlement, the fast fill must also occur at the pool address specified in the event.\\n    /// @notice Observability tools or indexing components should observe the `FastTransferFilled` and `FastTransferSettled` events from the `destinationPool`\\n    /// emitted in this event to monitor both fill and settlement actions for accurate status and metrics.\\n    bytes destinationPool,\\n    bytes receiver\\n  );\\n  /// @notice Emitted when a fast transfer is filled. This means the end user has received the tokens but the slow\\n  /// transfer is still in progress.\\n  event FastTransferFilled(\\n    bytes32 indexed fillId, bytes32 indexed settlementId, address indexed filler, uint256 destAmount, address receiver\\n  );\\n  /// @notice Emitted when a fast transfer is settled. This means the slow transfer has completed and the filler has\\n  /// received their fast transfer tokens and fee.\\n  event FastTransferSettled(\\n    bytes32 indexed fillId,\\n    bytes32 indexed settlementId,\\n    uint256 fillerReimbursementAmount,\\n    uint256 poolFeeAccumulated,\\n    FillState prevState\\n  );\\n\\n  /// @notice Emitted when pool fees are withdrawn.\\n  event PoolFeeWithdrawn(address indexed recipient, uint256 amount);\\n\\n  /// @notice Gets the CCIP send token fee and fast transfer fee for a given transfer.\\n  /// @param destinationChainSelector The destination chain selector.\\n  /// @param amount The amount to transfer.\\n  /// @param receiver The receiver address.\\n  /// @param settlementFeeToken The token used to pay the CCIP settlement fee.\\n  /// @param extraArgs Extra arguments for the transfer.\\n  /// @return Quote containing the CCIP fee and fast transfer fee.\\n  function getCcipSendTokenFee(\\n    uint64 destinationChainSelector,\\n    uint256 amount,\\n    bytes calldata receiver,\\n    address settlementFeeToken,\\n    bytes calldata extraArgs\\n  ) external view returns (Quote memory);\\n\\n  /// @notice Sends tokens via CCIP with optional fast transfer.\\n  /// @param destinationChainSelector The destination chain selector.\\n  /// @param amount The amount to transfer.\\n  /// @param maxFastTransferFee The maximum allowable fee deducted when computing\\n  /// the sourceAmountNetFee, expressed in lock/burn token units.\\n  /// @param receiver The receiver address.\\n  /// @param settlementFeeToken The token used to pay the settlement fee.\\n  /// @param extraArgs Extra arguments for the transfer.\\n  /// @return settlementId The fill request ID.\\n  function ccipSendToken(\\n    uint64 destinationChainSelector,\\n    uint256 amount,\\n    uint256 maxFastTransferFee,\\n    bytes calldata receiver,\\n    address settlementFeeToken,\\n    bytes calldata extraArgs\\n  ) external payable returns (bytes32 settlementId);\\n\\n  /// @notice Fast fills a transfer using liquidity provider funds.\\n  /// @param settlementId The settlement ID, which under normal circumstances is the same as the CCIP message ID.\\n  /// @param fillId The fill ID, computed from the fill request parameters.\\n  /// @param sourceChainSelector The source chain selector.\\n  /// @param sourceAmountNetFee The amount being filled, excluding the fast fill fee, expressed in source token decimals.\\n  /// @param sourceDecimals The decimals of the token on the source token.\\n  /// @param receiver The receiver on the destination chain. ABI encoded in the case of an EVM destination chain.\\n  function fastFill(\\n    bytes32 settlementId,\\n    bytes32 fillId,\\n    uint64 sourceChainSelector,\\n    uint256 sourceAmountNetFee,\\n    uint8 sourceDecimals,\\n    address receiver\\n  ) external;\\n\\n  /// @notice Helper function to generate fill ID from request parameters.\\n  /// @param settlementId The settlement ID, which under normal circumstances is the same as the CCIP message ID.\\n  /// @param sourceAmountNetFee The amount being filled, excluding the fast fill fee, expressed in source token decimals.\\n  /// @param sourceDecimals The decimals of the token on the source token.\\n  /// @param receiver The receiver on the destination chain. ABI encoded in the case of an EVM destination chain.\\n  /// @return fillId The computed fill ID.\\n  function computeFillId(\\n    bytes32 settlementId,\\n    uint256 sourceAmountNetFee,\\n    uint8 sourceDecimals,\\n    bytes memory receiver\\n  ) external pure returns (bytes32);\\n\\n  /// @notice Gets the accumulated pool fees that can be withdrawn.\\n  /// @return The amount of accumulated pool fees.\\n  function getAccumulatedPoolFees() external view returns (uint256);\\n\\n  /// @notice Withdraws all accumulated pool fees to the specified recipient.\\n  /// @param recipient The address to receive the withdrawn fees.\\n  function withdrawPoolFees(\\n    address recipient\\n  ) external;\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Pool} from \\\"../libraries/Pool.sol\\\";\\n\\nimport {IERC165} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\\\";\\n\\n/// @notice Shared public interface for multiple V1 pool types.\\n/// Each pool type handles a different child token model e.g. lock/unlock, mint/burn.\\ninterface IPoolV1 is IERC165 {\\n  /// @notice Lock tokens into the pool or burn the tokens.\\n  /// @param lockOrBurnIn Encoded data fields for the processing of tokens on the source chain.\\n  /// @return lockOrBurnOut Encoded data fields for the processing of tokens on the destination chain.\\n  function lockOrBurn(\\n    Pool.LockOrBurnInV1 calldata lockOrBurnIn\\n  ) external returns (Pool.LockOrBurnOutV1 memory lockOrBurnOut);\\n\\n  /// @notice Releases or mints tokens to the receiver address.\\n  /// @param releaseOrMintIn All data required to release or mint tokens.\\n  /// @return releaseOrMintOut The amount of tokens released or minted on the local chain, denominated\\n  /// in the local token's decimals.\\n  /// @dev The offRamp asserts that the balanceOf of the receiver has been incremented by exactly the number\\n  /// of tokens that is returned in ReleaseOrMintOutV1.destinationAmount. If the amounts do not match, the tx reverts.\\n  function releaseOrMint(\\n    Pool.ReleaseOrMintInV1 calldata releaseOrMintIn\\n  ) external returns (Pool.ReleaseOrMintOutV1 memory);\\n\\n  /// @notice Checks whether a remote chain is supported in the token pool.\\n  /// @param remoteChainSelector The selector of the remote chain.\\n  /// @return true if the given chain is a permissioned remote chain.\\n  function isSupportedChain(\\n    uint64 remoteChainSelector\\n  ) external view returns (bool);\\n\\n  /// @notice Returns if the token pool supports the given token.\\n  /// @param token The address of the token.\\n  /// @return true if the token is supported by the pool.\\n  function isSupportedToken(\\n    address token\\n  ) external view returns (bool);\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IRMN.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @notice This interface contains the only RMN-related functions that might be used on-chain by other CCIP contracts.\\ninterface IRMN {\\n  /// @notice A Merkle root tagged with the address of the commit store contract it is destined for.\\n  struct TaggedRoot {\\n    address commitStore;\\n    bytes32 root;\\n  }\\n\\n  /// @notice Callers MUST NOT cache the return value as a blessed tagged root could become unblessed.\\n  function isBlessed(\\n    TaggedRoot calldata taggedRoot\\n  ) external view returns (bool);\\n\\n  /// @notice Iff there is an active global or legacy curse, this function returns true.\\n  function isCursed() external view returns (bool);\\n\\n  /// @notice Iff there is an active global curse, or an active curse for `subject`, this function returns true.\\n  /// @param subject To check whether a particular chain is cursed, set to bytes16(uint128(chainSelector)).\\n  function isCursed(\\n    bytes16 subject\\n  ) external view returns (bool);\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IRouter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Client} from \\\"../libraries/Client.sol\\\";\\n\\ninterface IRouter {\\n  error OnlyOffRamp();\\n\\n  /// @notice Route the message to its intended receiver contract.\\n  /// @param message Client.Any2EVMMessage struct.\\n  /// @param gasForCallExactCheck of params for exec.\\n  /// @param gasLimit set of params for exec.\\n  /// @param receiver set of params for exec.\\n  /// @dev if the receiver is a contracts that signals support for CCIP execution through EIP-165.\\n  /// the contract is called. If not, only tokens are transferred.\\n  /// @return success A boolean value indicating whether the ccip message was received without errors.\\n  /// @return retBytes A bytes array containing return data form CCIP receiver.\\n  /// @return gasUsed the gas used by the external customer call. Does not include any overhead.\\n  function routeMessage(\\n    Client.Any2EVMMessage calldata message,\\n    uint16 gasForCallExactCheck,\\n    uint256 gasLimit,\\n    address receiver\\n  ) external returns (bool success, bytes memory retBytes, uint256 gasUsed);\\n\\n  /// @notice Returns the configured onRamp for a specific destination chain.\\n  /// @param destChainSelector The destination chain Id to get the onRamp for.\\n  /// @return onRampAddress The address of the onRamp.\\n  function getOnRamp(\\n    uint64 destChainSelector\\n  ) external view returns (address onRampAddress);\\n\\n  /// @notice Return true if the given offRamp is a configured offRamp for the given source chain.\\n  /// @param sourceChainSelector The source chain selector to check.\\n  /// @param offRamp The address of the offRamp to check.\\n  function isOffRamp(uint64 sourceChainSelector, address offRamp) external view returns (bool isOffRamp);\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/interfaces/IRouterClient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {Client} from \\\"../libraries/Client.sol\\\";\\n\\ninterface IRouterClient {\\n  error UnsupportedDestinationChain(uint64 destChainSelector);\\n  error InsufficientFeeTokenAmount();\\n  error InvalidMsgValue();\\n\\n  /// @notice Checks if the given chain ID is supported for sending/receiving.\\n  /// @param destChainSelector The chain to check.\\n  /// @return supported is true if it is supported, false if not.\\n  function isChainSupported(\\n    uint64 destChainSelector\\n  ) external view returns (bool supported);\\n\\n  /// @param destinationChainSelector The destination chainSelector.\\n  /// @param message The cross-chain CCIP message including data and/or tokens.\\n  /// @return fee returns execution fee for the message.\\n  /// delivery to destination chain, denominated in the feeToken specified in the message.\\n  /// @dev Reverts with appropriate reason upon invalid message.\\n  function getFee(\\n    uint64 destinationChainSelector,\\n    Client.EVM2AnyMessage memory message\\n  ) external view returns (uint256 fee);\\n\\n  /// @notice Request a message to be sent to the destination chain.\\n  /// @param destinationChainSelector The destination chain ID.\\n  /// @param message The cross-chain CCIP message including data and/or tokens.\\n  /// @return messageId The message ID.\\n  /// @dev Note if msg.value is larger than the required fee (from getFee) we accept.\\n  /// the overpayment with no refund.\\n  /// @dev Reverts with appropriate reason upon invalid message.\\n  function ccipSend(\\n    uint64 destinationChainSelector,\\n    Client.EVM2AnyMessage calldata message\\n  ) external payable returns (bytes32);\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/Client.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n// End consumer library.\\nlibrary Client {\\n  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.\\n  struct EVMTokenAmount {\\n    address token; // token address on the local chain.\\n    uint256 amount; // Amount of tokens.\\n  }\\n\\n  struct Any2EVMMessage {\\n    bytes32 messageId; // MessageId corresponding to ccipSend on source.\\n    uint64 sourceChainSelector; // Source chain selector.\\n    bytes sender; // abi.decode(sender) if coming from an EVM chain.\\n    bytes data; // payload sent in original message.\\n    EVMTokenAmount[] destTokenAmounts; // Tokens and their amounts in their destination chain representation.\\n  }\\n\\n  // If extraArgs is empty bytes, the default is 200k gas limit.\\n  struct EVM2AnyMessage {\\n    bytes receiver; // abi.encode(receiver address) for dest EVM chains.\\n    bytes data; // Data payload.\\n    EVMTokenAmount[] tokenAmounts; // Token transfers.\\n    address feeToken; // Address of feeToken. address(0) means you will send msg.value.\\n    bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV2).\\n  }\\n\\n  // Tag to indicate only a gas limit. Only usable for EVM as destination chain.\\n  bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9;\\n\\n  struct EVMExtraArgsV1 {\\n    uint256 gasLimit;\\n  }\\n\\n  function _argsToBytes(\\n    EVMExtraArgsV1 memory extraArgs\\n  ) internal pure returns (bytes memory bts) {\\n    return abi.encodeWithSelector(EVM_EXTRA_ARGS_V1_TAG, extraArgs);\\n  }\\n\\n  // Tag to indicate a gas limit (or dest chain equivalent processing units) and Out Of Order Execution. This tag is\\n  // available for multiple chain families. If there is no chain family specific tag, this is the default available\\n  // for a chain.\\n  // Note: not available for Solana VM based chains.\\n  bytes4 public constant GENERIC_EXTRA_ARGS_V2_TAG = 0x181dcf10;\\n\\n  /// @param gasLimit: gas limit for the callback on the destination chain.\\n  /// @param allowOutOfOrderExecution: if true, it indicates that the message can be executed in any order relative to\\n  /// other messages from the same sender. This value's default varies by chain. On some chains, a particular value is\\n  /// enforced, meaning if the expected value is not set, the message request will revert.\\n  /// @dev Fully compatible with the previously existing EVMExtraArgsV2.\\n  struct GenericExtraArgsV2 {\\n    uint256 gasLimit;\\n    bool allowOutOfOrderExecution;\\n  }\\n\\n  // Extra args tag for chains that use the Solana VM.\\n  bytes4 public constant SVM_EXTRA_ARGS_V1_TAG = 0x1f3b3aba;\\n\\n  struct SVMExtraArgsV1 {\\n    uint32 computeUnits;\\n    uint64 accountIsWritableBitmap;\\n    bool allowOutOfOrderExecution;\\n    bytes32 tokenReceiver;\\n    // Additional accounts needed for execution of CCIP receiver. Must be empty if message.receiver is zero.\\n    // Token transfer related accounts are specified in the token pool lookup table on SVM.\\n    bytes32[] accounts;\\n  }\\n\\n  /// @dev The maximum number of accounts that can be passed in SVMExtraArgs.\\n  uint256 public constant SVM_EXTRA_ARGS_MAX_ACCOUNTS = 64;\\n\\n  /// @dev The expected static payload size of a token transfer when Borsh encoded and submitted to SVM.\\n  /// TokenPool extra data and offchain data sizes are dynamic, and should be accounted for separately.\\n  uint256 public constant SVM_TOKEN_TRANSFER_DATA_OVERHEAD = (4 + 32) // source_pool\\n    + 32 // token_address\\n    + 4 // gas_amount\\n    + 4 // extra_data overhead\\n    + 32 // amount\\n    + 32 // size of the token lookup table account\\n    + 32 // token-related accounts in the lookup table, over-estimated to 32, typically between 11 - 13\\n    + 32 // token account belonging to the token receiver, e.g ATA, not included in the token lookup table\\n    + 32 // per-chain token pool config, not included in the token lookup table\\n    + 32 // per-chain token billing config, not always included in the token lookup table\\n    + 32; // OffRamp pool signer PDA, not included in the token lookup table\\n\\n  /// @dev Number of overhead accounts needed for message execution on SVM.\\n  /// @dev These are message.receiver, and the OffRamp Signer PDA specific to the receiver.\\n  uint256 public constant SVM_MESSAGING_ACCOUNTS_OVERHEAD = 2;\\n\\n  /// @dev The size of each SVM account address in bytes.\\n  uint256 public constant SVM_ACCOUNT_BYTE_SIZE = 32;\\n\\n  function _argsToBytes(\\n    GenericExtraArgsV2 memory extraArgs\\n  ) internal pure returns (bytes memory bts) {\\n    return abi.encodeWithSelector(GENERIC_EXTRA_ARGS_V2_TAG, extraArgs);\\n  }\\n\\n  function _svmArgsToBytes(\\n    SVMExtraArgsV1 memory extraArgs\\n  ) internal pure returns (bytes memory bts) {\\n    return abi.encodeWithSelector(SVM_EXTRA_ARGS_V1_TAG, extraArgs);\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/Internal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {MerkleMultiProof} from \\\"../libraries/MerkleMultiProof.sol\\\";\\n\\n/// @notice Library for CCIP internal definitions common to multiple contracts.\\n/// @dev The following is a non-exhaustive list of \\\"known issues\\\" for CCIP:\\n/// - We could implement yield claiming for Blast. This is not worth the custom code path on non-blast chains.\\n/// - uint32 is used for timestamps, which will overflow in 2106. This is not a concern for the current use case, as we\\n/// expect to have migrated to a new version by then.\\nlibrary Internal {\\n  error InvalidEVMAddress(bytes encodedAddress);\\n  error Invalid32ByteAddress(bytes encodedAddress);\\n  error InvalidTVMAddress(bytes encodedAddress);\\n\\n  /// @dev We limit return data to a selector plus 4 words. This is to avoid malicious contracts from returning\\n  /// large amounts of data and causing repeated out-of-gas scenarios.\\n  uint16 internal constant MAX_RET_BYTES = 4 + 4 * 32;\\n  /// @dev The expected number of bytes returned by the balanceOf function.\\n  uint256 internal constant MAX_BALANCE_OF_RET_BYTES = 32;\\n\\n  /// @dev The address used to send calls for gas estimation.\\n  /// You only need to use this address if the minimum gas limit specified by the user is not actually enough to execute the\\n  /// given message and you're attempting to estimate the actual necessary gas limit\\n  address public constant GAS_ESTIMATION_SENDER = address(0xC11C11C11C11C11C11C11C11C11C11C11C11C1);\\n\\n  /// @notice A collection of token price and gas price updates.\\n  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.\\n  struct PriceUpdates {\\n    TokenPriceUpdate[] tokenPriceUpdates;\\n    GasPriceUpdate[] gasPriceUpdates;\\n  }\\n\\n  /// @notice Token price in USD.\\n  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.\\n  struct TokenPriceUpdate {\\n    address sourceToken; // Source token.\\n    uint224 usdPerToken; // 1e18 USD per 1e18 of the smallest token denomination.\\n  }\\n\\n  /// @notice Gas price for a given chain in USD, its value may contain tightly packed fields.\\n  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.\\n  struct GasPriceUpdate {\\n    uint64 destChainSelector; // Destination chain selector.\\n    uint224 usdPerUnitGas; // 1e18 USD per smallest unit (e.g. wei) of destination chain gas.\\n  }\\n\\n  /// @notice A timestamped uint224 value that can contain several tightly packed fields.\\n  struct TimestampedPackedUint224 {\\n    uint224 value; // ────╮ Value in uint224, packed.\\n    uint32 timestamp; // ─╯ Timestamp of the most recent price update.\\n  }\\n\\n  /// @dev Gas price is stored in 112-bit unsigned int. uint224 can pack 2 prices.\\n  /// When packing L1 and L2 gas prices, L1 gas price is left-shifted to the higher-order bits.\\n  /// Using uint8 type, which cannot be higher than other bit shift operands, to avoid shift operand type warning.\\n  uint8 public constant GAS_PRICE_BITS = 112;\\n\\n  struct SourceTokenData {\\n    // The source pool address, abi encoded. This value is trusted as it was obtained through the onRamp. It can be\\n    // relied upon by the destination pool to validate the source pool.\\n    bytes sourcePoolAddress;\\n    // The address of the destination token, abi encoded in the case of EVM chains.\\n    // This value is UNTRUSTED as any pool owner can return whatever value they want.\\n    bytes destTokenAddress;\\n    // Optional pool data to be transferred to the destination chain. Be default this is capped at\\n    // CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes. If more data is required, the TokenTransferFeeConfig.destBytesOverhead\\n    // has to be set for the specific token.\\n    bytes extraData;\\n    uint32 destGasAmount; // The amount of gas available for the releaseOrMint and balanceOf calls on the offRamp\\n  }\\n\\n  /// @notice Report that is submitted by the execution DON at the execution phase, including chain selector data.\\n  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.\\n  struct ExecutionReport {\\n    uint64 sourceChainSelector; // Source chain selector for which the report is submitted.\\n    Any2EVMRampMessage[] messages;\\n    // Contains a bytes array for each message, each inner bytes array contains bytes per transferred token.\\n    bytes[][] offchainTokenData;\\n    bytes32[] proofs;\\n    uint256 proofFlagBits;\\n  }\\n\\n  /// @dev Any2EVMRampMessage struct has 10 fields, including 3 variable unnested arrays, sender, data and tokenAmounts.\\n  /// Each variable array takes 1 more slot to store its length.\\n  /// When abi encoded, excluding array contents, Any2EVMMessage takes up a fixed number of 13 slots, 32 bytes each.\\n  /// Assume 1 slot for sender\\n  /// For structs that contain arrays, 1 more slot is added to the front, reaching a total of 14.\\n  /// The fixed bytes does not cover struct data (this is represented by MESSAGE_FIXED_BYTES_PER_TOKEN)\\n  uint256 public constant MESSAGE_FIXED_BYTES = 32 * 15;\\n\\n  /// @dev Any2EVMTokensTransfer struct bytes length\\n  /// 0x20\\n  /// sourcePoolAddress_offset\\n  /// destTokenAddress\\n  /// destGasAmount\\n  /// extraData_offset\\n  /// amount\\n  /// sourcePoolAddress_length\\n  /// sourcePoolAddress_content // assume 1 slot\\n  /// extraData_length // contents billed separately\\n  uint256 public constant MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * (4 + (3 + 2));\\n\\n  bytes32 internal constant ANY_2_EVM_MESSAGE_HASH = keccak256(\\\"Any2EVMMessageHashV1\\\");\\n  bytes32 internal constant EVM_2_ANY_MESSAGE_HASH = keccak256(\\\"EVM2AnyMessageHashV1\\\");\\n\\n  /// @dev Used to hash messages for multi-lane family-agnostic OffRamps.\\n  /// OnRamp hash(EVM2AnyMessage) != Any2EVMRampMessage.messageId.\\n  /// OnRamp hash(EVM2AnyMessage) != OffRamp hash(Any2EVMRampMessage).\\n  /// @param original OffRamp message to hash.\\n  /// @param metadataHash Hash preimage to ensure global uniqueness.\\n  /// @return hashedMessage hashed message as a keccak256.\\n  function _hash(Any2EVMRampMessage memory original, bytes32 metadataHash) internal pure returns (bytes32) {\\n    // Fixed-size message fields are included in nested hash to reduce stack pressure.\\n    // This hashing scheme is also used by RMN. If changing it, please notify the RMN maintainers.\\n    return keccak256(\\n      abi.encode(\\n        MerkleMultiProof.LEAF_DOMAIN_SEPARATOR,\\n        metadataHash,\\n        keccak256(\\n          abi.encode(\\n            original.header.messageId,\\n            original.receiver,\\n            original.header.sequenceNumber,\\n            original.gasLimit,\\n            original.header.nonce\\n          )\\n        ),\\n        keccak256(original.sender),\\n        keccak256(original.data),\\n        keccak256(abi.encode(original.tokenAmounts))\\n      )\\n    );\\n  }\\n\\n  function _hash(EVM2AnyRampMessage memory original, bytes32 metadataHash) internal pure returns (bytes32) {\\n    // Fixed-size message fields are included in nested hash to reduce stack pressure.\\n    // This hashing scheme is also used by RMN. If changing it, please notify the RMN maintainers.\\n    return keccak256(\\n      abi.encode(\\n        MerkleMultiProof.LEAF_DOMAIN_SEPARATOR,\\n        metadataHash,\\n        keccak256(\\n          abi.encode(\\n            original.sender,\\n            original.header.sequenceNumber,\\n            original.header.nonce,\\n            original.feeToken,\\n            original.feeTokenAmount\\n          )\\n        ),\\n        keccak256(original.receiver),\\n        keccak256(original.data),\\n        keccak256(abi.encode(original.tokenAmounts)),\\n        keccak256(original.extraArgs)\\n      )\\n    );\\n  }\\n\\n  /// @dev We disallow the first 1024 addresses to avoid calling into a range known for hosting precompiles. Calling\\n  /// into precompiles probably won't cause any issues, but to be safe we can disallow this range. It is extremely\\n  /// unlikely that anyone would ever be able to generate an address in this range. There is no official range of\\n  /// precompiles, but EIP-7587 proposes to reserve the range 0x100 to 0x1ff. Our range is more conservative, even\\n  /// though it might not be exhaustive for all chains, which is OK. We also disallow the zero address, which is a\\n  /// common practice.\\n  uint256 public constant EVM_PRECOMPILE_SPACE = 1024;\\n\\n  // According to the Aptos docs, the first 0xa addresses are reserved for precompiles.\\n  // https://github.com/aptos-labs/aptos-core/blob/main/aptos-move/framework/aptos-framework/doc/account.md#function-create_framework_reserved_account-1\\n  uint256 public constant APTOS_PRECOMPILE_SPACE = 0x0b;\\n\\n  /// @notice This methods provides validation for parsing abi encoded addresses by ensuring the address is within the\\n  /// EVM address space. If it isn't it will revert with an InvalidEVMAddress error, which we can catch and handle\\n  /// more gracefully than a revert from abi.decode.\\n  function _validateEVMAddress(\\n    bytes memory encodedAddress\\n  ) internal pure {\\n    if (encodedAddress.length != 32) revert InvalidEVMAddress(encodedAddress);\\n    uint256 encodedAddressUint = abi.decode(encodedAddress, (uint256));\\n    if (encodedAddressUint \\u003e type(uint160).max || encodedAddressUint \\u003c EVM_PRECOMPILE_SPACE) {\\n      revert InvalidEVMAddress(encodedAddress);\\n    }\\n  }\\n\\n  /// @notice This methods provides validation for parsing abi encoded addresses by ensuring the address is within the\\n  /// bounds of [minValue, uint256.max]. If it isn't it will revert with an Invalid32ByteAddress error.\\n  function _validate32ByteAddress(bytes memory encodedAddress, uint256 minValue) internal pure {\\n    if (encodedAddress.length != 32) revert Invalid32ByteAddress(encodedAddress);\\n    if (minValue \\u003e 0) {\\n      if (abi.decode(encodedAddress, (uint256)) \\u003c minValue) {\\n        revert Invalid32ByteAddress(encodedAddress);\\n      }\\n    }\\n  }\\n\\n  /// @notice This methods provides validation for TON User-friendly addresses by ensuring the address is 36 bytes long.\\n  /// @dev The encodedAddress is expected to be the 36-byte raw representation:\\n  /// - 1 byte: flags (isBounceable, isTestnetOnly, etc.)\\n  /// - 1 byte: workchain_id (0x00 for BaseChain, 0xff for MasterChain)\\n  /// - 32 bytes: account_id\\n  /// - 2 bytes: CRC16 checksum(computationally heavy, validation omitted for simplicity)\\n  /// @param encodedAddress The 36-byte TON address.\\n  function _validateTVMAddress(\\n    bytes memory encodedAddress\\n  ) internal pure {\\n    if (encodedAddress.length != 36) revert InvalidTVMAddress(encodedAddress);\\n    bytes32 accountId;\\n    assembly {\\n      accountId := mload(add(encodedAddress, 0x22)) // 0x22 = 0x20 (data start) + 2 (offset for account_id)\\n    }\\n    if (accountId == bytes32(0)) revert InvalidTVMAddress(encodedAddress);\\n  }\\n\\n  /// @notice Enum listing the possible message execution states within the offRamp contract.\\n  /// UNTOUCHED never executed.\\n  /// IN_PROGRESS currently being executed, used a replay protection.\\n  /// SUCCESS successfully executed. End state.\\n  /// FAILURE unsuccessfully executed, manual execution is now enabled.\\n  /// @dev RMN depends on this enum, if changing, please notify the RMN maintainers.\\n  enum MessageExecutionState {\\n    UNTOUCHED,\\n    IN_PROGRESS,\\n    SUCCESS,\\n    FAILURE\\n  }\\n\\n  /// @notice CCIP OCR plugin type, used to separate execution \\u0026 commit transmissions and configs.\\n  enum OCRPluginType {\\n    Commit,\\n    Execution\\n  }\\n\\n  /// @notice Family-agnostic header for OnRamp \\u0026 OffRamp messages.\\n  /// The messageId is not expected to match hash(message), since it may originate from another ramp family.\\n  struct RampMessageHeader {\\n    bytes32 messageId; // Unique identifier for the message, generated with the source chain's encoding scheme (i.e. not necessarily abi.encoded).\\n    uint64 sourceChainSelector; // ─╮ the chain selector of the source chain, note: not chainId.\\n    uint64 destChainSelector; //    │ the chain selector of the destination chain, note: not chainId.\\n    uint64 sequenceNumber; //       │ sequence number, not unique across lanes.\\n    uint64 nonce; // ───────────────╯ nonce for this lane for this sender, not unique across senders/lanes.\\n  }\\n\\n  struct EVM2AnyTokenTransfer {\\n    // The source pool EVM address. This value is trusted as it was obtained through the onRamp. It can be relied\\n    // upon by the destination pool to validate the source pool.\\n    address sourcePoolAddress;\\n    // The EVM address of the destination token.\\n    // This value is UNTRUSTED as any pool owner can return whatever value they want.\\n    bytes destTokenAddress;\\n    // Optional pool data to be transferred to the destination chain. Be default this is capped at\\n    // CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes. If more data is required, the TokenTransferFeeConfig.destBytesOverhead\\n    // has to be set for the specific token.\\n    bytes extraData;\\n    uint256 amount; // Amount of tokens.\\n    // Destination chain data used to execute the token transfer on the destination chain. For an EVM destination, it\\n    // consists of the amount of gas available for the releaseOrMint and transfer calls made by the offRamp.\\n    bytes destExecData;\\n  }\\n\\n  struct Any2EVMTokenTransfer {\\n    // The source pool EVM address encoded to bytes. This value is trusted as it is obtained through the onRamp. It can\\n    // be relied upon by the destination pool to validate the source pool.\\n    bytes sourcePoolAddress;\\n    address destTokenAddress; // ─╮ Address of destination token\\n    uint32 destGasAmount; // ─────╯ The amount of gas available for the releaseOrMint and transfer calls on the offRamp.\\n    // Optional pool data to be transferred to the destination chain. Be default this is capped at\\n    // CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes. If more data is required, the TokenTransferFeeConfig.destBytesOverhead\\n    // has to be set for the specific token.\\n    bytes extraData;\\n    uint256 amount; // Amount of tokens.\\n  }\\n\\n  /// @notice Family-agnostic message routed to an OffRamp.\\n  /// Note: hash(Any2EVMRampMessage) != hash(EVM2AnyRampMessage), hash(Any2EVMRampMessage) != messageId due to encoding\\n  /// and parameter differences.\\n  struct Any2EVMRampMessage {\\n    RampMessageHeader header; // Message header.\\n    bytes sender; // sender address on the source chain.\\n    bytes data; // arbitrary data payload supplied by the message sender.\\n    address receiver; // receiver address on the destination chain.\\n    uint256 gasLimit; // user supplied maximum gas amount available for dest chain execution.\\n    Any2EVMTokenTransfer[] tokenAmounts; // array of tokens and amounts to transfer.\\n  }\\n\\n  /// @notice Family-agnostic message emitted from the OnRamp.\\n  /// Note: hash(Any2EVMRampMessage) != hash(EVM2AnyRampMessage) due to encoding \\u0026 parameter differences.\\n  /// messageId = hash(EVM2AnyRampMessage) using the source EVM chain's encoding format.\\n  struct EVM2AnyRampMessage {\\n    RampMessageHeader header; // Message header.\\n    address sender; // sender address on the source chain.\\n    bytes data; // arbitrary data payload supplied by the message sender.\\n    bytes receiver; // receiver address on the destination chain.\\n    bytes extraArgs; // destination-chain specific extra args, such as the gasLimit for EVM chains.\\n    address feeToken; // fee token.\\n    uint256 feeTokenAmount; // fee token amount.\\n    uint256 feeValueJuels; // fee amount in Juels.\\n    EVM2AnyTokenTransfer[] tokenAmounts; // array of tokens and amounts to transfer.\\n  }\\n\\n  // bytes4(keccak256(\\\"CCIP ChainFamilySelector EVM\\\"));\\n  bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c;\\n\\n  // bytes4(keccak256(\\\"CCIP ChainFamilySelector SVM\\\"));\\n  bytes4 public constant CHAIN_FAMILY_SELECTOR_SVM = 0x1e10bdc4;\\n\\n  // bytes4(keccak256(\\\"CCIP ChainFamilySelector APTOS\\\"));\\n  bytes4 public constant CHAIN_FAMILY_SELECTOR_APTOS = 0xac77ffec;\\n\\n  // bytes4(keccak256(\\\"CCIP ChainFamilySelector SUI\\\"));\\n  bytes4 public constant CHAIN_FAMILY_SELECTOR_SUI = 0xc4e05953;\\n\\n  // byte4(keccak256(\\\"CCIP ChainFamiliySelector TVM\\\"));\\n  bytes4 public constant CHAIN_FAMILY_SELECTOR_TVM = 0x647e2ba9;\\n\\n  /// @dev Holds a merkle root and interval for a source chain so that an array of these can be passed in the CommitReport.\\n  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.\\n  /// @dev inefficient struct packing intentionally chosen to maintain order of specificity. Not a storage struct so impact is minimal.\\n  // solhint-disable-next-line gas-struct-packing\\n  struct MerkleRoot {\\n    uint64 sourceChainSelector; // Remote source chain selector that the Merkle Root is scoped to\\n    bytes onRampAddress; //        Generic onRamp address, to support arbitrary sources; for EVM, use abi.encode\\n    uint64 minSeqNr; // ─────────╮ Minimum sequence number, inclusive\\n    uint64 maxSeqNr; // ─────────╯ Maximum sequence number, inclusive\\n    bytes32 merkleRoot; //         Merkle root covering the interval \\u0026 source chain messages\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/MerkleMultiProof.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.4;\\n\\nlibrary MerkleMultiProof {\\n  /// @notice Leaf domain separator, should be used as the first 32 bytes of a leaf's preimage.\\n  bytes32 internal constant LEAF_DOMAIN_SEPARATOR = 0x0000000000000000000000000000000000000000000000000000000000000000;\\n  /// @notice Internal domain separator, should be used as the first 32 bytes of an internal node's preimage.\\n  bytes32 internal constant INTERNAL_DOMAIN_SEPARATOR =\\n    0x0000000000000000000000000000000000000000000000000000000000000001;\\n\\n  uint256 internal constant MAX_NUM_HASHES = 256;\\n\\n  error InvalidProof();\\n  error LeavesCannotBeEmpty();\\n\\n  /// @notice Computes the root based on provided pre-hashed leaf nodes in leaves, internal nodes  in proofs, and using\\n  /// proofFlagBits' i-th bit to determine if an element of proofs or one of the previously computed leafs or internal\\n  /// nodes will be used for the i-th hash.\\n  /// @param leaves Should be pre-hashed and the first 32 bytes of a leaf's preimage should match LEAF_DOMAIN_SEPARATOR.\\n  /// @param proofs Hashes to be used instead of a leaf hash when the proofFlagBits indicates a proof should be used.\\n  /// @param proofFlagBits A single uint256 of which each bit indicates whether a leaf or a proof needs to be used in\\n  /// a hash operation.\\n  /// @dev the maximum number of hash operations it set to 256. Any input that would require more than 256 hashes to get\\n  /// to a root will revert.\\n  /// @dev For given input `leaves` = [a,b,c] `proofs` = [D] and `proofFlagBits` = 5\\n  ///     totalHashes = 3 + 1 - 1 = 3\\n  ///  ** round 1 **\\n  ///    proofFlagBits = (5 \\u003e\\u003e 0) \\u0026 1 = true\\n  ///    hashes[0] = hashPair(a, b)\\n  ///    (leafPos, hashPos, proofPos) = (2, 0, 0);\\n  ///\\n  ///  ** round 2 **\\n  ///    proofFlagBits = (5 \\u003e\\u003e 1) \\u0026 1 = false\\n  ///    hashes[1] = hashPair(D, c)\\n  ///    (leafPos, hashPos, proofPos) = (3, 0, 1);\\n  ///\\n  ///  ** round 3 **\\n  ///    proofFlagBits = (5 \\u003e\\u003e 2) \\u0026 1 = true\\n  ///    hashes[2] = hashPair(hashes[0], hashes[1])\\n  ///    (leafPos, hashPos, proofPos) = (3, 2, 1);\\n  ///\\n  ///    i = 3 and no longer \\u003c totalHashes. The algorithm is done\\n  ///    return hashes[totalHashes - 1] = hashes[2]; the last hash we computed.\\n  // We mark this function as internal to force it to be inlined in contracts that use it, but semantically it is public.\\n  function _merkleRoot(\\n    bytes32[] memory leaves,\\n    bytes32[] memory proofs,\\n    uint256 proofFlagBits\\n  ) internal pure returns (bytes32) {\\n    unchecked {\\n      uint256 leavesLen = leaves.length;\\n      uint256 proofsLen = proofs.length;\\n      if (leavesLen == 0) revert LeavesCannotBeEmpty();\\n      if (!(leavesLen \\u003c= MAX_NUM_HASHES + 1 \\u0026\\u0026 proofsLen \\u003c= MAX_NUM_HASHES + 1)) revert InvalidProof();\\n      uint256 totalHashes = leavesLen + proofsLen - 1;\\n      if (!(totalHashes \\u003c= MAX_NUM_HASHES)) revert InvalidProof();\\n      if (totalHashes == 0) {\\n        return leaves[0];\\n      }\\n      bytes32[] memory hashes = new bytes32[](totalHashes);\\n      (uint256 leafPos, uint256 hashPos, uint256 proofPos) = (0, 0, 0);\\n\\n      for (uint256 i = 0; i \\u003c totalHashes; ++i) {\\n        // Checks if the bit flag signals the use of a supplied proof or a leaf/previous hash.\\n        bytes32 a;\\n        if (proofFlagBits \\u0026 (1 \\u003c\\u003c i) == (1 \\u003c\\u003c i)) {\\n          // Use a leaf or a previously computed hash.\\n          if (leafPos \\u003c leavesLen) {\\n            a = leaves[leafPos++];\\n          } else {\\n            a = hashes[hashPos++];\\n          }\\n        } else {\\n          // Use a supplied proof.\\n          a = proofs[proofPos++];\\n        }\\n\\n        // The second part of the hashed pair is never a proof as hashing two proofs would result in a\\n        // hash that can already be computed offchain.\\n        bytes32 b;\\n        if (leafPos \\u003c leavesLen) {\\n          b = leaves[leafPos++];\\n        } else {\\n          b = hashes[hashPos++];\\n        }\\n\\n        if (!(hashPos \\u003c= i)) revert InvalidProof();\\n\\n        hashes[i] = _hashPair(a, b);\\n      }\\n      if (!(hashPos == totalHashes - 1 \\u0026\\u0026 leafPos == leavesLen \\u0026\\u0026 proofPos == proofsLen)) revert InvalidProof();\\n      // Return the last hash.\\n      return hashes[totalHashes - 1];\\n    }\\n  }\\n\\n  /// @notice Hashes two bytes32 objects in their given order, prepended by the INTERNAL_DOMAIN_SEPARATOR.\\n  function _hashInternalNode(bytes32 left, bytes32 right) private pure returns (bytes32 hash) {\\n    return keccak256(abi.encode(INTERNAL_DOMAIN_SEPARATOR, left, right));\\n  }\\n\\n  /// @notice Hashes two bytes32 objects. The order is taken into account, using the lower value first.\\n  function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n    return a \\u003c b ? _hashInternalNode(a, b) : _hashInternalNode(b, a);\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @notice This library contains various token pool functions to aid constructing the return data.\\nlibrary Pool {\\n  // The tag used to signal support for the pool v1 standard.\\n  // bytes4(keccak256(\\\"CCIP_POOL_V1\\\"))\\n  bytes4 public constant CCIP_POOL_V1 = 0xaff2afbf;\\n\\n  // The number of bytes in the return data for a pool v1 releaseOrMint call.\\n  // This should match the size of the ReleaseOrMintOutV1 struct.\\n  uint16 public constant CCIP_POOL_V1_RET_BYTES = 32;\\n\\n  // The default max number of bytes in the return data for a pool v1 lockOrBurn call.\\n  // This data can be used to send information to the destination chain token pool. Can be overwritten\\n  // in the TokenTransferFeeConfig.destBytesOverhead if more data is required.\\n  uint32 public constant CCIP_LOCK_OR_BURN_V1_RET_BYTES = 32;\\n\\n  struct LockOrBurnInV1 {\\n    bytes receiver; //  The recipient of the tokens on the destination chain, abi encoded.\\n    uint64 remoteChainSelector; // ─╮ The chain ID of the destination chain.\\n    address originalSender; // ─────╯ The original sender of the tx on the source chain.\\n    uint256 amount; //  The amount of tokens to lock or burn, denominated in the source token's decimals.\\n    address localToken; //  The address on this chain of the token to lock or burn.\\n  }\\n\\n  struct LockOrBurnOutV1 {\\n    // The address of the destination token, abi encoded in the case of EVM chains.\\n    // This value is UNTRUSTED as any pool owner can return whatever value they want.\\n    bytes destTokenAddress;\\n    // Optional pool data to be transferred to the destination chain. Be default this is capped at\\n    // CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes. If more data is required, the TokenTransferFeeConfig.destBytesOverhead\\n    // has to be set for the specific token.\\n    bytes destPoolData;\\n  }\\n\\n  struct ReleaseOrMintInV1 {\\n    bytes originalSender; //            The original sender of the tx on the source chain.\\n    uint64 remoteChainSelector; // ───╮ The chain ID of the source chain.\\n    address receiver; // ─────────────╯ The recipient of the tokens on the destination chain.\\n    uint256 sourceDenominatedAmount; // The amount of tokens to release or mint, denominated in the source token's decimals.\\n    address localToken; //              The address on this chain of the token to release or mint.\\n    /// @dev WARNING: sourcePoolAddress should be checked prior to any processing of funds. Make sure it matches the\\n    /// expected pool address for the given remoteChainSelector.\\n    bytes sourcePoolAddress; //         The address of the source pool, abi encoded in the case of EVM chains.\\n    bytes sourcePoolData; //            The data received from the source pool to process the release or mint.\\n    /// @dev WARNING: offchainTokenData is untrusted data.\\n    bytes offchainTokenData; //         The offchain data to process the release or mint.\\n  }\\n\\n  struct ReleaseOrMintOutV1 {\\n    // The number of tokens released or minted on the destination chain, denominated in the local token's decimals.\\n    // This value is expected to be equal to the ReleaseOrMintInV1.amount in the case where the source and destination\\n    // chain have the same number of decimals.\\n    uint256 destinationAmount;\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/libraries/RateLimiter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.4;\\n\\n/// @notice Implements Token Bucket rate limiting.\\n/// @dev uint128 is safe for rate limiter state.\\n/// - For USD value rate limiting, it can adequately store USD value in 18 decimals.\\n/// - For ERC20 token amount rate limiting, all tokens that will be listed will have at most a supply of uint128.max\\n/// tokens, and it will therefore not overflow the bucket. In exceptional scenarios where tokens consumed may be larger\\n/// than uint128, e.g. compromised issuer, an enabled RateLimiter will check and revert.\\nlibrary RateLimiter {\\n  error BucketOverfilled();\\n  error TokenMaxCapacityExceeded(uint256 capacity, uint256 requested, address tokenAddress);\\n  error TokenRateLimitReached(uint256 minWaitInSeconds, uint256 available, address tokenAddress);\\n  error InvalidRateLimitRate(Config rateLimiterConfig);\\n  error DisabledNonZeroRateLimit(Config config);\\n\\n  event ConfigChanged(Config config);\\n\\n  struct TokenBucket {\\n    uint128 tokens; // ────╮ Current number of tokens that are in the bucket.\\n    uint32 lastUpdated; // │ Timestamp in seconds of the last token refill, good for 100+ years.\\n    bool isEnabled; // ────╯ Indication whether the rate limiting is enabled or not.\\n    uint128 capacity; // ──╮ Maximum number of tokens that can be in the bucket.\\n    uint128 rate; // ──────╯ Number of tokens per second that the bucket is refilled.\\n  }\\n\\n  struct Config {\\n    bool isEnabled; // Indication whether the rate limiting should be enabled.\\n    uint128 capacity; // ──╮ Specifies the capacity of the rate limiter.\\n    uint128 rate; //  ─────╯ Specifies the rate of the rate limiter.\\n  }\\n\\n  /// @notice _consume removes the given tokens from the pool, lowering the rate tokens allowed to be\\n  /// consumed for subsequent calls.\\n  /// @param requestTokens The total tokens to be consumed from the bucket.\\n  /// @param tokenAddress The token to consume capacity for, use 0x0 to indicate aggregate value capacity.\\n  /// @dev Reverts when requestTokens exceeds bucket capacity or available tokens in the bucket.\\n  /// @dev emits removal of requestTokens if requestTokens is \\u003e 0.\\n  function _consume(TokenBucket storage s_bucket, uint256 requestTokens, address tokenAddress) internal {\\n    // If there is no value to remove or rate limiting is turned off, skip this step to reduce gas usage.\\n    if (!s_bucket.isEnabled || requestTokens == 0) {\\n      return;\\n    }\\n\\n    uint256 tokens = s_bucket.tokens;\\n    uint256 capacity = s_bucket.capacity;\\n    uint256 timeDiff = block.timestamp - s_bucket.lastUpdated;\\n\\n    if (timeDiff != 0) {\\n      if (tokens \\u003e capacity) revert BucketOverfilled();\\n\\n      // Refill tokens when arriving at a new block time.\\n      tokens = _calculateRefill(capacity, tokens, timeDiff, s_bucket.rate);\\n\\n      s_bucket.lastUpdated = uint32(block.timestamp);\\n    }\\n\\n    if (capacity \\u003c requestTokens) {\\n      revert TokenMaxCapacityExceeded(capacity, requestTokens, tokenAddress);\\n    }\\n    if (tokens \\u003c requestTokens) {\\n      uint256 rate = s_bucket.rate;\\n      // Wait required until the bucket is refilled enough to accept this value, round up to next higher second.\\n      // Consume is not guaranteed to succeed after wait time passes if there is competing traffic.\\n      // This acts as a lower bound of wait time.\\n      uint256 minWaitInSeconds = ((requestTokens - tokens) + (rate - 1)) / rate;\\n\\n      revert TokenRateLimitReached(minWaitInSeconds, tokens, tokenAddress);\\n    }\\n    tokens -= requestTokens;\\n\\n    // Downcast is safe here, as tokens is not larger than capacity.\\n    s_bucket.tokens = uint128(tokens);\\n  }\\n\\n  /// @notice Gets the token bucket with its values for the block it was requested at.\\n  /// @return The token bucket.\\n  function _currentTokenBucketState(\\n    TokenBucket memory bucket\\n  ) internal view returns (TokenBucket memory) {\\n    // We update the bucket to reflect the status at the exact time of the call. This means we might need to refill a\\n    // part of the bucket based on the time that has passed since the last update.\\n    bucket.tokens =\\n      uint128(_calculateRefill(bucket.capacity, bucket.tokens, block.timestamp - bucket.lastUpdated, bucket.rate));\\n    bucket.lastUpdated = uint32(block.timestamp);\\n    return bucket;\\n  }\\n\\n  /// @notice Sets the rate limited config.\\n  /// @param s_bucket The token bucket.\\n  /// @param config The new config.\\n  function _setTokenBucketConfig(TokenBucket storage s_bucket, Config memory config) internal {\\n    // First update the bucket to make sure the proper rate is used for all the time up until the config change.\\n    uint256 timeDiff = block.timestamp - s_bucket.lastUpdated;\\n    if (timeDiff != 0) {\\n      s_bucket.tokens = uint128(_calculateRefill(s_bucket.capacity, s_bucket.tokens, timeDiff, s_bucket.rate));\\n\\n      s_bucket.lastUpdated = uint32(block.timestamp);\\n    }\\n\\n    s_bucket.tokens = uint128(_min(config.capacity, s_bucket.tokens));\\n    s_bucket.isEnabled = config.isEnabled;\\n    s_bucket.capacity = config.capacity;\\n    s_bucket.rate = config.rate;\\n\\n    emit ConfigChanged(config);\\n  }\\n\\n  /// @notice Validates the token bucket config.\\n  function _validateTokenBucketConfig(\\n    Config memory config\\n  ) internal pure {\\n    if (config.isEnabled) {\\n      if (config.rate \\u003e config.capacity) {\\n        revert InvalidRateLimitRate(config);\\n      }\\n    } else {\\n      if (config.rate != 0 || config.capacity != 0) {\\n        revert DisabledNonZeroRateLimit(config);\\n      }\\n    }\\n  }\\n\\n  /// @notice Calculate refilled tokens.\\n  /// @param capacity bucket capacity.\\n  /// @param tokens current bucket tokens.\\n  /// @param timeDiff block time difference since last refill.\\n  /// @param rate bucket refill rate.\\n  /// @return the value of tokens after refill.\\n  function _calculateRefill(\\n    uint256 capacity,\\n    uint256 tokens,\\n    uint256 timeDiff,\\n    uint256 rate\\n  ) private pure returns (uint256) {\\n    return _min(capacity, tokens + timeDiff * rate);\\n  }\\n\\n  /// @notice Return the smallest of two integers.\\n  /// @param a first int.\\n  /// @param b second int.\\n  /// @return smallest.\\n  function _min(uint256 a, uint256 b) internal pure returns (uint256) {\\n    return a \\u003c b ? a : b;\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/pools/FastTransferTokenPoolAbstract.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.24;\\n\\nimport {IFastTransferPool} from \\\"../interfaces/IFastTransferPool.sol\\\";\\nimport {IRMN} from \\\"../interfaces/IRMN.sol\\\";\\nimport {IRouterClient} from \\\"../interfaces/IRouterClient.sol\\\";\\nimport {ITypeAndVersion} from \\\"@chainlink/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol\\\";\\n\\nimport {CCIPReceiver} from \\\"../applications/CCIPReceiver.sol\\\";\\nimport {Client} from \\\"../libraries/Client.sol\\\";\\nimport {Internal} from \\\"../libraries/Internal.sol\\\";\\nimport {TokenPool} from \\\"./TokenPool.sol\\\";\\n\\nimport {IERC20} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol\\\";\\nimport {SafeERC20} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {EnumerableSet} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\n/// @notice Base contract for fast-transfer pools that provides common functionality\\n/// for quoting, fill-tracking, and CCIP send helpers.\\n/// @dev To make this contract usable, it must be inherited by a concrete implementation that implements:\\n/// - `_lockOrBurn` - handles both the TokenPool lock/burn and the fast transfer lock/burn.\\n/// - `_releaseOrMint` - handles both the TokenPool release/mint and the fast transfer release/mint.\\n/// Additionally, there are some hooks that can optionally be overridden:\\n/// - `_handleFastTransferLockOrBurn`\\n/// - `_handleFastFill`\\n/// - `_handleSlowFill`\\n/// - `_handleFastFillReimbursement`\\n/// There are also validation functions that can optionally be overridden:\\n/// - `_validateSendRequest` - called before sending a fast transfer.\\n/// - `_validateSettlement` - called before settling.\\nabstract contract FastTransferTokenPoolAbstract is TokenPool, CCIPReceiver, ITypeAndVersion, IFastTransferPool {\\n  using EnumerableSet for EnumerableSet.AddressSet;\\n  using SafeERC20 for IERC20;\\n\\n  error InvalidDestChainConfig();\\n  error FillerNotAllowlisted(uint64 remoteChainSelector, address filler);\\n  error InvalidFillId(bytes32 fillId);\\n  error TransferAmountExceedsMaxFillAmount(uint64 remoteChainSelector, uint256 amount);\\n  error InsufficientPoolFees(uint256 requested, uint256 available);\\n  error QuoteFeeExceedsUserMaxLimit(uint256 quoteFee, uint256 maxFastTransferFee);\\n  error InvalidReceiver(bytes receiver);\\n\\n  event DestChainConfigUpdated(\\n    uint64 indexed destinationChainSelector,\\n    uint16 fastTransferFillerFeeBps,\\n    uint16 fastTransferPoolFeeBps,\\n    uint256 maxFillAmountPerRequest,\\n    bytes destinationPool,\\n    bytes4 chainFamilySelector,\\n    uint256 settlementOverheadGas,\\n    bool fillerAllowlistEnabled\\n  );\\n  event FillerAllowListUpdated(address[] addFillers, address[] removeFillers);\\n  event DestinationPoolUpdated(uint64 indexed destChainSelector, address destinationPool);\\n\\n  struct DestChainConfig {\\n    uint256 maxFillAmountPerRequest; // Maximum amount that can be filled per request.\\n    bool fillerAllowlistEnabled; // ────╮ Allowlist for fillers.\\n    uint16 fastTransferFillerFeeBps; // │ Basis points fee going to filler [0-10_000].\\n    uint16 fastTransferPoolFeeBps; //   │ Basis points fee going to pool [0-10_000].\\n    //                                  │ Settlement overhead gas for the destination chain. Used as a toggle for\\n    uint32 settlementOverheadGas; // ───╯ either custom ExtraArgs or GenericExtraArgsV2.\\n    bytes destinationPool; // Address of the destination pool.\\n    bytes customExtraArgs; // Pre-encoded extra args for EVM to Any message. Only used if settlementOverheadGas is 0.\\n  }\\n\\n  struct DestChainConfigUpdateArgs {\\n    bool fillerAllowlistEnabled; // ────╮ Allowlist for fillers.\\n    uint16 fastTransferFillerFeeBps; // │ Basis points fee going to filler [0-10_000].\\n    uint16 fastTransferPoolFeeBps; //   │ Basis points fee going to pool [0-10_000].\\n    uint32 settlementOverheadGas; //    │ Settlement overhead gas for the destination chain.\\n    uint64 remoteChainSelector; //      │ Remote chain selector. ABI encoded in the case of an EVM pool.\\n    bytes4 chainFamilySelector; // ─────╯ Selector that identifies the destination chain's family.\\n    uint256 maxFillAmountPerRequest; // Maximum amount that can be filled per request.\\n    bytes destinationPool; // Address of the destination pool.\\n    bytes customExtraArgs; // Pre-encoded extra args for EVM to Any message. Only used if settlementOverheadGas is 0.\\n  }\\n\\n  struct MintMessage {\\n    uint256 sourceAmount; // Amount to fill in the source token denomination.\\n    uint16 fastTransferFillerFeeBps; // ─╮ Basis points fee going to filler.\\n    uint16 fastTransferPoolFeeBps; //    │ Basis points fee going to pool.\\n    uint8 sourceDecimals; // ────────────╯ Decimals of the source token.\\n    bytes receiver; // Receiver address on the destination chain. ABI encoded in the case of an EVM address.\\n  }\\n\\n  /// @notice Struct to track fill request information.\\n  struct FillInfo {\\n    IFastTransferPool.FillState state; // Current state of the fill request.\\n    // Address of the filler, 0x0 until filled. If 0x0 after filled, it means the request was not fast-filled.\\n    address filler;\\n  }\\n\\n  /// @dev This struct helps avoid stack too deep errors by encapsulating fee components.\\n  struct InternalQuote {\\n    uint256 ccipSettlementFee; // Fee paid to for CCIP settlement in CCIP supported fee tokens.\\n    uint256 totalFastTransferFee; // Fee paid to the fast transfer filler in the same asset as requested.\\n    // The following two are the fee components that are used to calculate the total fast transfer fee.\\n    uint256 fillerFeeComponent; // Fee amount going to the filler.\\n    uint256 poolFeeComponent; // Fee amount going to the pool.\\n  }\\n\\n  /// @notice The division factor for basis points (BPS). This also represents the maximum BPS fee for fast transfer.\\n  uint256 internal constant BPS_DIVIDER = 10_000;\\n\\n  /// @dev Mapping of remote chain selector to destinationChain configuration.\\n  mapping(uint64 remoteChainSelector =\\u003e DestChainConfig destinationChainConfig) internal s_fastTransferDestChainConfig;\\n\\n  /// @dev Only addresses present in this list are able to fill.\\n  EnumerableSet.AddressSet internal s_fillerAllowLists;\\n\\n  /// @dev Mapping of fill request ID to fill information.\\n  /// This is used to track the state and filler of each fill request.\\n  mapping(bytes32 fillId =\\u003e FillInfo fillInfo) internal s_fills;\\n\\n  /// @param token The token this pool manages.\\n  /// @param localTokenDecimals The decimals of the local token.\\n  /// @param allowlist The allowlist of addresses.\\n  /// @param rmnProxy The RMN proxy address.\\n  /// @param router Address of the CCIP router.\\n  constructor(\\n    IERC20 token,\\n    uint8 localTokenDecimals,\\n    address[] memory allowlist,\\n    address rmnProxy,\\n    address router\\n  ) TokenPool(token, localTokenDecimals, allowlist, rmnProxy, router) CCIPReceiver(router) {}\\n\\n  /// @notice Gets the fill information for a given fill ID.\\n  /// @return fillInfo The fill information including state and filler address.\\n  function getFillInfo(\\n    bytes32 fillId\\n  ) external view returns (FillInfo memory) {\\n    return s_fills[fillId];\\n  }\\n\\n  /// @inheritdoc IFastTransferPool\\n  function ccipSendToken(\\n    uint64 destinationChainSelector,\\n    uint256 amount,\\n    uint256 maxFastTransferFee,\\n    bytes calldata receiver,\\n    address settlementFeeToken,\\n    bytes calldata extraArgs\\n  ) external payable virtual override returns (bytes32 settlementId) {\\n    (InternalQuote memory internalQuote, Client.EVM2AnyMessage memory message) =\\n      _getInternalQuoteAndCCIPMessage(destinationChainSelector, amount, receiver, settlementFeeToken, extraArgs);\\n\\n    _consumeOutboundRateLimit(destinationChainSelector, amount);\\n    if (internalQuote.totalFastTransferFee \\u003e maxFastTransferFee) {\\n      revert QuoteFeeExceedsUserMaxLimit(internalQuote.totalFastTransferFee, maxFastTransferFee);\\n    }\\n\\n    _handleFastTransferLockOrBurn(destinationChainSelector, msg.sender, amount);\\n\\n    // If the user is not paying in native, we need to transfer the fee token to the contract.\\n    if (settlementFeeToken != address(0)) {\\n      IERC20(settlementFeeToken).safeTransferFrom(msg.sender, address(this), internalQuote.ccipSettlementFee);\\n      IERC20(settlementFeeToken).safeApprove(i_ccipRouter, internalQuote.ccipSettlementFee);\\n    }\\n\\n    settlementId = IRouterClient(getRouter()).ccipSend{value: msg.value}(destinationChainSelector, message);\\n\\n    // Extracted FastTransferRequested into a helper to reduce the number of local variables in this function,\\n    // avoiding “stack too deep” compiler errors and keeping the main flow clear.\\n    _emitFastTransferRequested(\\n      destinationChainSelector,\\n      settlementId,\\n      amount - internalQuote.totalFastTransferFee,\\n      internalQuote.fillerFeeComponent,\\n      internalQuote.poolFeeComponent,\\n      message.receiver,\\n      receiver\\n    );\\n\\n    return settlementId;\\n  }\\n\\n  /// @inheritdoc IFastTransferPool\\n  function computeFillId(\\n    bytes32 settlementId,\\n    uint256 sourceAmountNetFee,\\n    uint8 sourceDecimals,\\n    bytes memory receiver\\n  ) public pure override returns (bytes32) {\\n    return keccak256(abi.encode(settlementId, sourceAmountNetFee, sourceDecimals, receiver));\\n  }\\n\\n  // ================================================================\\n  // │                      Fee calculation                         │\\n  // ================================================================\\n\\n  /// @notice Calculates the filler and pool fees for a fast transfer.\\n  /// @dev Common function to ensure consistent fee calculation.\\n  /// @param amount The transfer amount.\\n  /// @param fillerFeeBps Filler fee in basis points.\\n  /// @param poolFeeBps Pool fee in basis points.\\n  /// @return fillerFee The calculated filler fee.\\n  /// @return poolFee The calculated pool fee.\\n  function _calculateFastTransferFees(\\n    uint256 amount,\\n    uint16 fillerFeeBps,\\n    uint16 poolFeeBps\\n  ) internal pure returns (uint256 fillerFee, uint256 poolFee) {\\n    // Calculate individual fees using separate divisions to ensure consistency.\\n    fillerFee = (amount * fillerFeeBps) / BPS_DIVIDER;\\n    poolFee = (amount * poolFeeBps) / BPS_DIVIDER;\\n    return (fillerFee, poolFee);\\n  }\\n\\n  /// @inheritdoc IFastTransferPool\\n  function getCcipSendTokenFee(\\n    uint64 destinationChainSelector,\\n    uint256 amount,\\n    bytes calldata receiver,\\n    address settlementFeeToken,\\n    bytes calldata extraArgs\\n  ) public view virtual override returns (Quote memory quote) {\\n    (InternalQuote memory internalQuote,) =\\n      _getInternalQuoteAndCCIPMessage(destinationChainSelector, amount, receiver, settlementFeeToken, extraArgs);\\n    return\\n      Quote({ccipSettlementFee: internalQuote.ccipSettlementFee, fastTransferFee: internalQuote.totalFastTransferFee});\\n  }\\n\\n  function _getInternalQuoteAndCCIPMessage(\\n    uint64 destinationChainSelector,\\n    uint256 amount,\\n    bytes calldata receiver,\\n    address settlementFeeToken,\\n    bytes calldata\\n  ) internal view virtual returns (InternalQuote memory internalQuote, Client.EVM2AnyMessage memory message) {\\n    _validateSendRequest(destinationChainSelector, receiver);\\n\\n    // Using storage here appears to be cheaper.\\n    DestChainConfig storage destChainConfig = s_fastTransferDestChainConfig[destinationChainSelector];\\n    if (amount \\u003e destChainConfig.maxFillAmountPerRequest) {\\n      revert TransferAmountExceedsMaxFillAmount(destinationChainSelector, amount);\\n    }\\n\\n    (internalQuote.fillerFeeComponent, internalQuote.poolFeeComponent) = _calculateFastTransferFees(\\n      amount, destChainConfig.fastTransferFillerFeeBps, destChainConfig.fastTransferPoolFeeBps\\n    );\\n    internalQuote.totalFastTransferFee = internalQuote.fillerFeeComponent + internalQuote.poolFeeComponent;\\n\\n    bytes memory extraArgs;\\n\\n    // We use 0 as a toggle for whether the destination chain requires custom ExtraArgs. Zero would not be a sensible\\n    // value for settlementOverheadGas, so we can use it as a toggle.\\n    if (destChainConfig.settlementOverheadGas == 0) {\\n      extraArgs = destChainConfig.customExtraArgs;\\n    } else {\\n      // If the value is not zero, we encode it as GenericExtraArgsV2.\\n      extraArgs = Client._argsToBytes(\\n        Client.GenericExtraArgsV2({gasLimit: destChainConfig.settlementOverheadGas, allowOutOfOrderExecution: true})\\n      );\\n    }\\n\\n    message = Client.EVM2AnyMessage({\\n      receiver: destChainConfig.destinationPool,\\n      data: abi.encode(\\n        MintMessage({\\n          sourceAmount: amount,\\n          sourceDecimals: i_tokenDecimals,\\n          fastTransferFillerFeeBps: destChainConfig.fastTransferFillerFeeBps,\\n          fastTransferPoolFeeBps: destChainConfig.fastTransferPoolFeeBps,\\n          receiver: receiver\\n        })\\n      ),\\n      tokenAmounts: new Client.EVMTokenAmount[](0),\\n      feeToken: settlementFeeToken,\\n      extraArgs: extraArgs\\n    });\\n\\n    internalQuote.ccipSettlementFee = IRouterClient(getRouter()).getFee(destinationChainSelector, message);\\n    return (internalQuote, message);\\n  }\\n\\n  // ================================================================\\n  // │                           Filling                            │\\n  // ================================================================\\n\\n  /// @notice Fast fills a transfer using liquidity provider funds based on CCIP settlement.\\n  /// @param fillId The fill ID, computed from the fill request parameters.\\n  /// @param settlementId The settlement ID, which under normal circumstances is the same as the CCIP message ID.\\n  /// @param sourceAmountNetFee The amount to fill, calculated as the amount sent in `ccipSendToken` minus\\n  /// the fast fill fee, expressed in source token decimals.\\n  /// @param sourceDecimals The decimals of the source token.\\n  /// @param receiver The receiver address.\\n  function fastFill(\\n    bytes32 fillId,\\n    bytes32 settlementId,\\n    uint64 sourceChainSelector,\\n    uint256 sourceAmountNetFee,\\n    uint8 sourceDecimals,\\n    address receiver\\n  ) public virtual {\\n    if (s_fastTransferDestChainConfig[sourceChainSelector].fillerAllowlistEnabled) {\\n      if (!s_fillerAllowLists.contains(msg.sender)) {\\n        revert FillerNotAllowlisted(sourceChainSelector, msg.sender);\\n      }\\n    }\\n\\n    if (fillId != computeFillId(settlementId, sourceAmountNetFee, sourceDecimals, abi.encode(receiver))) {\\n      revert InvalidFillId(fillId);\\n    }\\n\\n    FillInfo memory fillInfo = s_fills[fillId];\\n    if (fillInfo.state != IFastTransferPool.FillState.NOT_FILLED) revert AlreadyFilledOrSettled(fillId);\\n\\n    // Calculate the local amount.\\n    uint256 localAmount = _calculateLocalAmount(sourceAmountNetFee, sourceDecimals);\\n\\n    s_fills[fillId] = FillInfo({state: IFastTransferPool.FillState.FILLED, filler: msg.sender});\\n\\n    emit FastTransferFilled(fillId, settlementId, msg.sender, localAmount, receiver);\\n\\n    _handleFastFill(fillId, msg.sender, receiver, localAmount);\\n  }\\n\\n  // @inheritdoc CCIPReceiver\\n  function _ccipReceive(\\n    Client.Any2EVMMessage memory message\\n  ) internal virtual override {\\n    _settle(message.sourceChainSelector, message.messageId, message.sender, abi.decode(message.data, (MintMessage)));\\n  }\\n\\n  function _settle(\\n    uint64 sourceChainSelector,\\n    bytes32 settlementId,\\n    bytes memory sourcePoolAddress,\\n    MintMessage memory mintMessage\\n  ) internal virtual {\\n    _validateSettlement(sourceChainSelector, sourcePoolAddress);\\n\\n    // Calculate the fast transfer inputs\\n    (uint256 sourceFillerFee, uint256 sourcePoolFee) = _calculateFastTransferFees(\\n      mintMessage.sourceAmount, mintMessage.fastTransferFillerFeeBps, mintMessage.fastTransferPoolFeeBps\\n    );\\n    // Inputs are in the source chain denomination, so we need to convert them to the local token denomination.\\n    uint256 localAmount = _calculateLocalAmount(mintMessage.sourceAmount, mintMessage.sourceDecimals);\\n    uint256 localPoolFee = _calculateLocalAmount(sourcePoolFee, mintMessage.sourceDecimals);\\n    bytes32 fillId = computeFillId(\\n      settlementId,\\n      // sourceAmountNetFee is the amount minus the fast fill fee, so we need to subtract both fees.\\n      mintMessage.sourceAmount - sourceFillerFee - sourcePoolFee,\\n      mintMessage.sourceDecimals,\\n      mintMessage.receiver\\n    );\\n\\n    // Cache current fill info to decide which hook to call.\\n    FillInfo memory fillInfo = s_fills[fillId];\\n    /// Mark the fill as SETTLED before any value transfers or external calls.\\n    /// This makes the new state visible immediately, preventing the same fill\\n    /// from being settled twice even if execution re-enters this contract.\\n    s_fills[fillId].state = IFastTransferPool.FillState.SETTLED;\\n    // Rate limiting should apply to the full sourceAmount regardless of whether the request was fast-filled or not.\\n    // This ensures that the rate limit controls the overall rate of release/mint operations.\\n    _consumeInboundRateLimit(sourceChainSelector, localAmount);\\n\\n    // The amount to reimburse to the filler in local denomination.\\n    uint256 fillerReimbursementAmount = 0;\\n    if (fillInfo.state == IFastTransferPool.FillState.NOT_FILLED) {\\n      // Set the local pool fee to zero, as fees are only applied for fast-fill operations.\\n      localPoolFee = 0;\\n      // When no filler is involved, we send the entire amount to the receiver.\\n      _handleSlowFill(fillId, sourceChainSelector, localAmount, abi.decode(mintMessage.receiver, (address)));\\n    } else if (fillInfo.state == IFastTransferPool.FillState.FILLED) {\\n      fillerReimbursementAmount = localAmount - localPoolFee;\\n      _handleFastFillReimbursement(\\n        fillId, sourceChainSelector, fillInfo.filler, fillerReimbursementAmount, localPoolFee\\n      );\\n    } else {\\n      // The catch all assertion for already settled fills ensures that any wrong value will revert.\\n      revert AlreadySettled(fillId);\\n    }\\n    emit FastTransferSettled(fillId, settlementId, fillerReimbursementAmount, localPoolFee, fillInfo.state);\\n  }\\n\\n  /// @notice Validates the send request parameters. Can be overridden by derived contracts to add additional checks.\\n  /// @param destinationChainSelector The destination chain selector.\\n  /// @dev Checks if the destination chain is allowed, if the sender is allowed, and if the RMN curse applies.\\n  function _validateSendRequest(uint64 destinationChainSelector, bytes calldata receiver) internal view virtual {\\n    _validateReceiver(receiver);\\n\\n    if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(destinationChainSelector)))) revert CursedByRMN();\\n    _checkAllowList(msg.sender);\\n    if (!isSupportedChain(destinationChainSelector)) revert ChainNotAllowed(destinationChainSelector);\\n  }\\n\\n  /// @notice Validates receiver address parameters.\\n  /// @dev Checks length bounds (0 \\u003c length ≤ 64) and ensures receiver is not all zeros.\\n  /// @param receiver The receiver address to validate.\\n  function _validateReceiver(\\n    bytes calldata receiver\\n  ) internal pure {\\n    uint256 receiverLength = receiver.length;\\n    if (receiverLength == 0 || receiverLength \\u003e 64) {\\n      revert InvalidReceiver(receiver);\\n    }\\n\\n    // Check if receiver is all zeros by scanning at most 2 32-byte words\\n    bool isNonZero = false;\\n    assembly {\\n      let dataPtr := receiver.offset\\n      // Load and check first 32 bytes\\n      if calldataload(dataPtr) { isNonZero := 1 }\\n\\n      if gt(receiverLength, 32) {\\n        // Load and check second 32 bytes only if receiver length \\u003e 32\\n        // Note: dataPtr + 32 may exceed the actual receiver data bounds (e.g., for 40-byte receiver,\\n        // this reads bytes [32, 64) where [40, 64) is out-of-bounds). However, this is safe because\\n        // calldata is ABI-encoded with zero-padding to 32-byte boundaries, so out-of-bounds bytes are zeros.\\n        if calldataload(add(dataPtr, 32)) { isNonZero := 1 }\\n      }\\n    }\\n\\n    if (!isNonZero) {\\n      revert InvalidReceiver(receiver);\\n    }\\n  }\\n\\n  /// @notice Validates settlement prerequisites. Can be overridden by derived contracts to add additional checks.\\n  /// @param sourceChainSelector The source chain selector.\\n  /// @param sourcePoolAddress The source pool address.\\n  function _validateSettlement(uint64 sourceChainSelector, bytes memory sourcePoolAddress) internal view virtual {\\n    if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(sourceChainSelector)))) revert CursedByRMN();\\n    //Validates that the source pool address is configured on this pool.\\n    if (!isRemotePool(sourceChainSelector, sourcePoolAddress)) {\\n      revert InvalidSourcePoolAddress(sourcePoolAddress);\\n    }\\n  }\\n\\n  // ================================================================\\n  // │                      Filling Hooks                           │\\n  // ================================================================\\n\\n  /// @notice Handles the token to transfer on fast fill request at source chain.\\n  /// @dev The first param is the chainSelector. It's unused in this implementation, but kept to allow overriding this\\n  /// function to handle the transfer in a different way.\\n  /// @param sender The sender address.\\n  /// @param amount The amount to transfer.\\n  function _handleFastTransferLockOrBurn(uint64, address sender, uint256 amount) internal virtual {\\n    // Since this is a fast transfer, the Router doesn't forward the tokens to the pool.\\n    getToken().safeTransferFrom(sender, address(this), amount);\\n    // Use the normal burn logic once the tokens are in the pool.\\n    _lockOrBurn(amount);\\n  }\\n\\n  /// @notice Transfers tokens from the filler to the receiver.\\n  /// @dev The first param is the fillId. It's unused in this implementation, but kept to allow overriding this function\\n  /// to handle the transfer in a different way.\\n  /// @param filler The address of the filler.\\n  /// @param receiver The address of the receiver.\\n  /// @param amount The amount to transfer in local denomination.\\n  function _handleFastFill(bytes32, address filler, address receiver, uint256 amount) internal virtual {\\n    getToken().safeTransferFrom(filler, receiver, amount);\\n  }\\n\\n  /// @notice Handles settlement when the request was not fast-filled\\n  /// @dev The first two parameters, `fillId` and `chainSelector`, are unused in this implementation.\\n  /// They are included to allow derived contracts to override this function and implement custom logic\\n  /// for handling slow fills.\\n  /// @param localSettlementAmount The amount to settle in local token.\\n  /// @param receiver The receiver address.\\n  function _handleSlowFill(bytes32, uint64, uint256 localSettlementAmount, address receiver) internal virtual {\\n    _releaseOrMint(receiver, localSettlementAmount);\\n  }\\n\\n  /// @notice Handles reimbursement when the request was fast-filled.\\n  /// @dev The first param is the fillId. It's unused in this implementation, but kept to allow overriding this function\\n  /// to handle the reimbursement in a different way.\\n  ///\\n  /// Burn/Mint token pools:\\n  /// This default implementation mints pool fee rewards directly to the pool itself (address(this)).\\n  /// The pool contract itself holds the reward tokens and they can be managed through standard token operations.\\n  ///\\n  /// Lock/Release pools:\\n  /// Lock/Release pools should override this function to implement accounting-based fee management since they\\n  /// cannot mint new tokens. They should keep track of accumulated pool fees in a storage variable (e.g., s_accumulatedPoolFees)\\n  /// @param filler The filler address to reimburse.\\n  /// @param fillerReimbursementAmount The amount to reimburse (what they provided + their fee).\\n  /// @param poolReimbursementAmount The amount to reimburse to the pool (the pool fee).\\n  function _handleFastFillReimbursement(\\n    bytes32,\\n    uint64,\\n    address filler,\\n    uint256 fillerReimbursementAmount,\\n    uint256 poolReimbursementAmount\\n  ) internal virtual {\\n    // Mint entire amount to pool first.\\n    _releaseOrMint(address(this), fillerReimbursementAmount + poolReimbursementAmount);\\n\\n    // Then transfer filler's share to them.\\n    if (fillerReimbursementAmount \\u003e 0) {\\n      getToken().safeTransfer(filler, fillerReimbursementAmount);\\n    }\\n  }\\n\\n  // ================================================================\\n  // │                          Config                              │\\n  // ================================================================\\n\\n  /// @notice Override getRouter to resolve both TokenPool and CCIPReceiver implementing getRouter().\\n  function getRouter() public view virtual override(TokenPool, CCIPReceiver) returns (address) {\\n    return TokenPool.getRouter();\\n  }\\n\\n  /// @notice Gets the destChain configuration for a given destination chain selector.\\n  /// @param remoteChainSelector The remote chain selector.\\n  /// @return destChainConfig The destChain configuration for the given destination chain selector.\\n  function getDestChainConfig(\\n    uint64 remoteChainSelector\\n  ) external view virtual returns (DestChainConfig memory, address[] memory) {\\n    return (s_fastTransferDestChainConfig[remoteChainSelector], s_fillerAllowLists.values());\\n  }\\n\\n  /// @notice Gets the accumulated pool fees that can be withdrawn.\\n  /// @dev This is an abstract function that must be implemented by derived contracts.\\n  /// Burn/Mint pools : Should return the contract's token balance since pool fees\\n  /// are minted directly to the pool contract (e.g., `return getToken().balanceOf(address(this))`).\\n  /// Lock/Release pools : Should implement their own accounting mechanism for pool fees\\n  /// by adding a storage variable (e.g., `s_accumulatedPoolFees`) since they cannot mint\\n  /// additional tokens for pool fee rewards.\\n  /// Note: Fee accounting can be obscured by sending tokens directly to the pool.\\n  /// This does not introduce security issues but will need to be handled operationally.\\n  /// @return The amount of accumulated pool fees available for withdrawal.\\n  function getAccumulatedPoolFees() public view virtual returns (uint256);\\n\\n  /// @notice Withdraws all accumulated pool fees to the specified recipient.\\n  /// @dev For BURN/MINT pools, this transfers the entire token balance of the pool contract.\\n  /// LOCK/RELEASE pools should override this function with their own accounting mechanism.\\n  /// @param recipient The address to receive the withdrawn fees.\\n  function withdrawPoolFees(\\n    address recipient\\n  ) external virtual onlyOwner {\\n    uint256 amount = getAccumulatedPoolFees();\\n    if (amount \\u003e 0) {\\n      getToken().safeTransfer(recipient, amount);\\n      emit PoolFeeWithdrawn(recipient, amount);\\n    }\\n  }\\n\\n  /// @notice Updates the destination chain configuration.\\n  /// @param destChainConfigArgs The destChain configuration arguments.\\n  function updateDestChainConfig(\\n    DestChainConfigUpdateArgs[] calldata destChainConfigArgs\\n  ) external virtual onlyOwner {\\n    for (uint256 i = 0; i \\u003c destChainConfigArgs.length; ++i) {\\n      _updateDestChainConfig(destChainConfigArgs[i]);\\n    }\\n  }\\n\\n  function _updateDestChainConfig(\\n    DestChainConfigUpdateArgs calldata destChainConfigArgs\\n  ) internal virtual {\\n    // We know Solana requires custom args, if they are not provided, we revert.\\n    if (destChainConfigArgs.chainFamilySelector == Internal.CHAIN_FAMILY_SELECTOR_SVM) {\\n      if (destChainConfigArgs.settlementOverheadGas != 0) {\\n        revert InvalidDestChainConfig();\\n      }\\n    }\\n\\n    // Ensure total fees is below 100%.\\n    if (destChainConfigArgs.fastTransferFillerFeeBps + destChainConfigArgs.fastTransferPoolFeeBps \\u003e= BPS_DIVIDER) {\\n      revert InvalidDestChainConfig();\\n    }\\n\\n    DestChainConfig storage destChainConfig = s_fastTransferDestChainConfig[destChainConfigArgs.remoteChainSelector];\\n    destChainConfig.destinationPool = destChainConfigArgs.destinationPool;\\n    destChainConfig.fastTransferFillerFeeBps = destChainConfigArgs.fastTransferFillerFeeBps;\\n    destChainConfig.fastTransferPoolFeeBps = destChainConfigArgs.fastTransferPoolFeeBps;\\n    destChainConfig.fillerAllowlistEnabled = destChainConfigArgs.fillerAllowlistEnabled;\\n    destChainConfig.maxFillAmountPerRequest = destChainConfigArgs.maxFillAmountPerRequest;\\n    destChainConfig.settlementOverheadGas = destChainConfigArgs.settlementOverheadGas;\\n    destChainConfig.customExtraArgs = destChainConfigArgs.customExtraArgs;\\n\\n    emit DestChainConfigUpdated(\\n      destChainConfigArgs.remoteChainSelector,\\n      destChainConfigArgs.fastTransferFillerFeeBps,\\n      destChainConfigArgs.fastTransferPoolFeeBps,\\n      destChainConfigArgs.maxFillAmountPerRequest,\\n      destChainConfigArgs.destinationPool,\\n      destChainConfigArgs.chainFamilySelector,\\n      destChainConfigArgs.settlementOverheadGas,\\n      destChainConfigArgs.fillerAllowlistEnabled\\n    );\\n  }\\n\\n  /// @notice Override supportsInterface to resolve the double inheritance.\\n  function supportsInterface(\\n    bytes4 interfaceId\\n  ) public pure virtual override(TokenPool, CCIPReceiver) returns (bool) {\\n    return interfaceId == type(IFastTransferPool).interfaceId || TokenPool.supportsInterface(interfaceId)\\n      || CCIPReceiver.supportsInterface(interfaceId);\\n  }\\n\\n  // ================================================================\\n  // │                      Filler allowlist                        │\\n  // ================================================================\\n\\n  /// @notice Gets all allowlisted fillers for a given destination chain.\\n  /// @return fillers Array of allowlisted filler addresses.\\n  function getAllowedFillers() external view virtual returns (address[] memory) {\\n    return s_fillerAllowLists.values();\\n  }\\n\\n  /// @notice Checks if a filler is allowlisted for a given destChain.\\n  /// @param filler The filler address to check.\\n  /// @return True if the filler is allowed, false otherwise.\\n  function isAllowedFiller(\\n    address filler\\n  ) external view virtual returns (bool) {\\n    return s_fillerAllowLists.contains(filler);\\n  }\\n\\n  /// @notice Updates the filler allowlist configuration for a given lane.\\n  /// @param fillersToAdd The addresses to add to the allowlist.\\n  /// @param fillersToRemove The addresses to remove from the allowlist.\\n  function updateFillerAllowList(\\n    address[] memory fillersToAdd,\\n    address[] memory fillersToRemove\\n  ) external virtual onlyOwner {\\n    for (uint256 i = 0; i \\u003c fillersToAdd.length; ++i) {\\n      s_fillerAllowLists.add(fillersToAdd[i]);\\n    }\\n    for (uint256 i = 0; i \\u003c fillersToRemove.length; ++i) {\\n      s_fillerAllowLists.remove(fillersToRemove[i]);\\n    }\\n\\n    emit FillerAllowListUpdated(fillersToAdd, fillersToRemove);\\n  }\\n\\n  /// @dev Pulled out event emission into its own function to handle stack too deep in ccipSendToken\\n  function _emitFastTransferRequested(\\n    uint64 destinationChainSelector,\\n    bytes32 settlementId,\\n    uint256 sourceAmountNetFee,\\n    uint256 fillerFee,\\n    uint256 poolFee,\\n    bytes memory destinationPool,\\n    bytes calldata receiver\\n  ) internal {\\n    bytes32 fillId = computeFillId(settlementId, sourceAmountNetFee, i_tokenDecimals, receiver);\\n\\n    emit FastTransferRequested({\\n      destinationChainSelector: destinationChainSelector,\\n      fillId: fillId,\\n      settlementId: settlementId,\\n      sourceAmountNetFee: sourceAmountNetFee,\\n      sourceDecimals: i_tokenDecimals,\\n      fillerFee: fillerFee,\\n      poolFee: poolFee,\\n      destinationPool: destinationPool,\\n      receiver: receiver\\n    });\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts-ccip/chains/evm/contracts/pools/TokenPool.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.24;\\n\\nimport {IPoolV1} from \\\"../interfaces/IPool.sol\\\";\\nimport {IRMN} from \\\"../interfaces/IRMN.sol\\\";\\nimport {IRouter} from \\\"../interfaces/IRouter.sol\\\";\\n\\nimport {Pool} from \\\"../libraries/Pool.sol\\\";\\nimport {RateLimiter} from \\\"../libraries/RateLimiter.sol\\\";\\nimport {Ownable2StepMsgSender} from \\\"@chainlink/contracts/src/v0.8/shared/access/Ownable2StepMsgSender.sol\\\";\\n\\nimport {IERC20} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC20Metadata} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport {IERC165} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\\\";\\nimport {EnumerableSet} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\n/// @notice Base abstract class with common functions for all token pools.\\n/// A token pool serves as isolated place for holding tokens and token specific logic\\n/// that may execute as tokens move across the bridge.\\n/// @dev This pool supports different decimals on different chains but using this feature could impact the total number\\n/// of tokens in circulation. Since all of the tokens are locked/burned on the source, and a rounded amount is\\n/// minted/released on the destination, the number of tokens minted/released could be less than the number of tokens\\n/// burned/locked. This is because the source chain does not know about the destination token decimals. This is not a\\n/// problem if the decimals are the same on both chains.\\n///\\n/// Example:\\n/// Assume there is a token with 6 decimals on chain A and 3 decimals on chain B.\\n/// - 1.234567 tokens are burned on chain A.\\n/// - 1.234    tokens are minted on chain B.\\n/// When sending the 1.234 tokens back to chain A, you will receive 1.234000 tokens on chain A, effectively losing\\n/// 0.000567 tokens.\\n/// In the case of a burnMint pool on chain A, these funds are burned in the pool on chain A.\\n/// In the case of a lockRelease pool on chain A, these funds accumulate in the pool on chain A.\\nabstract contract TokenPool is IPoolV1, Ownable2StepMsgSender {\\n  using EnumerableSet for EnumerableSet.Bytes32Set;\\n  using EnumerableSet for EnumerableSet.AddressSet;\\n  using EnumerableSet for EnumerableSet.UintSet;\\n  using RateLimiter for RateLimiter.TokenBucket;\\n\\n  error CallerIsNotARampOnRouter(address caller);\\n  error ZeroAddressNotAllowed();\\n  error SenderNotAllowed(address sender);\\n  error AllowListNotEnabled();\\n  error NonExistentChain(uint64 remoteChainSelector);\\n  error ChainNotAllowed(uint64 remoteChainSelector);\\n  error CursedByRMN();\\n  error ChainAlreadyExists(uint64 chainSelector);\\n  error InvalidSourcePoolAddress(bytes sourcePoolAddress);\\n  error InvalidToken(address token);\\n  error Unauthorized(address caller);\\n  error PoolAlreadyAdded(uint64 remoteChainSelector, bytes remotePoolAddress);\\n  error InvalidRemotePoolForChain(uint64 remoteChainSelector, bytes remotePoolAddress);\\n  error InvalidRemoteChainDecimals(bytes sourcePoolData);\\n  error MismatchedArrayLengths();\\n  error OverflowDetected(uint8 remoteDecimals, uint8 localDecimals, uint256 remoteAmount);\\n  error InvalidDecimalArgs(uint8 expected, uint8 actual);\\n\\n  event LockedOrBurned(uint64 indexed remoteChainSelector, address token, address sender, uint256 amount);\\n  event ReleasedOrMinted(\\n    uint64 indexed remoteChainSelector, address token, address sender, address recipient, uint256 amount\\n  );\\n  event ChainAdded(\\n    uint64 remoteChainSelector,\\n    bytes remoteToken,\\n    RateLimiter.Config outboundRateLimiterConfig,\\n    RateLimiter.Config inboundRateLimiterConfig\\n  );\\n  event ChainConfigured(\\n    uint64 remoteChainSelector,\\n    RateLimiter.Config outboundRateLimiterConfig,\\n    RateLimiter.Config inboundRateLimiterConfig\\n  );\\n  event ChainRemoved(uint64 remoteChainSelector);\\n  event RemotePoolAdded(uint64 indexed remoteChainSelector, bytes remotePoolAddress);\\n  event RemotePoolRemoved(uint64 indexed remoteChainSelector, bytes remotePoolAddress);\\n  event AllowListAdd(address sender);\\n  event AllowListRemove(address sender);\\n  event RouterUpdated(address oldRouter, address newRouter);\\n  event RateLimitAdminSet(address rateLimitAdmin);\\n  event OutboundRateLimitConsumed(uint64 indexed remoteChainSelector, address token, uint256 amount);\\n  event InboundRateLimitConsumed(uint64 indexed remoteChainSelector, address token, uint256 amount);\\n\\n  struct ChainUpdate {\\n    uint64 remoteChainSelector; // Remote chain selector\\n    bytes[] remotePoolAddresses; // Address of the remote pool, ABI encoded in the case of a remote EVM chain.\\n    bytes remoteTokenAddress; // Address of the remote token, ABI encoded in the case of a remote EVM chain.\\n    RateLimiter.Config outboundRateLimiterConfig; // Outbound rate limited config, meaning the rate limits for all of the onRamps for the given chain\\n    RateLimiter.Config inboundRateLimiterConfig; // Inbound rate limited config, meaning the rate limits for all of the offRamps for the given chain\\n  }\\n\\n  struct RemoteChainConfig {\\n    RateLimiter.TokenBucket outboundRateLimiterConfig; // Outbound rate limited config, meaning the rate limits for all of the onRamps for the given chain\\n    RateLimiter.TokenBucket inboundRateLimiterConfig; // Inbound rate limited config, meaning the rate limits for all of the offRamps for the given chain\\n    bytes remoteTokenAddress; // Address of the remote token, ABI encoded in the case of a remote EVM chain.\\n    EnumerableSet.Bytes32Set remotePools; // Set of remote pool hashes, ABI encoded in the case of a remote EVM chain.\\n  }\\n\\n  /// @dev The bridgeable token that is managed by this pool. Pools could support multiple tokens at the same time if\\n  /// required, but this implementation only supports one token.\\n  IERC20 internal immutable i_token;\\n  /// @dev The number of decimals of the token managed by this pool.\\n  uint8 internal immutable i_tokenDecimals;\\n  /// @dev The address of the RMN proxy\\n  address internal immutable i_rmnProxy;\\n  /// @dev The immutable flag that indicates if the pool is access-controlled.\\n  bool internal immutable i_allowlistEnabled;\\n  /// @dev A set of addresses allowed to trigger lockOrBurn as original senders.\\n  /// Only takes effect if i_allowlistEnabled is true.\\n  /// This can be used to ensure only token-issuer specified addresses can move tokens.\\n  EnumerableSet.AddressSet internal s_allowlist;\\n  /// @dev The address of the router\\n  IRouter internal s_router;\\n  /// @dev A set of allowed chain selectors. We want the allowlist to be enumerable to\\n  /// be able to quickly determine (without parsing logs) who can access the pool.\\n  /// @dev The chain selectors are in uint256 format because of the EnumerableSet implementation.\\n  EnumerableSet.UintSet internal s_remoteChainSelectors;\\n  mapping(uint64 remoteChainSelector =\\u003e RemoteChainConfig) internal s_remoteChainConfigs;\\n  /// @notice A mapping of hashed pool addresses to their unhashed form. This is used to be able to find the actually\\n  /// configured pools and not just their hashed versions.\\n  mapping(bytes32 poolAddressHash =\\u003e bytes poolAddress) internal s_remotePoolAddresses;\\n  /// @notice The address of the rate limiter admin.\\n  /// @dev Can be address(0) if none is configured.\\n  address internal s_rateLimitAdmin;\\n\\n  constructor(IERC20 token, uint8 localTokenDecimals, address[] memory allowlist, address rmnProxy, address router) {\\n    if (address(token) == address(0) || router == address(0) || rmnProxy == address(0)) revert ZeroAddressNotAllowed();\\n    i_token = token;\\n    i_rmnProxy = rmnProxy;\\n\\n    try IERC20Metadata(address(token)).decimals() returns (uint8 actualTokenDecimals) {\\n      if (localTokenDecimals != actualTokenDecimals) {\\n        revert InvalidDecimalArgs(localTokenDecimals, actualTokenDecimals);\\n      }\\n    } catch {\\n      // The decimals function doesn't exist, which is possible since it's optional in the ERC20 spec. We skip the check and\\n      // assume the supplied token decimals are correct.\\n    }\\n    i_tokenDecimals = localTokenDecimals;\\n\\n    s_router = IRouter(router);\\n\\n    // Pool can be set as permissioned or permissionless at deployment time only to save hot-path gas.\\n    i_allowlistEnabled = allowlist.length \\u003e 0;\\n    if (i_allowlistEnabled) {\\n      _applyAllowListUpdates(new address[](0), allowlist);\\n    }\\n  }\\n\\n  /// @inheritdoc IPoolV1\\n  function isSupportedToken(\\n    address token\\n  ) public view virtual returns (bool) {\\n    return token == address(i_token);\\n  }\\n\\n  /// @notice Gets the IERC20 token that this pool can lock or burn.\\n  /// @return token The IERC20 token representation.\\n  function getToken() public view returns (IERC20 token) {\\n    return i_token;\\n  }\\n\\n  /// @notice Get RMN proxy address\\n  /// @return rmnProxy Address of RMN proxy\\n  function getRmnProxy() public view returns (address rmnProxy) {\\n    return i_rmnProxy;\\n  }\\n\\n  /// @notice Gets the pool's Router\\n  /// @return router The pool's Router\\n  function getRouter() public view virtual returns (address router) {\\n    return address(s_router);\\n  }\\n\\n  /// @notice Sets the pool's Router\\n  /// @param newRouter The new Router\\n  function setRouter(\\n    address newRouter\\n  ) public onlyOwner {\\n    if (newRouter == address(0)) revert ZeroAddressNotAllowed();\\n    address oldRouter = address(s_router);\\n    s_router = IRouter(newRouter);\\n\\n    emit RouterUpdated(oldRouter, newRouter);\\n  }\\n\\n  /// @notice Signals which version of the pool interface is supported\\n  function supportsInterface(\\n    bytes4 interfaceId\\n  ) public pure virtual override returns (bool) {\\n    return interfaceId == Pool.CCIP_POOL_V1 || interfaceId == type(IPoolV1).interfaceId\\n      || interfaceId == type(IERC165).interfaceId;\\n  }\\n\\n  // ================================================================\\n  // │                        Lock or Burn                          │\\n  // ================================================================\\n\\n  /// @notice Burn the token in the pool\\n  /// @dev The _validateLockOrBurn check is an essential security check\\n  function lockOrBurn(\\n    Pool.LockOrBurnInV1 calldata lockOrBurnIn\\n  ) public virtual override returns (Pool.LockOrBurnOutV1 memory) {\\n    _validateLockOrBurn(lockOrBurnIn);\\n\\n    _lockOrBurn(lockOrBurnIn.amount);\\n\\n    emit LockedOrBurned({\\n      remoteChainSelector: lockOrBurnIn.remoteChainSelector,\\n      token: address(i_token),\\n      sender: msg.sender,\\n      amount: lockOrBurnIn.amount\\n    });\\n\\n    return Pool.LockOrBurnOutV1({\\n      destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector),\\n      destPoolData: _encodeLocalDecimals()\\n    });\\n  }\\n\\n  /// @notice Contains the specific lock or burn token logic for a pool.\\n  /// @dev overriding this method allows us to create pools with different lock/burn signatures\\n  /// without duplicating the underlying logic.\\n  function _lockOrBurn(\\n    uint256 amount\\n  ) internal virtual {}\\n\\n  // ================================================================\\n  // │                      Release or Mint                         │\\n  // ================================================================\\n\\n  /// @notice Mint tokens from the pool to the recipient\\n  /// @dev The _validateReleaseOrMint check is an essential security check\\n  function releaseOrMint(\\n    Pool.ReleaseOrMintInV1 calldata releaseOrMintIn\\n  ) public virtual override returns (Pool.ReleaseOrMintOutV1 memory) {\\n    // Calculate the local amount\\n    uint256 localAmount = _calculateLocalAmount(\\n      releaseOrMintIn.sourceDenominatedAmount, _parseRemoteDecimals(releaseOrMintIn.sourcePoolData)\\n    );\\n\\n    _validateReleaseOrMint(releaseOrMintIn, localAmount);\\n\\n    // Mint to the receiver\\n    _releaseOrMint(releaseOrMintIn.receiver, localAmount);\\n\\n    emit ReleasedOrMinted({\\n      remoteChainSelector: releaseOrMintIn.remoteChainSelector,\\n      token: address(i_token),\\n      sender: msg.sender,\\n      recipient: releaseOrMintIn.receiver,\\n      amount: localAmount\\n    });\\n\\n    return Pool.ReleaseOrMintOutV1({destinationAmount: localAmount});\\n  }\\n\\n  /// @notice Contains the specific release or mint token logic for a pool.\\n  /// @dev overriding this method allows us to create pools with different release/mint signatures\\n  /// without duplicating the underlying logic.\\n  function _releaseOrMint(address receiver, uint256 amount) internal virtual {}\\n\\n  // ================================================================\\n  // │                         Validation                           │\\n  // ================================================================\\n\\n  /// @notice Validates the lock or burn input for correctness on\\n  /// - token to be locked or burned\\n  /// - RMN curse status\\n  /// - allowlist status\\n  /// - if the sender is a valid onRamp\\n  /// - rate limit status\\n  /// @param lockOrBurnIn The input to validate.\\n  /// @dev This function should always be called before executing a lock or burn. Not doing so would allow\\n  /// for various exploits.\\n  function _validateLockOrBurn(\\n    Pool.LockOrBurnInV1 calldata lockOrBurnIn\\n  ) internal {\\n    if (!isSupportedToken(lockOrBurnIn.localToken)) revert InvalidToken(lockOrBurnIn.localToken);\\n    if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(lockOrBurnIn.remoteChainSelector)))) revert CursedByRMN();\\n    _checkAllowList(lockOrBurnIn.originalSender);\\n\\n    _onlyOnRamp(lockOrBurnIn.remoteChainSelector);\\n    _consumeOutboundRateLimit(lockOrBurnIn.remoteChainSelector, lockOrBurnIn.amount);\\n  }\\n\\n  /// @notice Validates the release or mint input for correctness on\\n  /// - token to be released or minted\\n  /// - RMN curse status\\n  /// - if the sender is a valid offRamp\\n  /// - if the source pool is valid\\n  /// - rate limit status\\n  /// @param releaseOrMintIn The input to validate.\\n  /// @param localAmount The local amount to be released or minted.\\n  /// @dev This function should always be called before executing a release or mint. Not doing so would allow\\n  /// for various exploits.\\n  function _validateReleaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn, uint256 localAmount) internal {\\n    if (!isSupportedToken(releaseOrMintIn.localToken)) revert InvalidToken(releaseOrMintIn.localToken);\\n    if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(releaseOrMintIn.remoteChainSelector)))) revert CursedByRMN();\\n    _onlyOffRamp(releaseOrMintIn.remoteChainSelector);\\n\\n    // Validates that the source pool address is configured on this pool.\\n    if (!isRemotePool(releaseOrMintIn.remoteChainSelector, releaseOrMintIn.sourcePoolAddress)) {\\n      revert InvalidSourcePoolAddress(releaseOrMintIn.sourcePoolAddress);\\n    }\\n\\n    _consumeInboundRateLimit(releaseOrMintIn.remoteChainSelector, localAmount);\\n  }\\n\\n  // ================================================================\\n  // │                      Token decimals                          │\\n  // ================================================================\\n\\n  /// @notice Gets the IERC20 token decimals on the local chain.\\n  function getTokenDecimals() public view virtual returns (uint8 decimals) {\\n    return i_tokenDecimals;\\n  }\\n\\n  function _encodeLocalDecimals() internal view virtual returns (bytes memory) {\\n    return abi.encode(i_tokenDecimals);\\n  }\\n\\n  function _parseRemoteDecimals(\\n    bytes memory sourcePoolData\\n  ) internal view virtual returns (uint8) {\\n    // Fallback to the local token decimals if the source pool data is empty. This allows for backwards compatibility.\\n    if (sourcePoolData.length == 0) {\\n      return i_tokenDecimals;\\n    }\\n    if (sourcePoolData.length != 32) {\\n      revert InvalidRemoteChainDecimals(sourcePoolData);\\n    }\\n    uint256 remoteDecimals = abi.decode(sourcePoolData, (uint256));\\n    if (remoteDecimals \\u003e type(uint8).max) {\\n      revert InvalidRemoteChainDecimals(sourcePoolData);\\n    }\\n    return uint8(remoteDecimals);\\n  }\\n\\n  /// @notice Calculates the local amount based on the remote amount and decimals.\\n  /// @param remoteAmount The amount on the remote chain.\\n  /// @param remoteDecimals The decimals of the token on the remote chain.\\n  /// @return The local amount.\\n  /// @dev This function protects against overflows. If there is a transaction that hits the overflow check, it is\\n  /// probably incorrect as that means the amount cannot be represented on this chain. If the local decimals have been\\n  /// wrongly configured, the token issuer could redeploy the pool with the correct decimals and manually re-execute the\\n  /// CCIP tx to fix the issue.\\n  function _calculateLocalAmount(uint256 remoteAmount, uint8 remoteDecimals) internal view virtual returns (uint256) {\\n    if (remoteDecimals == i_tokenDecimals) {\\n      return remoteAmount;\\n    }\\n    if (remoteDecimals \\u003e i_tokenDecimals) {\\n      uint8 decimalsDiff = remoteDecimals - i_tokenDecimals;\\n      if (decimalsDiff \\u003e 77) {\\n        // This is a safety check to prevent overflow in the next calculation.\\n        revert OverflowDetected(remoteDecimals, i_tokenDecimals, remoteAmount);\\n      }\\n      // Solidity rounds down so there is no risk of minting more tokens than the remote chain sent.\\n      return remoteAmount / (10 ** decimalsDiff);\\n    }\\n\\n    // This is a safety check to prevent overflow in the next calculation.\\n    // More than 77 would never fit in a uint256 and would cause an overflow. We also check if the resulting amount\\n    // would overflow.\\n    uint8 diffDecimals = i_tokenDecimals - remoteDecimals;\\n    if (diffDecimals \\u003e 77 || remoteAmount \\u003e type(uint256).max / (10 ** diffDecimals)) {\\n      revert OverflowDetected(remoteDecimals, i_tokenDecimals, remoteAmount);\\n    }\\n\\n    return remoteAmount * (10 ** diffDecimals);\\n  }\\n\\n  // ================================================================\\n  // │                     Chain permissions                        │\\n  // ================================================================\\n\\n  /// @notice Gets the pool address on the remote chain.\\n  /// @param remoteChainSelector Remote chain selector.\\n  /// @dev To support non-evm chains, this value is encoded into bytes\\n  function getRemotePools(\\n    uint64 remoteChainSelector\\n  ) public view returns (bytes[] memory) {\\n    bytes32[] memory remotePoolHashes = s_remoteChainConfigs[remoteChainSelector].remotePools.values();\\n\\n    bytes[] memory remotePools = new bytes[](remotePoolHashes.length);\\n    for (uint256 i = 0; i \\u003c remotePoolHashes.length; ++i) {\\n      remotePools[i] = s_remotePoolAddresses[remotePoolHashes[i]];\\n    }\\n\\n    return remotePools;\\n  }\\n\\n  /// @notice Checks if the pool address is configured on the remote chain.\\n  /// @param remoteChainSelector Remote chain selector.\\n  /// @param remotePoolAddress The address of the remote pool.\\n  function isRemotePool(uint64 remoteChainSelector, bytes memory remotePoolAddress) public view returns (bool) {\\n    return s_remoteChainConfigs[remoteChainSelector].remotePools.contains(keccak256(remotePoolAddress));\\n  }\\n\\n  /// @notice Gets the token address on the remote chain.\\n  /// @param remoteChainSelector Remote chain selector.\\n  /// @dev To support non-evm chains, this value is encoded into bytes\\n  function getRemoteToken(\\n    uint64 remoteChainSelector\\n  ) public view returns (bytes memory) {\\n    return s_remoteChainConfigs[remoteChainSelector].remoteTokenAddress;\\n  }\\n\\n  /// @notice Adds a remote pool for a given chain selector. This could be due to a pool being upgraded on the remote\\n  /// chain. We don't simply want to replace the old pool as there could still be valid inflight messages from the old\\n  /// pool. This function allows for multiple pools to be added for a single chain selector.\\n  /// @param remoteChainSelector The remote chain selector for which the remote pool address is being added.\\n  /// @param remotePoolAddress The address of the new remote pool.\\n  function addRemotePool(uint64 remoteChainSelector, bytes calldata remotePoolAddress) external onlyOwner {\\n    if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector);\\n\\n    _setRemotePool(remoteChainSelector, remotePoolAddress);\\n  }\\n\\n  /// @notice Removes the remote pool address for a given chain selector.\\n  /// @dev All inflight txs from the remote pool will be rejected after it is removed. To ensure no loss of funds, there\\n  /// should be no inflight txs from the given pool.\\n  function removeRemotePool(uint64 remoteChainSelector, bytes calldata remotePoolAddress) external onlyOwner {\\n    if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector);\\n\\n    if (!s_remoteChainConfigs[remoteChainSelector].remotePools.remove(keccak256(remotePoolAddress))) {\\n      revert InvalidRemotePoolForChain(remoteChainSelector, remotePoolAddress);\\n    }\\n\\n    emit RemotePoolRemoved(remoteChainSelector, remotePoolAddress);\\n  }\\n\\n  /// @inheritdoc IPoolV1\\n  function isSupportedChain(\\n    uint64 remoteChainSelector\\n  ) public view returns (bool) {\\n    return s_remoteChainSelectors.contains(remoteChainSelector);\\n  }\\n\\n  /// @notice Get list of allowed chains\\n  /// @return list of chains.\\n  function getSupportedChains() public view returns (uint64[] memory) {\\n    uint256[] memory uint256ChainSelectors = s_remoteChainSelectors.values();\\n    uint64[] memory chainSelectors = new uint64[](uint256ChainSelectors.length);\\n    for (uint256 i = 0; i \\u003c uint256ChainSelectors.length; ++i) {\\n      chainSelectors[i] = uint64(uint256ChainSelectors[i]);\\n    }\\n\\n    return chainSelectors;\\n  }\\n\\n  /// @notice Sets the permissions for a list of chains selectors. Actual senders for these chains\\n  /// need to be allowed on the Router to interact with this pool.\\n  /// @param remoteChainSelectorsToRemove A list of chain selectors to remove.\\n  /// @param chainsToAdd A list of chains and their new permission status \\u0026 rate limits. Rate limits\\n  /// are only used when the chain is being added through `allowed` being true.\\n  /// @dev Only callable by the owner\\n  function applyChainUpdates(\\n    uint64[] calldata remoteChainSelectorsToRemove,\\n    ChainUpdate[] calldata chainsToAdd\\n  ) external virtual onlyOwner {\\n    for (uint256 i = 0; i \\u003c remoteChainSelectorsToRemove.length; ++i) {\\n      uint64 remoteChainSelectorToRemove = remoteChainSelectorsToRemove[i];\\n      // If the chain doesn't exist, revert\\n      if (!s_remoteChainSelectors.remove(remoteChainSelectorToRemove)) {\\n        revert NonExistentChain(remoteChainSelectorToRemove);\\n      }\\n\\n      // Remove all remote pool hashes for the chain\\n      bytes32[] memory remotePools = s_remoteChainConfigs[remoteChainSelectorToRemove].remotePools.values();\\n      for (uint256 j = 0; j \\u003c remotePools.length; ++j) {\\n        s_remoteChainConfigs[remoteChainSelectorToRemove].remotePools.remove(remotePools[j]);\\n      }\\n\\n      delete s_remoteChainConfigs[remoteChainSelectorToRemove];\\n\\n      emit ChainRemoved(remoteChainSelectorToRemove);\\n    }\\n\\n    for (uint256 i = 0; i \\u003c chainsToAdd.length; ++i) {\\n      ChainUpdate memory newChain = chainsToAdd[i];\\n      RateLimiter._validateTokenBucketConfig(newChain.outboundRateLimiterConfig);\\n      RateLimiter._validateTokenBucketConfig(newChain.inboundRateLimiterConfig);\\n\\n      if (newChain.remoteTokenAddress.length == 0) {\\n        revert ZeroAddressNotAllowed();\\n      }\\n\\n      // If the chain already exists, revert\\n      if (!s_remoteChainSelectors.add(newChain.remoteChainSelector)) {\\n        revert ChainAlreadyExists(newChain.remoteChainSelector);\\n      }\\n\\n      RemoteChainConfig storage remoteChainConfig = s_remoteChainConfigs[newChain.remoteChainSelector];\\n\\n      remoteChainConfig.outboundRateLimiterConfig = RateLimiter.TokenBucket({\\n        rate: newChain.outboundRateLimiterConfig.rate,\\n        capacity: newChain.outboundRateLimiterConfig.capacity,\\n        tokens: newChain.outboundRateLimiterConfig.capacity,\\n        lastUpdated: uint32(block.timestamp),\\n        isEnabled: newChain.outboundRateLimiterConfig.isEnabled\\n      });\\n      remoteChainConfig.inboundRateLimiterConfig = RateLimiter.TokenBucket({\\n        rate: newChain.inboundRateLimiterConfig.rate,\\n        capacity: newChain.inboundRateLimiterConfig.capacity,\\n        tokens: newChain.inboundRateLimiterConfig.capacity,\\n        lastUpdated: uint32(block.timestamp),\\n        isEnabled: newChain.inboundRateLimiterConfig.isEnabled\\n      });\\n      remoteChainConfig.remoteTokenAddress = newChain.remoteTokenAddress;\\n\\n      for (uint256 j = 0; j \\u003c newChain.remotePoolAddresses.length; ++j) {\\n        _setRemotePool(newChain.remoteChainSelector, newChain.remotePoolAddresses[j]);\\n      }\\n\\n      emit ChainAdded(\\n        newChain.remoteChainSelector,\\n        newChain.remoteTokenAddress,\\n        newChain.outboundRateLimiterConfig,\\n        newChain.inboundRateLimiterConfig\\n      );\\n    }\\n  }\\n\\n  /// @notice Adds a pool address to the allowed remote token pools for a particular chain.\\n  /// @param remoteChainSelector The remote chain selector for which the remote pool address is being added.\\n  /// @param remotePoolAddress The address of the new remote pool.\\n  function _setRemotePool(uint64 remoteChainSelector, bytes memory remotePoolAddress) internal {\\n    if (remotePoolAddress.length == 0) {\\n      revert ZeroAddressNotAllowed();\\n    }\\n\\n    bytes32 poolHash = keccak256(remotePoolAddress);\\n\\n    // Check if the pool already exists.\\n    if (!s_remoteChainConfigs[remoteChainSelector].remotePools.add(poolHash)) {\\n      revert PoolAlreadyAdded(remoteChainSelector, remotePoolAddress);\\n    }\\n\\n    // Add the pool to the mapping to be able to un-hash it later.\\n    s_remotePoolAddresses[poolHash] = remotePoolAddress;\\n\\n    emit RemotePoolAdded(remoteChainSelector, remotePoolAddress);\\n  }\\n\\n  // ================================================================\\n  // │                        Rate limiting                         │\\n  // ================================================================\\n\\n  /// @dev The inbound rate limits should be slightly higher than the outbound rate limits. This is because many chains\\n  /// finalize blocks in batches. CCIP also commits messages in batches: the commit plugin bundles multiple messages in\\n  /// a single merkle root.\\n  /// Imagine the following scenario.\\n  /// - Chain A has an inbound and outbound rate limit of 100 tokens capacity and 1 token per second refill rate.\\n  /// - Chain B has an inbound and outbound rate limit of 100 tokens capacity and 1 token per second refill rate.\\n  ///\\n  /// At time 0:\\n  /// - Chain A sends 100 tokens to Chain B.\\n  /// At time 5:\\n  /// - Chain A sends 5 tokens to Chain B.\\n  /// At time 6:\\n  /// The epoch that contains blocks [0-5] is finalized.\\n  /// Both transactions will be included in the same merkle root and become executable at the same time. This means\\n  /// the token pool on chain B requires a capacity of 105 to successfully execute both messages at the same time.\\n  /// The exact additional capacity required depends on the refill rate and the size of the source chain epochs and the\\n  /// CCIP round time. For simplicity, a 5-10% buffer should be sufficient in most cases.\\n\\n  /// @notice Sets the rate limiter admin address.\\n  /// @dev Only callable by the owner.\\n  /// @param rateLimitAdmin The new rate limiter admin address.\\n  function setRateLimitAdmin(\\n    address rateLimitAdmin\\n  ) external onlyOwner {\\n    s_rateLimitAdmin = rateLimitAdmin;\\n    emit RateLimitAdminSet(rateLimitAdmin);\\n  }\\n\\n  /// @notice Gets the rate limiter admin address.\\n  function getRateLimitAdmin() external view returns (address) {\\n    return s_rateLimitAdmin;\\n  }\\n\\n  /// @notice Consumes outbound rate limiting capacity in this pool\\n  function _consumeOutboundRateLimit(uint64 remoteChainSelector, uint256 amount) internal {\\n    s_remoteChainConfigs[remoteChainSelector].outboundRateLimiterConfig._consume(amount, address(i_token));\\n\\n    emit OutboundRateLimitConsumed({token: address(i_token), remoteChainSelector: remoteChainSelector, amount: amount});\\n  }\\n\\n  /// @notice Consumes inbound rate limiting capacity in this pool\\n  function _consumeInboundRateLimit(uint64 remoteChainSelector, uint256 amount) internal {\\n    s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._consume(amount, address(i_token));\\n\\n    emit InboundRateLimitConsumed({token: address(i_token), remoteChainSelector: remoteChainSelector, amount: amount});\\n  }\\n\\n  /// @notice Gets the token bucket with its values for the block it was requested at.\\n  /// @return The token bucket.\\n  function getCurrentOutboundRateLimiterState(\\n    uint64 remoteChainSelector\\n  ) external view returns (RateLimiter.TokenBucket memory) {\\n    return s_remoteChainConfigs[remoteChainSelector].outboundRateLimiterConfig._currentTokenBucketState();\\n  }\\n\\n  /// @notice Gets the token bucket with its values for the block it was requested at.\\n  /// @return The token bucket.\\n  function getCurrentInboundRateLimiterState(\\n    uint64 remoteChainSelector\\n  ) external view returns (RateLimiter.TokenBucket memory) {\\n    return s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._currentTokenBucketState();\\n  }\\n\\n  /// @notice Sets multiple chain rate limiter configs.\\n  /// @param remoteChainSelectors The remote chain selector for which the rate limits apply.\\n  /// @param outboundConfigs The new outbound rate limiter config, meaning the onRamp rate limits for the given chain.\\n  /// @param inboundConfigs The new inbound rate limiter config, meaning the offRamp rate limits for the given chain.\\n  function setChainRateLimiterConfigs(\\n    uint64[] calldata remoteChainSelectors,\\n    RateLimiter.Config[] calldata outboundConfigs,\\n    RateLimiter.Config[] calldata inboundConfigs\\n  ) external {\\n    if (msg.sender != s_rateLimitAdmin \\u0026\\u0026 msg.sender != owner()) revert Unauthorized(msg.sender);\\n    if (remoteChainSelectors.length != outboundConfigs.length || remoteChainSelectors.length != inboundConfigs.length) {\\n      revert MismatchedArrayLengths();\\n    }\\n\\n    for (uint256 i = 0; i \\u003c remoteChainSelectors.length; ++i) {\\n      _setRateLimitConfig(remoteChainSelectors[i], outboundConfigs[i], inboundConfigs[i]);\\n    }\\n  }\\n\\n  /// @notice Sets the chain rate limiter config.\\n  /// @param remoteChainSelector The remote chain selector for which the rate limits apply.\\n  /// @param outboundConfig The new outbound rate limiter config, meaning the onRamp rate limits for the given chain.\\n  /// @param inboundConfig The new inbound rate limiter config, meaning the offRamp rate limits for the given chain.\\n  function setChainRateLimiterConfig(\\n    uint64 remoteChainSelector,\\n    RateLimiter.Config memory outboundConfig,\\n    RateLimiter.Config memory inboundConfig\\n  ) external {\\n    if (msg.sender != s_rateLimitAdmin \\u0026\\u0026 msg.sender != owner()) revert Unauthorized(msg.sender);\\n\\n    _setRateLimitConfig(remoteChainSelector, outboundConfig, inboundConfig);\\n  }\\n\\n  function _setRateLimitConfig(\\n    uint64 remoteChainSelector,\\n    RateLimiter.Config memory outboundConfig,\\n    RateLimiter.Config memory inboundConfig\\n  ) internal {\\n    if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector);\\n    RateLimiter._validateTokenBucketConfig(outboundConfig);\\n    s_remoteChainConfigs[remoteChainSelector].outboundRateLimiterConfig._setTokenBucketConfig(outboundConfig);\\n    RateLimiter._validateTokenBucketConfig(inboundConfig);\\n    s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._setTokenBucketConfig(inboundConfig);\\n    emit ChainConfigured(remoteChainSelector, outboundConfig, inboundConfig);\\n  }\\n\\n  // ================================================================\\n  // │                           Access                             │\\n  // ================================================================\\n\\n  /// @notice Checks whether remote chain selector is configured on this contract, and if the msg.sender\\n  /// is a permissioned onRamp for the given chain on the Router.\\n  function _onlyOnRamp(\\n    uint64 remoteChainSelector\\n  ) internal view {\\n    if (!isSupportedChain(remoteChainSelector)) revert ChainNotAllowed(remoteChainSelector);\\n    if (!(msg.sender == s_router.getOnRamp(remoteChainSelector))) revert CallerIsNotARampOnRouter(msg.sender);\\n  }\\n\\n  /// @notice Checks whether remote chain selector is configured on this contract, and if the msg.sender\\n  /// is a permissioned offRamp for the given chain on the Router.\\n  function _onlyOffRamp(\\n    uint64 remoteChainSelector\\n  ) internal view {\\n    if (!isSupportedChain(remoteChainSelector)) revert ChainNotAllowed(remoteChainSelector);\\n    if (!s_router.isOffRamp(remoteChainSelector, msg.sender)) revert CallerIsNotARampOnRouter(msg.sender);\\n  }\\n\\n  // ================================================================\\n  // │                          Allowlist                           │\\n  // ================================================================\\n\\n  function _checkAllowList(\\n    address sender\\n  ) internal view {\\n    if (i_allowlistEnabled) {\\n      if (!s_allowlist.contains(sender)) {\\n        revert SenderNotAllowed(sender);\\n      }\\n    }\\n  }\\n\\n  /// @notice Gets whether the allowlist functionality is enabled.\\n  /// @return true is enabled, false if not.\\n  function getAllowListEnabled() external view returns (bool) {\\n    return i_allowlistEnabled;\\n  }\\n\\n  /// @notice Gets the allowed addresses.\\n  /// @return The allowed addresses.\\n  function getAllowList() external view returns (address[] memory) {\\n    return s_allowlist.values();\\n  }\\n\\n  /// @notice Apply updates to the allow list.\\n  /// @param removes The addresses to be removed.\\n  /// @param adds The addresses to be added.\\n  function applyAllowListUpdates(address[] calldata removes, address[] calldata adds) external onlyOwner {\\n    _applyAllowListUpdates(removes, adds);\\n  }\\n\\n  /// @notice Internal version of applyAllowListUpdates to allow for reuse in the constructor.\\n  function _applyAllowListUpdates(address[] memory removes, address[] memory adds) internal {\\n    if (!i_allowlistEnabled) revert AllowListNotEnabled();\\n\\n    for (uint256 i = 0; i \\u003c removes.length; ++i) {\\n      address toRemove = removes[i];\\n      if (s_allowlist.remove(toRemove)) {\\n        emit AllowListRemove(toRemove);\\n      }\\n    }\\n    for (uint256 i = 0; i \\u003c adds.length; ++i) {\\n      address toAdd = adds[i];\\n      if (toAdd == address(0)) {\\n        continue;\\n      }\\n      if (s_allowlist.add(toAdd)) {\\n        emit AllowListAdd(toAdd);\\n      }\\n    }\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/shared/access/Ownable2Step.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {IOwnable} from \\\"../interfaces/IOwnable.sol\\\";\\n\\n/// @notice A minimal contract that implements 2-step ownership transfer and nothing more. It's made to be minimal\\n/// to reduce the impact of the bytecode size on any contract that inherits from it.\\ncontract Ownable2Step is IOwnable {\\n  /// @notice The pending owner is the address to which ownership may be transferred.\\n  address private s_pendingOwner;\\n  /// @notice The owner is the current owner of the contract.\\n  /// @dev The owner is the second storage variable so any implementing contract could pack other state with it\\n  /// instead of the much less used s_pendingOwner.\\n  address private s_owner;\\n\\n  error OwnerCannotBeZero();\\n  error MustBeProposedOwner();\\n  error CannotTransferToSelf();\\n  error OnlyCallableByOwner();\\n\\n  event OwnershipTransferRequested(address indexed from, address indexed to);\\n  event OwnershipTransferred(address indexed from, address indexed to);\\n\\n  constructor(address newOwner, address pendingOwner) {\\n    if (newOwner == address(0)) {\\n      revert OwnerCannotBeZero();\\n    }\\n\\n    s_owner = newOwner;\\n    if (pendingOwner != address(0)) {\\n      _transferOwnership(pendingOwner);\\n    }\\n  }\\n\\n  /// @notice Get the current owner\\n  function owner() public view override returns (address) {\\n    return s_owner;\\n  }\\n\\n  /// @notice Allows an owner to begin transferring ownership to a new address. The new owner needs to call\\n  /// `acceptOwnership` to accept the transfer before any permissions are changed.\\n  /// @param to The address to which ownership will be transferred.\\n  function transferOwnership(address to) public override onlyOwner {\\n    _transferOwnership(to);\\n  }\\n\\n  /// @notice validate, transfer ownership, and emit relevant events\\n  /// @param to The address to which ownership will be transferred.\\n  function _transferOwnership(address to) private {\\n    if (to == msg.sender) {\\n      revert CannotTransferToSelf();\\n    }\\n\\n    s_pendingOwner = to;\\n\\n    emit OwnershipTransferRequested(s_owner, to);\\n  }\\n\\n  /// @notice Allows an ownership transfer to be completed by the recipient.\\n  function acceptOwnership() external override {\\n    if (msg.sender != s_pendingOwner) {\\n      revert MustBeProposedOwner();\\n    }\\n\\n    address oldOwner = s_owner;\\n    s_owner = msg.sender;\\n    s_pendingOwner = address(0);\\n\\n    emit OwnershipTransferred(oldOwner, msg.sender);\\n  }\\n\\n  /// @notice validate access\\n  function _validateOwnership() internal view {\\n    if (msg.sender != s_owner) {\\n      revert OnlyCallableByOwner();\\n    }\\n  }\\n\\n  /// @notice Reverts if called by anyone other than the contract owner.\\n  modifier onlyOwner() {\\n    _validateOwnership();\\n    _;\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/shared/access/Ownable2StepMsgSender.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {Ownable2Step} from \\\"./Ownable2Step.sol\\\";\\n\\n/// @notice Sets the msg.sender to be the owner of the contract and does not set a pending owner.\\ncontract Ownable2StepMsgSender is Ownable2Step {\\n  constructor() Ownable2Step(msg.sender, address(0)) {}\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/shared/interfaces/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IOwnable {\\n  function owner() external returns (address);\\n\\n  function transferOwnership(address recipient) external;\\n\\n  function acceptOwnership() external;\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITypeAndVersion {\\n  function typeAndVersion() external pure returns (string memory);\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n  /**\\n   * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n   * another (`to`).\\n   *\\n   * Note that `value` may be zero.\\n   */\\n  event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n  /**\\n   * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n   * a call to {approve}. `value` is the new allowance.\\n   */\\n  event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n  /**\\n   * @dev Returns the amount of tokens in existence.\\n   */\\n  function totalSupply() external view returns (uint256);\\n\\n  /**\\n   * @dev Returns the amount of tokens owned by `account`.\\n   */\\n  function balanceOf(address account) external view returns (uint256);\\n\\n  /**\\n   * @dev Moves `amount` tokens from the caller's account to `to`.\\n   *\\n   * Returns a boolean value indicating whether the operation succeeded.\\n   *\\n   * Emits a {Transfer} event.\\n   */\\n  function transfer(address to, uint256 amount) external returns (bool);\\n\\n  /**\\n   * @dev Returns the remaining number of tokens that `spender` will be\\n   * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n   * zero by default.\\n   *\\n   * This value changes when {approve} or {transferFrom} are called.\\n   */\\n  function allowance(address owner, address spender) external view returns (uint256);\\n\\n  /**\\n   * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n   *\\n   * Returns a boolean value indicating whether the operation succeeded.\\n   *\\n   * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n   * that someone may use both the old and the new allowance by unfortunate\\n   * transaction ordering. One possible solution to mitigate this race\\n   * condition is to first reduce the spender's allowance to 0 and set the\\n   * desired value afterwards:\\n   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n   *\\n   * Emits an {Approval} event.\\n   */\\n  function approve(address spender, uint256 amount) external returns (bool);\\n\\n  /**\\n   * @dev Moves `amount` tokens from `from` to `to` using the\\n   * allowance mechanism. `amount` is then deducted from the caller's\\n   * allowance.\\n   *\\n   * Returns a boolean value indicating whether the operation succeeded.\\n   *\\n   * Emits a {Transfer} event.\\n   */\\n  function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n  /**\\n   * @dev Returns the name of the token.\\n   */\\n  function name() external view returns (string memory);\\n\\n  /**\\n   * @dev Returns the symbol of the token.\\n   */\\n  function symbol() external view returns (string memory);\\n\\n  /**\\n   * @dev Returns the decimals places of the token.\\n   */\\n  function decimals() external view returns (uint8);\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n  /**\\n   * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n   * given ``owner``'s signed approval.\\n   *\\n   * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n   * ordering also apply here.\\n   *\\n   * Emits an {Approval} event.\\n   *\\n   * Requirements:\\n   *\\n   * - `spender` cannot be the zero address.\\n   * - `deadline` must be a timestamp in the future.\\n   * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n   * over the EIP712-formatted function arguments.\\n   * - the signature must use ``owner``'s current nonce (see {nonces}).\\n   *\\n   * For more information on the signature format, see the\\n   * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n   * section].\\n   */\\n  function permit(\\n    address owner,\\n    address spender,\\n    uint256 value,\\n    uint256 deadline,\\n    uint8 v,\\n    bytes32 r,\\n    bytes32 s\\n  ) external;\\n\\n  /**\\n   * @dev Returns the current nonce for `owner`. This value must be\\n   * included whenever a signature is generated for {permit}.\\n   *\\n   * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n   * prevents a signature from being used multiple times.\\n   */\\n  function nonces(address owner) external view returns (uint256);\\n\\n  /**\\n   * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n   */\\n  // solhint-disable-next-line func-name-mixedcase\\n  function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n  using Address for address;\\n\\n  function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n    _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n  }\\n\\n  function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n    _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n  }\\n\\n  /**\\n   * @dev Deprecated. This function has issues similar to the ones found in\\n   * {IERC20-approve}, and its usage is discouraged.\\n   *\\n   * Whenever possible, use {safeIncreaseAllowance} and\\n   * {safeDecreaseAllowance} instead.\\n   */\\n  function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n    // safeApprove should only be called when setting an initial allowance,\\n    // or when resetting it to zero. To increase and decrease it, use\\n    // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n    require(\\n      (value == 0) || (token.allowance(address(this), spender) == 0),\\n      \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n    );\\n    _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n  }\\n\\n  function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n    uint256 newAllowance = token.allowance(address(this), spender) + value;\\n    _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n  }\\n\\n  function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n    unchecked {\\n      uint256 oldAllowance = token.allowance(address(this), spender);\\n      require(oldAllowance \\u003e= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n      uint256 newAllowance = oldAllowance - value;\\n      _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n    }\\n  }\\n\\n  function safePermit(\\n    IERC20Permit token,\\n    address owner,\\n    address spender,\\n    uint256 value,\\n    uint256 deadline,\\n    uint8 v,\\n    bytes32 r,\\n    bytes32 s\\n  ) internal {\\n    uint256 nonceBefore = token.nonces(owner);\\n    token.permit(owner, spender, value, deadline, v, r, s);\\n    uint256 nonceAfter = token.nonces(owner);\\n    require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n  }\\n\\n  /**\\n   * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n   * on the return value: the return value is optional (but if data is returned, it must not be false).\\n   * @param token The token targeted by the call.\\n   * @param data The call data (encoded using abi.encode or one of its variants).\\n   */\\n  function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n    // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n    // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n    // the target address contains contract code and also asserts for success in the low-level call.\\n\\n    bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n    if (returndata.length \\u003e 0) {\\n      // Return data is optional\\n      require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n    }\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n  /**\\n   * @dev Returns true if `account` is a contract.\\n   *\\n   * [IMPORTANT]\\n   * ====\\n   * It is unsafe to assume that an address for which this function returns\\n   * false is an externally-owned account (EOA) and not a contract.\\n   *\\n   * Among others, `isContract` will return false for the following\\n   * types of addresses:\\n   *\\n   *  - an externally-owned account\\n   *  - a contract in construction\\n   *  - an address where a contract will be created\\n   *  - an address where a contract lived, but was destroyed\\n   * ====\\n   *\\n   * [IMPORTANT]\\n   * ====\\n   * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n   *\\n   * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n   * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n   * constructor.\\n   * ====\\n   */\\n  function isContract(address account) internal view returns (bool) {\\n    // This method relies on extcodesize/address.code.length, which returns 0\\n    // for contracts in construction, since the code is only stored at the end\\n    // of the constructor execution.\\n\\n    return account.code.length \\u003e 0;\\n  }\\n\\n  /**\\n   * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n   * `recipient`, forwarding all available gas and reverting on errors.\\n   *\\n   * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n   * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n   * imposed by `transfer`, making them unable to receive funds via\\n   * `transfer`. {sendValue} removes this limitation.\\n   *\\n   * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n   *\\n   * IMPORTANT: because control is transferred to `recipient`, care must be\\n   * taken to not create reentrancy vulnerabilities. Consider using\\n   * {ReentrancyGuard} or the\\n   * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n   */\\n  function sendValue(address payable recipient, uint256 amount) internal {\\n    require(address(this).balance \\u003e= amount, \\\"Address: insufficient balance\\\");\\n\\n    (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n    require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n  }\\n\\n  /**\\n   * @dev Performs a Solidity function call using a low level `call`. A\\n   * plain `call` is an unsafe replacement for a function call: use this\\n   * function instead.\\n   *\\n   * If `target` reverts with a revert reason, it is bubbled up by this\\n   * function (like regular Solidity function calls).\\n   *\\n   * Returns the raw returned data. To convert to the expected return value,\\n   * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n   *\\n   * Requirements:\\n   *\\n   * - `target` must be a contract.\\n   * - calling `target` with `data` must not revert.\\n   *\\n   * _Available since v3.1._\\n   */\\n  function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n    return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n  }\\n\\n  /**\\n   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n   * `errorMessage` as a fallback revert reason when `target` reverts.\\n   *\\n   * _Available since v3.1._\\n   */\\n  function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n    return functionCallWithValue(target, data, 0, errorMessage);\\n  }\\n\\n  /**\\n   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n   * but also transferring `value` wei to `target`.\\n   *\\n   * Requirements:\\n   *\\n   * - the calling contract must have an ETH balance of at least `value`.\\n   * - the called Solidity function must be `payable`.\\n   *\\n   * _Available since v3.1._\\n   */\\n  function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n    return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n  }\\n\\n  /**\\n   * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n   * with `errorMessage` as a fallback revert reason when `target` reverts.\\n   *\\n   * _Available since v3.1._\\n   */\\n  function functionCallWithValue(\\n    address target,\\n    bytes memory data,\\n    uint256 value,\\n    string memory errorMessage\\n  ) internal returns (bytes memory) {\\n    require(address(this).balance \\u003e= value, \\\"Address: insufficient balance for call\\\");\\n    (bool success, bytes memory returndata) = target.call{value: value}(data);\\n    return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n  }\\n\\n  /**\\n   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n   * but performing a static call.\\n   *\\n   * _Available since v3.3._\\n   */\\n  function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n    return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n  }\\n\\n  /**\\n   * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n   * but performing a static call.\\n   *\\n   * _Available since v3.3._\\n   */\\n  function functionStaticCall(\\n    address target,\\n    bytes memory data,\\n    string memory errorMessage\\n  ) internal view returns (bytes memory) {\\n    (bool success, bytes memory returndata) = target.staticcall(data);\\n    return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n  }\\n\\n  /**\\n   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n   * but performing a delegate call.\\n   *\\n   * _Available since v3.4._\\n   */\\n  function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n    return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n  }\\n\\n  /**\\n   * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n   * but performing a delegate call.\\n   *\\n   * _Available since v3.4._\\n   */\\n  function functionDelegateCall(\\n    address target,\\n    bytes memory data,\\n    string memory errorMessage\\n  ) internal returns (bytes memory) {\\n    (bool success, bytes memory returndata) = target.delegatecall(data);\\n    return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n  }\\n\\n  /**\\n   * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n   * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n   *\\n   * _Available since v4.8._\\n   */\\n  function verifyCallResultFromTarget(\\n    address target,\\n    bool success,\\n    bytes memory returndata,\\n    string memory errorMessage\\n  ) internal view returns (bytes memory) {\\n    if (success) {\\n      if (returndata.length == 0) {\\n        // only check isContract if the call was successful and the return data is empty\\n        // otherwise we already know that it was a contract\\n        require(isContract(target), \\\"Address: call to non-contract\\\");\\n      }\\n      return returndata;\\n    } else {\\n      _revert(returndata, errorMessage);\\n    }\\n  }\\n\\n  /**\\n   * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n   * revert reason or using the provided one.\\n   *\\n   * _Available since v4.3._\\n   */\\n  function verifyCallResult(\\n    bool success,\\n    bytes memory returndata,\\n    string memory errorMessage\\n  ) internal pure returns (bytes memory) {\\n    if (success) {\\n      return returndata;\\n    } else {\\n      _revert(returndata, errorMessage);\\n    }\\n  }\\n\\n  function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n    // Look for revert reason and bubble it up if present\\n    if (returndata.length \\u003e 0) {\\n      // The easiest way to bubble the revert reason is using memory via assembly\\n      /// @solidity memory-safe-assembly\\n      assembly {\\n        let returndata_size := mload(returndata)\\n        revert(add(32, returndata), returndata_size)\\n      }\\n    } else {\\n      revert(errorMessage);\\n    }\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n *     // Add the library methods\\n *     using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n *     // Declare a set state variable\\n *     EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n  // To implement this library for multiple types with as little code\\n  // repetition as possible, we write it in terms of a generic Set type with\\n  // bytes32 values.\\n  // The Set implementation uses private functions, and user-facing\\n  // implementations (such as AddressSet) are just wrappers around the\\n  // underlying Set.\\n  // This means that we can only create new EnumerableSets for types that fit\\n  // in bytes32.\\n\\n  struct Set {\\n    // Storage of set values\\n    bytes32[] _values;\\n    // Position of the value in the `values` array, plus 1 because index 0\\n    // means a value is not in the set.\\n    mapping(bytes32 =\\u003e uint256) _indexes;\\n  }\\n\\n  /**\\n   * @dev Add a value to a set. O(1).\\n   *\\n   * Returns true if the value was added to the set, that is if it was not\\n   * already present.\\n   */\\n  function _add(Set storage set, bytes32 value) private returns (bool) {\\n    if (!_contains(set, value)) {\\n      set._values.push(value);\\n      // The value is stored at length-1, but we add 1 to all indexes\\n      // and use 0 as a sentinel value\\n      set._indexes[value] = set._values.length;\\n      return true;\\n    } else {\\n      return false;\\n    }\\n  }\\n\\n  /**\\n   * @dev Removes a value from a set. O(1).\\n   *\\n   * Returns true if the value was removed from the set, that is if it was\\n   * present.\\n   */\\n  function _remove(Set storage set, bytes32 value) private returns (bool) {\\n    // We read and store the value's index to prevent multiple reads from the same storage slot\\n    uint256 valueIndex = set._indexes[value];\\n\\n    if (valueIndex != 0) {\\n      // Equivalent to contains(set, value)\\n      // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n      // the array, and then remove the last element (sometimes called as 'swap and pop').\\n      // This modifies the order of the array, as noted in {at}.\\n\\n      uint256 toDeleteIndex = valueIndex - 1;\\n      uint256 lastIndex = set._values.length - 1;\\n\\n      if (lastIndex != toDeleteIndex) {\\n        bytes32 lastValue = set._values[lastIndex];\\n\\n        // Move the last value to the index where the value to delete is\\n        set._values[toDeleteIndex] = lastValue;\\n        // Update the index for the moved value\\n        set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n      }\\n\\n      // Delete the slot where the moved value was stored\\n      set._values.pop();\\n\\n      // Delete the index for the deleted slot\\n      delete set._indexes[value];\\n\\n      return true;\\n    } else {\\n      return false;\\n    }\\n  }\\n\\n  /**\\n   * @dev Returns true if the value is in the set. O(1).\\n   */\\n  function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n    return set._indexes[value] != 0;\\n  }\\n\\n  /**\\n   * @dev Returns the number of values on the set. O(1).\\n   */\\n  function _length(Set storage set) private view returns (uint256) {\\n    return set._values.length;\\n  }\\n\\n  /**\\n   * @dev Returns the value stored at position `index` in the set. O(1).\\n   *\\n   * Note that there are no guarantees on the ordering of values inside the\\n   * array, and it may change when more values are added or removed.\\n   *\\n   * Requirements:\\n   *\\n   * - `index` must be strictly less than {length}.\\n   */\\n  function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n    return set._values[index];\\n  }\\n\\n  /**\\n   * @dev Return the entire set in an array\\n   *\\n   * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n   * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n   * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n   * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n   */\\n  function _values(Set storage set) private view returns (bytes32[] memory) {\\n    return set._values;\\n  }\\n\\n  // Bytes32Set\\n\\n  struct Bytes32Set {\\n    Set _inner;\\n  }\\n\\n  /**\\n   * @dev Add a value to a set. O(1).\\n   *\\n   * Returns true if the value was added to the set, that is if it was not\\n   * already present.\\n   */\\n  function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n    return _add(set._inner, value);\\n  }\\n\\n  /**\\n   * @dev Removes a value from a set. O(1).\\n   *\\n   * Returns true if the value was removed from the set, that is if it was\\n   * present.\\n   */\\n  function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n    return _remove(set._inner, value);\\n  }\\n\\n  /**\\n   * @dev Returns true if the value is in the set. O(1).\\n   */\\n  function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n    return _contains(set._inner, value);\\n  }\\n\\n  /**\\n   * @dev Returns the number of values in the set. O(1).\\n   */\\n  function length(Bytes32Set storage set) internal view returns (uint256) {\\n    return _length(set._inner);\\n  }\\n\\n  /**\\n   * @dev Returns the value stored at position `index` in the set. O(1).\\n   *\\n   * Note that there are no guarantees on the ordering of values inside the\\n   * array, and it may change when more values are added or removed.\\n   *\\n   * Requirements:\\n   *\\n   * - `index` must be strictly less than {length}.\\n   */\\n  function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n    return _at(set._inner, index);\\n  }\\n\\n  /**\\n   * @dev Return the entire set in an array\\n   *\\n   * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n   * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n   * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n   * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n   */\\n  function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n    bytes32[] memory store = _values(set._inner);\\n    bytes32[] memory result;\\n\\n    /// @solidity memory-safe-assembly\\n    assembly {\\n      result := store\\n    }\\n\\n    return result;\\n  }\\n\\n  // AddressSet\\n\\n  struct AddressSet {\\n    Set _inner;\\n  }\\n\\n  /**\\n   * @dev Add a value to a set. O(1).\\n   *\\n   * Returns true if the value was added to the set, that is if it was not\\n   * already present.\\n   */\\n  function add(AddressSet storage set, address value) internal returns (bool) {\\n    return _add(set._inner, bytes32(uint256(uint160(value))));\\n  }\\n\\n  /**\\n   * @dev Removes a value from a set. O(1).\\n   *\\n   * Returns true if the value was removed from the set, that is if it was\\n   * present.\\n   */\\n  function remove(AddressSet storage set, address value) internal returns (bool) {\\n    return _remove(set._inner, bytes32(uint256(uint160(value))));\\n  }\\n\\n  /**\\n   * @dev Returns true if the value is in the set. O(1).\\n   */\\n  function contains(AddressSet storage set, address value) internal view returns (bool) {\\n    return _contains(set._inner, bytes32(uint256(uint160(value))));\\n  }\\n\\n  /**\\n   * @dev Returns the number of values in the set. O(1).\\n   */\\n  function length(AddressSet storage set) internal view returns (uint256) {\\n    return _length(set._inner);\\n  }\\n\\n  /**\\n   * @dev Returns the value stored at position `index` in the set. O(1).\\n   *\\n   * Note that there are no guarantees on the ordering of values inside the\\n   * array, and it may change when more values are added or removed.\\n   *\\n   * Requirements:\\n   *\\n   * - `index` must be strictly less than {length}.\\n   */\\n  function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n    return address(uint160(uint256(_at(set._inner, index))));\\n  }\\n\\n  /**\\n   * @dev Return the entire set in an array\\n   *\\n   * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n   * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n   * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n   * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n   */\\n  function values(AddressSet storage set) internal view returns (address[] memory) {\\n    bytes32[] memory store = _values(set._inner);\\n    address[] memory result;\\n\\n    /// @solidity memory-safe-assembly\\n    assembly {\\n      result := store\\n    }\\n\\n    return result;\\n  }\\n\\n  // UintSet\\n\\n  struct UintSet {\\n    Set _inner;\\n  }\\n\\n  /**\\n   * @dev Add a value to a set. O(1).\\n   *\\n   * Returns true if the value was added to the set, that is if it was not\\n   * already present.\\n   */\\n  function add(UintSet storage set, uint256 value) internal returns (bool) {\\n    return _add(set._inner, bytes32(value));\\n  }\\n\\n  /**\\n   * @dev Removes a value from a set. O(1).\\n   *\\n   * Returns true if the value was removed from the set, that is if it was\\n   * present.\\n   */\\n  function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n    return _remove(set._inner, bytes32(value));\\n  }\\n\\n  /**\\n   * @dev Returns true if the value is in the set. O(1).\\n   */\\n  function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n    return _contains(set._inner, bytes32(value));\\n  }\\n\\n  /**\\n   * @dev Returns the number of values in the set. O(1).\\n   */\\n  function length(UintSet storage set) internal view returns (uint256) {\\n    return _length(set._inner);\\n  }\\n\\n  /**\\n   * @dev Returns the value stored at position `index` in the set. O(1).\\n   *\\n   * Note that there are no guarantees on the ordering of values inside the\\n   * array, and it may change when more values are added or removed.\\n   *\\n   * Requirements:\\n   *\\n   * - `index` must be strictly less than {length}.\\n   */\\n  function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n    return uint256(_at(set._inner, index));\\n  }\\n\\n  /**\\n   * @dev Return the entire set in an array\\n   *\\n   * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n   * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n   * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n   * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n   */\\n  function values(UintSet storage set) internal view returns (uint256[] memory) {\\n    bytes32[] memory store = _values(set._inner);\\n    uint256[] memory result;\\n\\n    /// @solidity memory-safe-assembly\\n    assembly {\\n      result := store\\n    }\\n\\n    return result;\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n    /**\\n     * @dev Returns true if this contract implements the interface defined by\\n     * `interfaceId`. See the corresponding\\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n     * to learn more about how these ids are created.\\n     *\\n     * This function call must use less than 30 000 gas.\\n     */\\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n *     // Add the library methods\\n *     using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n *     // Declare a set state variable\\n *     EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n    // To implement this library for multiple types with as little code\\n    // repetition as possible, we write it in terms of a generic Set type with\\n    // bytes32 values.\\n    // The Set implementation uses private functions, and user-facing\\n    // implementations (such as AddressSet) are just wrappers around the\\n    // underlying Set.\\n    // This means that we can only create new EnumerableSets for types that fit\\n    // in bytes32.\\n\\n    struct Set {\\n        // Storage of set values\\n        bytes32[] _values;\\n        // Position is the index of the value in the `values` array plus 1.\\n        // Position 0 is used to mean a value is not in the set.\\n        mapping(bytes32 value =\\u003e uint256) _positions;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function _add(Set storage set, bytes32 value) private returns (bool) {\\n        if (!_contains(set, value)) {\\n            set._values.push(value);\\n            // The value is stored at length-1, but we add 1 to all indexes\\n            // and use 0 as a sentinel value\\n            set._positions[value] = set._values.length;\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\\n        // We cache the value's position to prevent multiple reads from the same storage slot\\n        uint256 position = set._positions[value];\\n\\n        if (position != 0) {\\n            // Equivalent to contains(set, value)\\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\\n            // This modifies the order of the array, as noted in {at}.\\n\\n            uint256 valueIndex = position - 1;\\n            uint256 lastIndex = set._values.length - 1;\\n\\n            if (valueIndex != lastIndex) {\\n                bytes32 lastValue = set._values[lastIndex];\\n\\n                // Move the lastValue to the index where the value to delete is\\n                set._values[valueIndex] = lastValue;\\n                // Update the tracked position of the lastValue (that was just moved)\\n                set._positions[lastValue] = position;\\n            }\\n\\n            // Delete the slot where the moved value was stored\\n            set._values.pop();\\n\\n            // Delete the tracked position for the deleted slot\\n            delete set._positions[value];\\n\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n        return set._positions[value] != 0;\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function _length(Set storage set) private view returns (uint256) {\\n        return set._values.length;\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n        return set._values[index];\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function _values(Set storage set) private view returns (bytes32[] memory) {\\n        return set._values;\\n    }\\n\\n    // Bytes32Set\\n\\n    struct Bytes32Set {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _add(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _remove(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n        return _contains(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(Bytes32Set storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n        return _at(set._inner, index);\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        bytes32[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // AddressSet\\n\\n    struct AddressSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(AddressSet storage set, address value) internal returns (bool) {\\n        return _add(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(AddressSet storage set, address value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(AddressSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n        return address(uint160(uint256(_at(set._inner, index))));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(AddressSet storage set) internal view returns (address[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        address[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // UintSet\\n\\n    struct UintSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _add(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(UintSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n        return uint256(_at(set._inner, index));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        uint256[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n}\\n\"}}}"
