From 07e2c9dc9eef2cde9fbb91a147b5acfdb8c0d851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wei=C3=9Fer=20Hase?= Date: Wed, 21 Aug 2024 19:16:37 +0200 Subject: [PATCH] feat: adding cache and sync functionality (#5) * chore: deprecating unused chains * feat: adding uniV3Factory to constructors * fix: fixture tests and e2e * fix: ups * feat: deprecate polygon * chore: final tweaks * fix: workflow url * fix: upsy * feat: adding cache functionality * fix: compilation issues * fix: unit tests * fix: e2e and unit tests * fix: minor comments * fix: addressing comments in PR * chore: deployments * fix: fatal override bug * feat: adding sync public method * feat: optimize sync method * fix: yarn lock * fix: reverting nasty test trimming * fix: add natspec * chore: cleanup contracts to redeploy * fix: typos * chore: new deployments * chore: ups, deployment files --- .env.example | 2 + .gitignore | 1 + README.md | 70 +- .../1a064550c306047de745b0aa850ace2a.json | 281 ------- .../c13a9c9fec104b95e6c1800beae11ff9.json | 251 ------ .../eef40425e50b109f1821184fab9444c8.json | 278 ------- .../optimism/ConnextReceiverAdapter.json | 32 +- deployments/optimism/DataReceiver.json | 192 +++-- deployments/optimism/OracleFactory.json | 70 +- deployments/optimism/OracleSidechain.json | 396 ---------- .../1a064550c306047de745b0aa850ace2a.json | 281 ------- .../c13a9c9fec104b95e6c1800beae11ff9.json | 251 ------ .../eef40425e50b109f1821184fab9444c8.json | 278 ------- deployments/polygon/.chainId | 1 + .../polygon/ConnextReceiverAdapter.json | 279 +++++++ deployments/polygon/DataReceiver.json | 696 +++++++++++++++++ deployments/polygon/OracleFactory.json | 726 ++++++++++++++++++ hardhat.config.ts | 19 +- solidity/contracts/DataReceiver.sol | 60 +- solidity/contracts/OracleSidechain.sol | 3 +- solidity/interfaces/IDataReceiver.sol | 20 +- test/e2e/data-receiver.spec.ts | 137 +++- test/unit/DataReceiver.spec.ts | 245 +++++- utils/constants.ts | 3 + yarn.lock | 138 +++- 25 files changed, 2536 insertions(+), 2174 deletions(-) delete mode 100644 deployments/ethereum/solcInputs/1a064550c306047de745b0aa850ace2a.json delete mode 100644 deployments/ethereum/solcInputs/c13a9c9fec104b95e6c1800beae11ff9.json delete mode 100644 deployments/ethereum/solcInputs/eef40425e50b109f1821184fab9444c8.json delete mode 100644 deployments/optimism/OracleSidechain.json delete mode 100644 deployments/optimism/solcInputs/1a064550c306047de745b0aa850ace2a.json delete mode 100644 deployments/optimism/solcInputs/c13a9c9fec104b95e6c1800beae11ff9.json delete mode 100644 deployments/optimism/solcInputs/eef40425e50b109f1821184fab9444c8.json create mode 100644 deployments/polygon/.chainId create mode 100644 deployments/polygon/ConnextReceiverAdapter.json create mode 100644 deployments/polygon/DataReceiver.json create mode 100644 deployments/polygon/OracleFactory.json diff --git a/.env.example b/.env.example index fee4603..52e287c 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,7 @@ # HTTPs providers NODE_URI_ETHEREUM= NODE_URI_OPTIMISM= +NODE_URI_POLYGON= NODE_URI_SEPOLIA= NODE_URI_OPTIMISTICSEPOLIA= @@ -11,6 +12,7 @@ TEST_1_PRIVATE_KEY= # Etherscan (optional, only for verifying smart contracts) ETHEREUM_ETHERSCAN_API_KEY= OPTIMISTICETHEREUM_ETHERSCAN_API_KEY= +POLYGON_ETHERSCAN_API_KEY= SEPOLIA_ETHERSCAN_API_KEY= OPTIMISTICSEPOLIA_ETHERSCAN_API_KEY= diff --git a/.gitignore b/.gitignore index c1f16df..f99ae0b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ deployments/localhost deployments/sepoliaDummy deployments/sepolia deployments/optimisticSepolia +deployments/**/solcInputs # Config files .env diff --git a/README.md b/README.md index f44a3bc..1610c1e 100644 --- a/README.md +++ b/README.md @@ -199,35 +199,71 @@ For 1 tag manual-deployment and bridging In `/utils/constants.ts`, one can find the configuration of the strategies chosen by chain. The default for Sepolia is set to refresh each 1/2 day, using periods of 1hr, and comparing a 2hr twap with 500 ticks (+-5%) threshold. +## Production deployment + +Make sure to have the correct addresses for `tokenA` and `tokenB` in `utils/constants.ts` as well as the desired `periodLength`, `strategyCooldown`, `twapPeriod`, and `twapThreshold`. Also check the correct fee, as if an inexistent UniswapV3 pool is referenced, the script will eventually deploy it. + +Setup the `receiver` network for the origin chain (e.g. `ethereum`, receiver `polygon`) and select the desired script to run using the origin chain as script selected network (even if the deployment occurs in the sidechain), with the exception of `verify` scripts. Each script will execute the required subsequent ones, so it is not necessary to run them all. + +This script will deploy (the OracleFactory if necessary and) the DataReceiver, in the receiver chain of `ethereum` (that it might be `optimism` or `polygon`). This is to enable the off-chain coordination. + +```bash +yarn deploy --network ethereum --tags data-receiver +``` + +Scripts: + +- `data-sender`: deploys DataFeed (mainnet) +- `data-receiver`: deploys OracleFactory and DataReceiver (sidechain) +- `connext-setup`: runs both `data-sender` and `data-receiver` (if not yet deployed) plus deploys Connext SenderAdapter and ReceiverAdapter +- `manual-fetch-observation`: runs `data-receiver` and attempts to fetch a new observation with arbitrary timestamps +- `fetch-observation`: runs `data-receiver` plus deploys DataFeedStrategy and attempts to programatically fetch a new observation +- `bridge-observation`: runs up to `connext-setup` and attempts to bridge a recently fetched observation +- `setup-keeper`: runs up to `connext-setup` and deploys StrategyJob +- `work-job`: (runs up to `setup-keeper` and) attempts to work StrategyJob (requires registration in Keep3r contract) + ## Address Registry -**TODO: Update with the latest addresses** +#### Mainnet -#### Testnet +##### Optimism (_receiver_) + +| Contract | Address | +| ------------------------- | -------------------------------------------- | +| _Connext ReceiverAdapter_ | `0xe5BE7f12B94D185f892c4BBe6F88ABE65CE1A8af` | +| _DataReceiver_ | `0x4E0CeF6426eb70b5708845825A5375688808891d` | +| _OracleFactory_ | `0x0BcD059c1546359b45f2606Ed6E08e1F5ef4f4Bf` | -##### Sepolia (sender and _receiver_) +##### Polygon (_receiver_) | Contract | Address | | ------------------------- | -------------------------------------------- | -| DataFeed | `0x8Fb68E83831c7e8622e10C154CC0d24856440809` | -| DataFeedStrategy | `0x606e25c67B8d6550075C8085083c763769Cfe2BE` | -| StrategyJob | `0x606e25c67B8d6550075C8085083c763769Cfe2BE` | -| Connext SenderAdapter | `0xF73E6BC8ca4Fec5e9773C4f22E8EBEEEd12733d6` | -| _Connext ReceiverAdapter_ | `0x05a6CEF3f938E8E9b3112CB44e8B9771638989Ed` | -| _DataReceiver_ | `0xa09683377E5cE0bB7eEa90D2b64e3644f7eA1B8a` | -| _OracleFactory_ | `0x0594Dc74043b93Bdb371f01187704C98D45bd4E6` | +| _Connext ReceiverAdapter_ | `0x4839750090571A0fCcBaa3a8Fffe3DE22b4B7D51` | +| _DataReceiver_ | `0xe5BE7f12B94D185f892c4BBe6F88ABE65CE1A8af` | +| _OracleFactory_ | `0x69ceAA797274fd85F3b3a1f5b29857BFD9B9b259` | + +#### Testnet + +##### Sepolia (sender) + +| Contract | Address | +| --------------------- | -------------------------------------------- | +| DataFeed | `0xcDddb7c04000e492E2e6CbD924b595CdaB9DEFa9` | +| DataFeedStrategy | `0x8379506385432f1e02cE516f5A5F52d15E250c88` | +| StrategyJob | `0xa77E459Eba5F1D05Cd22C8a28fB6b2725dfd4D21` | +| Connext SenderAdapter | `0x54B79C4B3E5BA80275B33B5bCaaeC762bf04E558` | ##### OP Sepolia (_receiver_) | Contract | Address | | ------------------------- | -------------------------------------------- | -| _Connext ReceiverAdapter_ | `0x4D81A5C9F7706377df368D1716460da03faEcBcb` | -| _DataReceiver_ | `0x768c227320165A71A4001fE23A0C38CD6B5585c0` | -| _OracleFactory_ | `0xB8aD440Ad7A3298C73258b1Fc202A081Db9107cb` | +| _Connext ReceiverAdapter_ | `0x4839750090571A0fCcBaa3a8Fffe3DE22b4B7D51` | +| _DataReceiver_ | `0x4B11b6BEF9480d62b471a9a91a52C893143Bad19` | +| _OracleFactory_ | `0xa32f6603F9466eF0190CAc36759E41B40653471A` | ##### Whitelisted pipelines: -| Chain - Pool | Chain - OracleSidechain | -| ------------------------------------------------------ | --------------------------------------------------------- | -| Sepolia - `0x317ceCd3eB02158f97DF0B67B788edCda4E066e5` | OP Sepolia - `0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9` | -| Sepolia - `0x317ceCd3eB02158f97DF0B67B788edCda4E066e5` | Sepolia - `0xED7f635EE962537b4DB13a1e1c3922EC65366fE2` | +| Chain - Pool | Chain - OracleSidechain | +| ------------------------------------------------------ | ----------------------- | +| Mainnet - `0xTODO` | OP - `0xTBD` | +| Sepolia - `0xd0EAFA86eC9C2f3f8f12798974222C645dc8DBF0` | OP Sepolia - `0xTBD` | diff --git a/deployments/ethereum/solcInputs/1a064550c306047de745b0aa850ace2a.json b/deployments/ethereum/solcInputs/1a064550c306047de745b0aa850ace2a.json deleted file mode 100644 index a8053ba..0000000 --- a/deployments/ethereum/solcInputs/1a064550c306047de745b0aa850ace2a.json +++ /dev/null @@ -1,281 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "solidity/contracts/DataFeed.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {PipelineManagement, Governable} from './peripherals/PipelineManagement.sol';\nimport {IDataFeed, IDataFeedStrategy, IUniswapV3Pool, IConnextSenderAdapter, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeed.sol';\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\n\n/// @title The DataFeed contract\n/// @notice Queries UniV3Pools, stores history proofs on chain, handles data broadcast\ncontract DataFeed is IDataFeed, PipelineManagement {\n /// @inheritdoc IDataFeed\n IDataFeedStrategy public strategy;\n\n /// @inheritdoc IDataFeed\n uint32 public minLastOracleDelta;\n\n /// @inheritdoc IDataFeed\n mapping(bytes32 => PoolState) public lastPoolStateObserved;\n\n mapping(bytes32 => bool) internal _observedKeccak;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(\n address _governor,\n IDataFeedStrategy _strategy,\n uint32 _minLastOracleDelta\n ) Governable(_governor) {\n _setStrategy(_strategy);\n _setMinLastOracleDelta(_minLastOracleDelta);\n }\n\n /// @inheritdoc IDataFeed\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external payable validatePipeline(_chainId, _poolSalt, _poolNonce) {\n (uint32 _destinationDomainId, address _dataReceiver) = validateSenderAdapter(_bridgeSenderAdapter, _chainId);\n\n {\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _poolNonce, _observationsData));\n if (!_observedKeccak[_resultingKeccak]) revert UnknownHash();\n }\n\n _bridgeSenderAdapter.bridgeObservations{value: msg.value}(_dataReceiver, _destinationDomainId, _observationsData, _poolSalt, _poolNonce);\n emit DataBroadcast(_poolSalt, _poolNonce, _chainId, _dataReceiver, _bridgeSenderAdapter);\n }\n\n /// @inheritdoc IDataFeed\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external onlyStrategy validatePool(_poolSalt) {\n IOracleSidechain.ObservationData[] memory _observationsData;\n PoolState memory _lastPoolStateObserved = lastPoolStateObserved[_poolSalt];\n\n {\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _tickCumulatives, ) = _pool.observe(_secondsAgos);\n\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _secondsAgo;\n int56 _tickCumulative;\n int24 _arithmeticMeanTick;\n uint256 _secondsAgosLength = _secondsAgos.length;\n uint256 _i;\n\n // If first fetched observation\n if (_lastPoolStateObserved.blockTimestamp == 0) {\n if (_secondsAgosLength == 1) revert InvalidSecondsAgos();\n // Initializes timestamp and cumulative with first item\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength - 1);\n _secondsAgo = _secondsAgos[0];\n _tickCumulative = _tickCumulatives[0];\n // Skips first loop iteration\n // Cannot not calculate twap (there is no last tickCumulative)\n unchecked {\n ++_i;\n }\n } else {\n // Initializes timestamp and cumulative with cache\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength);\n _secondsAgo = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n _tickCumulative = _lastPoolStateObserved.tickCumulative;\n }\n\n uint32 _delta;\n int56 _tickCumulativesDelta;\n uint256 _observationsDataIndex;\n\n for (; _i < _secondsAgosLength; ) {\n // Twap is calculated using the last recorded tickCumulative and time\n _tickCumulativesDelta = _tickCumulatives[_i] - _tickCumulative;\n _delta = _secondsAgo - _secondsAgos[_i];\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n\n // Stores blockTimestamp and tick in observations array\n _observationsData[_observationsDataIndex++] = IOracleSidechain.ObservationData({\n blockTimestamp: _secondsNow - _secondsAgo,\n tick: _arithmeticMeanTick\n });\n\n // Updates state for next iteration calculation\n _secondsAgo = _secondsAgos[_i];\n _tickCumulative = _tickCumulatives[_i];\n\n unchecked {\n ++_i;\n }\n }\n\n if (_delta < minLastOracleDelta) revert InsufficientDelta();\n\n _lastPoolStateObserved = PoolState({\n poolNonce: _lastPoolStateObserved.poolNonce + 1,\n blockTimestamp: _secondsNow - _secondsAgo,\n tickCumulative: _tickCumulative,\n arithmeticMeanTick: _arithmeticMeanTick\n });\n }\n\n // Stores last pool state in the contract cache\n lastPoolStateObserved[_poolSalt] = _lastPoolStateObserved;\n\n // Whitelists keccak256 to be broadcast to other chains\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData));\n _observedKeccak[_resultingKeccak] = true;\n\n // Emits event with data to be read off-chain and used as broadcast input parameters\n emit PoolObserved(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData);\n }\n\n /// @inheritdoc IDataFeed\n function setStrategy(IDataFeedStrategy _strategy) external onlyGovernor {\n _setStrategy(_strategy);\n }\n\n /// @inheritdoc IDataFeed\n function setMinLastOracleDelta(uint32 _minLastOracleDelta) external onlyGovernor {\n _setMinLastOracleDelta(_minLastOracleDelta);\n }\n\n /// @inheritdoc IDataFeed\n function getPoolNonce(bytes32 _poolSalt) public view override(IDataFeed, PipelineManagement) returns (uint24 _poolNonce) {\n PoolState memory _lastPoolStateObserved = lastPoolStateObserved[_poolSalt];\n return _lastPoolStateObserved.poolNonce;\n }\n\n function _setStrategy(IDataFeedStrategy _strategy) private {\n if (address(_strategy) == address(0)) revert ZeroAddress();\n\n strategy = _strategy;\n emit StrategySet(_strategy);\n }\n\n function _setMinLastOracleDelta(uint32 _minLastOracleDelta) private {\n if (_minLastOracleDelta == 0) revert ZeroAmount();\n\n minLastOracleDelta = _minLastOracleDelta;\n emit MinLastOracleDeltaSet(_minLastOracleDelta);\n }\n\n modifier onlyStrategy() {\n if (msg.sender != address(strategy)) revert OnlyStrategy();\n _;\n }\n}\n" - }, - "solidity/contracts/peripherals/PipelineManagement.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {IPipelineManagement, IBridgeSenderAdapter} from '../../interfaces/peripherals/IPipelineManagement.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\n\nabstract contract PipelineManagement is IPipelineManagement, Governable {\n using EnumerableSet for EnumerableSet.Bytes32Set;\n using EnumerableSet for EnumerableSet.UintSet;\n\n EnumerableSet.Bytes32Set private _whitelistedPools;\n\n EnumerableSet.UintSet private _whitelistedChains;\n\n /// @inheritdoc IPipelineManagement\n mapping(uint32 => mapping(bytes32 => uint24)) public whitelistedNonces;\n\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => bool) public whitelistedAdapters;\n\n // adapter => chainId => destinationDomain\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => uint32)) public destinationDomainIds;\n\n // adapter => destinationDomainId => dataReceiver\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => address)) public receivers;\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external onlyGovernor {\n _whitelistPipeline(_chainId, _poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external onlyGovernor {\n uint256 _chainIdsLength = _chainIds.length;\n if (_chainIdsLength != _poolSalts.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _chainIdsLength; ++_i) {\n _whitelistPipeline(_chainIds[_i], _poolSalts[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _whitelistAdapter(_bridgeSenderAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external onlyGovernor {\n _setDestinationDomainId(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _chainIds,\n uint32[] calldata _destinationDomainIds\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _chainIds.length || _bridgeSenderAdapterLength != _destinationDomainIds.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setDestinationDomainId(_bridgeSenderAdapters[_i], _chainIds[_i], _destinationDomainIds[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external onlyGovernor {\n _setReceiver(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _destinationDomainIds.length || _bridgeSenderAdapterLength != _dataReceivers.length)\n revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setReceiver(_bridgeSenderAdapters[_i], _destinationDomainIds[_i], _dataReceivers[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistedPools() external view returns (bytes32[] memory) {\n return _whitelistedPools.values();\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistedChains() external view returns (uint256[] memory) {\n return _whitelistedChains.values();\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return _whitelistedPools.contains(_poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return whitelistedNonces[_chainId][_poolSalt] != 0;\n }\n\n function getPoolNonce(bytes32 _poolSalt) public view virtual returns (uint24 _poolNonce);\n\n /// @inheritdoc IPipelineManagement\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n public\n view\n returns (uint32 _destinationDomainId, address _dataReceiver)\n {\n if (!whitelistedAdapters[_bridgeSenderAdapter]) revert UnallowedAdapter();\n\n _destinationDomainId = destinationDomainIds[_bridgeSenderAdapter][_chainId];\n if (_destinationDomainId == 0) revert DestinationDomainIdNotSet();\n\n _dataReceiver = receivers[_bridgeSenderAdapter][_destinationDomainId];\n if (_dataReceiver == address(0)) revert ReceiverNotSet();\n }\n\n function _whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) internal {\n if (whitelistedNonces[_chainId][_poolSalt] != 0) revert AlreadyAllowedPipeline();\n\n uint24 _whitelistedNonce = getPoolNonce(_poolSalt) + 1;\n whitelistedNonces[_chainId][_poolSalt] = _whitelistedNonce;\n _whitelistedPools.add(_poolSalt);\n _whitelistedChains.add(_chainId);\n emit PipelineWhitelisted(_chainId, _poolSalt, _whitelistedNonce);\n }\n\n function _whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_bridgeSenderAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n function _setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) internal {\n destinationDomainIds[_bridgeSenderAdapter][_chainId] = _destinationDomainId;\n emit DestinationDomainIdSet(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n function _setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) internal {\n receivers[_bridgeSenderAdapter][_destinationDomainId] = _dataReceiver;\n emit ReceiverSet(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n modifier validatePool(bytes32 _poolSalt) {\n if (!_whitelistedPools.contains(_poolSalt)) revert UnallowedPool();\n _;\n }\n\n modifier validatePipeline(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) {\n uint24 _whitelistedNonce = whitelistedNonces[_chainId][_poolSalt];\n if (_whitelistedNonce == 0) revert UnallowedPipeline();\n if (_whitelistedNonce > _poolNonce) revert WrongNonce();\n _;\n }\n}\n" - }, - "solidity/interfaces/IDataFeed.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IPipelineManagement} from './peripherals/IPipelineManagement.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IConnextSenderAdapter} from './bridges/IConnextSenderAdapter.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IDataFeed is IPipelineManagement {\n // STRUCTS\n\n struct PoolState {\n uint24 poolNonce; // Nonce of the last observation\n uint32 blockTimestamp; // Last observed timestamp\n int56 tickCumulative; // Pool's tickCumulative at last observed timestamp\n int24 arithmeticMeanTick; // Last calculated twap\n }\n\n // STATE VARIABLES\n\n /// @return _strategy Address of the contract allowed to trigger an oracle update\n /// @dev The Strategy should define when and with which timestamps the pool should be read\n function strategy() external view returns (IDataFeedStrategy _strategy);\n\n /// @return _minLastOracleDelta Minimum timestamp delta between latest oracle observations\n function minLastOracleDelta() external view returns (uint32 _minLastOracleDelta);\n\n /// @notice Tracks the last observed pool state by salt\n /// @param _poolSalt The id of both the oracle and the pool\n /// @return _lastPoolNonceObserved Nonce of the last observation\n /// @return _lastBlockTimestampObserved Last observed timestamp\n /// @return _lastTickCumulativeObserved Pool's tickCumulative at last observed timestamp\n /// @return _lastArithmeticMeanTickObserved Last calculated twap\n function lastPoolStateObserved(bytes32 _poolSalt)\n external\n view\n returns (\n uint24 _lastPoolNonceObserved,\n uint32 _lastBlockTimestampObserved,\n int56 _lastTickCumulativeObserved,\n int24 _lastArithmeticMeanTickObserved\n );\n\n // EVENTS\n\n /// @notice Emitted when a data batch is broadcast\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _dataReceiver Address of the targeted contract receiving the data\n /// @param _chainId Identifier number of the targeted chain\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n event DataBroadcast(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n uint32 _chainId,\n address _dataReceiver,\n IBridgeSenderAdapter _bridgeSenderAdapter\n );\n\n /// @notice Emitted when a data batch is observed\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n /// @param _observationsData Timestamp and tick data of the broadcast nonce\n event PoolObserved(bytes32 indexed _poolSalt, uint24 indexed _poolNonce, IOracleSidechain.ObservationData[] _observationsData);\n\n /// @notice Emitted when the Strategy contract is set\n /// @param _strategy Address of the new Strategy\n event StrategySet(IDataFeedStrategy _strategy);\n\n /// @notice Emitted when minLastOracleDelta is set\n /// @param _minLastOracleDelta New value of minLastOracleDelta\n event MinLastOracleDeltaSet(uint32 _minLastOracleDelta);\n\n // ERRORS\n\n /// @notice Thrown if set of secondsAgos is invalid to update the oracle\n error InvalidSecondsAgos();\n\n /// @notice Thrown if the last oracle delta is less than minLastOracleDelta\n error InsufficientDelta();\n\n /// @notice Thrown if an unknown dataset is being broadcast\n error UnknownHash();\n\n /// @notice Thrown if a contract other than Strategy calls an update\n error OnlyStrategy();\n\n // FUNCTIONS\n\n /// @notice Broadcasts a validated set of datapoints to a bridge adapter\n /// @dev Permisionless, input parameters are validated to ensure being correct\n /// @param _bridgeSenderAdapter Address of the bridge adapter\n /// @param _chainId Identifier of the receiving chain\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _poolNonce Nonce identifier of the dataset\n /// @param _observationsData Array of tuples representing broadcast dataset\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external payable;\n\n /// @notice Triggers an update of the oracle state\n /// @dev Permisioned, callable only by Strategy\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _secondsAgos Set of time periods to consult the pool with\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external;\n\n /// @notice Sets the Strategy address\n /// @dev Permissioned, callable only by governor\n /// @param _strategy Address of the new Strategy\n function setStrategy(IDataFeedStrategy _strategy) external;\n\n /// @notice Sets the minLastOracleDelta value\n /// @dev Permissioned, callable only by governor\n /// @param _minLastOracleDelta New value of minLastOracleDelta\n function setMinLastOracleDelta(uint32 _minLastOracleDelta) external;\n\n /// @return _poolNonce The last observed nonce of the given pool\n function getPoolNonce(bytes32 _poolSalt) external view returns (uint24 _poolNonce);\n}\n" - }, - "@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.8 <0.9.0;\n\n/// @title Provides functions for deriving a UniswapV3Pool address from its factory, tokens and fee\nlibrary Create2Address {\n /// @notice Deterministically computes the pool address given the factory, salt and initCodeHash\n /// @param _factory The Uniswap V3 factory contract address\n /// @param _salt The PoolKey encoded bytes\n /// @param _initCodeHash The Init Code Hash of the target\n /// @return _pool The contract address of the target UniswapV3Pool\n function computeAddress(address _factory, bytes32 _salt, bytes32 _initCodeHash)\n internal\n pure\n returns (address _pool)\n {\n _pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', _factory, _salt, _initCodeHash)))));\n }\n}\n" - }, - "solidity/interfaces/peripherals/IPipelineManagement.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IBridgeSenderAdapter} from '../bridges/IBridgeSenderAdapter.sol';\n\ninterface IPipelineManagement is IGovernable {\n // STATE VARIABLES\n\n /// @notice Gets the whitelisted nonce of a pipeline\n /// @param _chainId Identifier number of the chain\n /// @param _poolSalt Identifier of the pool\n /// @return _whitelistedNonce The nonce of the observation from which the oracle is fed\n function whitelistedNonces(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _whitelistedNonce);\n\n /// @notice Returns whether a bridge sender adapter is whitelisted or not\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @return _isWhitelisted Whether the bridge sender adapter is whitelisted or not\n function whitelistedAdapters(IBridgeSenderAdapter _bridgeSenderAdapter) external view returns (bool _isWhitelisted);\n\n /// @notice Gets the destination domain id\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _chainId Identifier number of the chain\n /// @return _destinationDomainId Domain id of the destination chain\n function destinationDomainIds(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId) external view returns (uint32 _destinationDomainId);\n\n /// @notice Gets the address of the DataReceiver contract\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _destinationDomainId Domain id of the destination chain\n /// @return _dataReceiver Address of the DataReceiver contract\n function receivers(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId) external view returns (address _dataReceiver);\n\n // EVENTS\n\n /// @notice Emitted when a pipeline is whitelisted\n /// @param _chainId Identifier number of the chain\n /// @param _poolSalt Identifier of the pool\n /// @param _whitelistedNonce The nonce of the observation from which the oracle is fed\n event PipelineWhitelisted(uint32 _chainId, bytes32 indexed _poolSalt, uint24 _whitelistedNonce);\n\n /// @notice Emitted when the whitelist status of a bridge sender adapter is updated\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _isWhitelisted Whether the bridge sender adapter is whitelisted or not\n event AdapterWhitelisted(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted);\n\n /// @notice Emitted when a destination domain id is set\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _chainId Identifier number of the chain\n /// @param _destinationDomainId Domain id of the destination chain\n event DestinationDomainIdSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId, uint32 _destinationDomainId);\n\n /// @notice Emitted when a DataReceiver contract is set\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _destinationDomainId Domain id of the destination chain\n /// @param _dataReceiver Address of the DataReceiver contract\n event ReceiverSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId, address _dataReceiver);\n\n // ERRORS\n\n /// @notice Thrown if the pipeline is already whitelisted\n error AlreadyAllowedPipeline();\n\n /// @notice Thrown if the pool is not whitelisted\n error UnallowedPool();\n\n /// @notice Thrown if the pipeline is not whitelisted\n error UnallowedPipeline();\n\n /// @notice Thrown if the nonce is below the whitelisted nonce\n error WrongNonce();\n\n /// @notice Thrown if the bridge sender adapter is not whitelisted\n error UnallowedAdapter();\n\n /// @notice Thrown if the destination domain id is not set\n error DestinationDomainIdNotSet();\n\n /// @notice Thrown if the DataReceiver contract is not set\n error ReceiverNotSet();\n\n // FUNCTIONS\n\n /// @notice Whitelists a pipeline\n /// @param _chainId Identifier number of the chain\n /// @param _poolSalt Identifier of the pool\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external;\n\n /// @notice Whitelists several pipelines\n /// @param _chainIds Identifier number of each chain\n /// @param _poolSalts Identifier of each pool\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external;\n\n /// @notice Whitelists a bridge sender adapter\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _isWhitelisted Whether to whitelist the bridge sender adapter or not\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external;\n\n /// @notice Whitelists several bridge sender adapters\n /// @param _bridgeSenderAdapters Addresses of the bridge sender adapters\n /// @param _isWhitelisted Whether to whitelist each bridge sender adapter or not\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external;\n\n /// @notice Sets a destination domain id\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _chainId Identifier number of the chain\n /// @param _destinationDomainId Domain id of the destination chain\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external;\n\n /// @notice Sets several destination domain ids\n /// @param _bridgeSenderAdapters Addresses of the bridge sender adapters\n /// @param _chainIds Identifier number of each chain\n /// @param _destinationDomainIds Domain id of each destination chain\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _chainIds,\n uint32[] calldata _destinationDomainIds\n ) external;\n\n /// @notice Sets a DataReceiver contract\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _destinationDomainId Domain id of the destination chain\n /// @param _dataReceiver Address of the DataReceiver contract\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external;\n\n /// @notice Sets several DataReceiver contracts\n /// @param _bridgeSenderAdapters Addresses of the bridge sender adapters\n /// @param _destinationDomainIds Domain id of each destination chain\n /// @param _dataReceivers Address of each DataReceiver contract\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external;\n\n /// @notice Gets the salt of each whitelisted pool\n function whitelistedPools() external view returns (bytes32[] memory);\n\n /// @notice Gets the id of each whitelisted chain\n function whitelistedChains() external view returns (uint256[] memory);\n\n /// @notice Returns whether a pool is whitelisted or not\n /// @param _poolSalt Identifier of the pool\n /// @return _isWhitelisted Whether the pool is whitelisted or not\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n /// @notice Returns whether a pipeline is whitelisted or not\n /// @param _chainId Identifier number of the chain\n /// @param _poolSalt Identifier of the pool\n /// @return _isWhitelisted Whether the pipeline is whitelisted or not\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n /// @notice Validates whether a bridge sender adapter is set up for a particular chain\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _chainId Identifier number of the chain\n /// @return _destinationDomainId Domain id of the destination chain\n /// @return _dataReceiver Address of the DataReceiver contract\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n external\n view\n returns (uint32 _destinationDomainId, address _dataReceiver);\n}\n" - }, - "@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '../interfaces/IGovernable.sol';\n\n/// @title Governable contract\n/// @notice Manages the governor role\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public governor;\n\n /// @inheritdoc IGovernable\n address public pendingGovernor;\n\n constructor(address _governor) {\n if (_governor == address(0)) revert ZeroAddress();\n governor = _governor;\n }\n\n /// @inheritdoc IGovernable\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\n _setPendingGovernor(_pendingGovernor);\n }\n\n /// @inheritdoc IGovernable\n function acceptPendingGovernor() external onlyPendingGovernor {\n _acceptPendingGovernor();\n }\n\n function _setPendingGovernor(address _pendingGovernor) internal {\n if (_pendingGovernor == address(0)) revert ZeroAddress();\n pendingGovernor = _pendingGovernor;\n emit PendingGovernorSet(governor, _pendingGovernor);\n }\n\n function _acceptPendingGovernor() internal {\n governor = pendingGovernor;\n delete pendingGovernor;\n emit PendingGovernorAccepted(governor);\n }\n\n /// @notice Functions with this modifier can only be called by governor\n modifier onlyGovernor() {\n if (msg.sender != governor) revert OnlyGovernor();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernor\n modifier onlyPendingGovernor() {\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\n _;\n }\n}\n" - }, - "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 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 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 => 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 return _values(set._inner);\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 on 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" - }, - "solidity/interfaces/bridges/IBridgeSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeSenderAdapter {\n /// @notice Bridges observations across chains\n /// @param _to Address of the target contract to xcall\n /// @param _destinationDomainId Domain id of the destination chain\n /// @param _observationsData Array of tuples representing broadcast dataset\n /// @param _poolSalt Identifier of the pool\n /// @param _poolNonce Nonce identifier of the dataset\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable;\n}\n" - }, - "@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBaseErrors} from './IBaseErrors.sol';\n\n/// @title Governable interface\ninterface IGovernable is IBaseErrors {\n // STATE VARIABLES\n\n /// @return _governor Address of the current governor\n function governor() external view returns (address _governor);\n\n /// @return _pendingGovernor Address of the current pending governor\n function pendingGovernor() external view returns (address _pendingGovernor);\n\n // EVENTS\n\n /// @notice Emitted when a new pending governor is set\n /// @param _governor Address of the current governor\n /// @param _pendingGovernor Address of the proposed next governor\n event PendingGovernorSet(address _governor, address _pendingGovernor);\n\n /// @notice Emitted when a new governor is set\n /// @param _newGovernor Address of the new governor\n event PendingGovernorAccepted(address _newGovernor);\n\n // ERRORS\n\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\n error OnlyGovernor();\n\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\n error OnlyPendingGovernor();\n\n // FUNCTIONS\n\n /// @notice Allows a governor to propose a new governor\n /// @param _pendingGovernor Address of the proposed new governor\n function setPendingGovernor(address _pendingGovernor) external;\n\n /// @notice Allows a proposed governor to accept the governance\n function acceptPendingGovernor() external;\n}\n" - }, - "solidity/interfaces/IOracleSidechain.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleFactory} from './IOracleFactory.sol';\n\ninterface IOracleSidechain {\n // STRUCTS\n\n struct ObservationData {\n uint32 blockTimestamp;\n int24 tick;\n }\n\n // STATE VARIABLES\n\n /// @return _oracleFactory The address of the OracleFactory\n function factory() external view returns (IOracleFactory _oracleFactory);\n\n /// @return _token0 The mainnet address of the Token0 of the oracle\n function token0() external view returns (address _token0);\n\n /// @return _token1 The mainnet address of the Token1 of the oracle\n function token1() external view returns (address _token1);\n\n /// @return _fee The fee identifier of the pool\n function fee() external view returns (uint24 _fee);\n\n /// @return _poolSalt The identifier of both the pool and the oracle\n function poolSalt() external view returns (bytes32 _poolSalt);\n\n /// @return _poolNonce Last recorded nonce of the pool history\n function poolNonce() external view returns (uint24 _poolNonce);\n\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\n /// @return _tick Used to maintain compatibility with Uniswap V3\n /// @return _observationIndex The index of the last oracle observation that was written,\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\n /// @return _unlocked Used to track if a pool information was already verified\n function slot0()\n external\n view\n returns (\n uint160 _sqrtPriceX96,\n int24 _tick,\n uint16 _observationIndex,\n uint16 _observationCardinality,\n uint16 _observationCardinalityNext,\n uint8 _feeProtocol,\n bool _unlocked\n );\n\n /// @notice Returns data about a specific observation index\n /// @param _index The element of the observations array to fetch\n /// @return _blockTimestamp The timestamp of the observation,\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return _initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 _index)\n external\n view\n returns (\n uint32 _blockTimestamp,\n int56 _tickCumulative,\n uint160 _secondsPerLiquidityCumulativeX128,\n bool _initialized\n );\n\n // EVENTS\n\n /// @notice Emitted when the pool information is verified\n /// @param _poolSalt Identifier of the pool and the oracle\n /// @param _token0 The contract address of either token0 or token1\n /// @param _token1 The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\n\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param _tick The log base 1.0001 of price of the pool after the swap\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\n\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\n\n // ERRORS\n\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\n error AI();\n\n /// @notice Thrown if the pool info does not correspond to the pool salt\n error InvalidPool();\n\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\n error OnlyDataReceiver();\n\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\n error OnlyFactory();\n\n // FUNCTIONS\n\n /// @notice Permisionless method to verify token0, token1 and fee\n /// @dev Before verified, token0 and token1 views will return address(0)\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external;\n\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\n\n /// @notice Permisioned method to push a dataset to update\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolNonce Nonce of the observation broadcast\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\n\n /// @notice Permisioned method to increase the cardinalityNext value\n /// @param _observationCardinalityNext The new next length of the observations array\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\n}\n" - }, - "solidity/interfaces/IOracleFactory.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IDataReceiver} from './IDataReceiver.sol';\n\ninterface IOracleFactory is IGovernable {\n // STRUCTS\n\n struct OracleParameters {\n bytes32 poolSalt; // Identifier of the pool and oracle\n uint24 poolNonce; // Initial nonce of the deployed pool\n uint16 cardinality; // Initial cardinality of the deployed pool\n }\n\n // STATE VARIABLES\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /// @return _poolSalt The id of both the oracle and the pool\n /// @return _poolNonce The initial nonce of the pool data\n /// @return _cardinality The size of the observations memory storage\n function oracleParameters()\n external\n view\n returns (\n bytes32 _poolSalt,\n uint24 _poolNonce,\n uint16 _cardinality\n );\n\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function initialCardinality() external view returns (uint16 _initialCardinality);\n\n // EVENTS\n\n /// @notice Emitted when a new oracle is deployed\n /// @param _poolSalt The id of both the oracle and the pool\n /// @param _oracle The address of the deployed oracle\n /// @param _initialNonce The initial nonce of the pool data\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\n\n /// @notice Emitted when a new DataReceiver is set\n /// @param _dataReceiver The address of the new DataReceiver\n event DataReceiverSet(IDataReceiver _dataReceiver);\n\n /// @notice Emitted when a new initial oracle cardinality is set\n /// @param _initialCardinality The initial length of the observationCardinality array\n event InitialCardinalitySet(uint16 _initialCardinality);\n\n // ERRORS\n\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\n error OnlyDataReceiver();\n\n // FUNCTIONS\n\n /// @notice Deploys a new oracle given an inputted salt\n /// @dev Requires that the salt has not been deployed before\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\n /// @return _oracle The address of the newly deployed oracle\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\n\n /// @notice Allows governor to set a new allowed dataReceiver\n /// @dev Will disallow the previous dataReceiver\n /// @param _dataReceiver The address of the new allowed dataReceiver\n function setDataReceiver(IDataReceiver _dataReceiver) external;\n\n /// @notice Allows governor to set a new initial cardinality for new oracles\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function setInitialCardinality(uint16 _initialCardinality) external;\n\n /// @notice Overrides UniV3Factory getPool mapping\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _oracle The oracle address\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle);\n\n /// @notice Tracks the addresses of the oracle by poolSalt\n /// @param _poolSalt Identifier of both the pool and the oracle\n /// @return _oracle The address (if deployed) of the correspondant oracle\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\n\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _poolSalt Pool salt for inquired parameters\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (bytes32 _poolSalt);\n}\n" - }, - "solidity/interfaces/IDataReceiver.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IOracleFactory} from './IOracleFactory.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\n\ninterface IDataReceiver is IGovernable {\n // STATE VARIABLES\n\n /// @return _oracleFactory The address of the OracleFactory\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\n\n /// @notice Tracks already deployed oracles\n /// @param _poolSalt The identifier of the oracle\n /// @return _deployedOracle The address of the correspondant Oracle\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\n\n /// @notice Tracks the whitelisting of bridge adapters\n /// @param _adapter Address of the bridge adapter to consult\n /// @return _isAllowed Whether a bridge adapter is whitelisted\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\n\n // EVENTS\n\n /// @notice Emitted when a broadcast observation is succesfully processed\n /// @param _poolSalt Identifier of the pool to fetch\n /// @return _poolNonce Nonce of the observation broadcast\n /// @return _observationsData Array of tuples containing the dataset\n /// @return _receiverAdapter Handler of the broadcast\n event ObservationsAdded(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] _observationsData,\n address _receiverAdapter\n );\n\n /// @notice Emitted when a new adapter whitelisting rule is set\n /// @param _adapter Address of the adapter\n /// @param _isAllowed New whitelisting status\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\n\n // ERRORS\n\n /// @notice Thrown when the broadcast nonce is incorrect\n error ObservationsNotWritable();\n\n /// @notice Thrown when a not-whitelisted adapter triggers an update\n error UnallowedAdapter();\n\n // FUNCTIONS\n\n /// @notice Allows whitelisted bridge adapters to push a broadcast\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _poolNonce Nonce of the observation broadcast\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external;\n\n /// @notice Allows governance to set an adapter whitelisted state\n /// @param _receiverAdapter Address of the adapter\n /// @param _isWhitelisted New whitelisting status\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\n\n /// @notice Allows governance to batch set adapters whitelisted state\n /// @param _receiverAdapters Array of addresses of the adapter\n /// @param _isWhitelisted Array of whitelisting status for each address\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\nimport {IDataReceiver} from '../IDataReceiver.sol';\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeReceiverAdapter is IBaseErrors {\n // STATE VARIABLES\n\n /// @notice Gets the address of the DataReceiver contract\n /// @return _dataReceiver Address of the DataReceiver contract\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /* NOTE: callback methods should be here declared */\n}\n" - }, - "@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Thrown if an address is invalid\n error InvalidAddress();\n\n /// @notice Thrown if an amount is invalid\n error InvalidAmount();\n\n /// @notice Thrown if the lengths of a set of lists mismatch\n error LengthMismatch();\n\n /// @notice Thrown if an address is the zero address\n error ZeroAddress();\n\n /// @notice Thrown if an amount is zero\n error ZeroAmount();\n}\n" - }, - "solidity/interfaces/IDataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\n\ninterface IDataFeedStrategy is IGovernable {\n // ENUMS\n\n enum TriggerReason {\n NONE,\n TIME,\n TWAP,\n OLD\n }\n\n // STRUCTS\n\n struct StrategySettings {\n uint32 periodDuration; // Resolution of the oracle, target twap length\n uint32 strategyCooldown; // Time since last update to wait to time-trigger update\n uint24 defaultTwapThreshold; // Default twap difference, in ticks, to twap-trigger update\n uint32 twapLength; // Twap length, in seconds, used for twap-trigger update\n }\n\n // STATE VARIABLES\n\n /// @return _dataFeed The address of the DataFeed contract\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _periodDuration The targetted amount of seconds between pool consultations\n /// @dev Defines the resolution of the oracle, averaging data between consultations\n function periodDuration() external view returns (uint32 _periodDuration);\n\n /// @return _strategyCooldown Time in seconds since last update required to time-trigger an update\n function strategyCooldown() external view returns (uint32 _strategyCooldown);\n\n /// @return _defaultTwapThreshold Default twap difference, in ticks, to twap-trigger an update\n function defaultTwapThreshold() external view returns (uint24 _defaultTwapThreshold);\n\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _twapThreshold Twap difference, in ticks, to twap-trigger an update\n function twapThreshold(bytes32 _poolSalt) external view returns (uint24 _twapThreshold);\n\n /// @return _twapLength The time length, in seconds, used to calculate twap-trigger\n function twapLength() external view returns (uint32 _twapLength);\n\n // EVENTS\n\n /// @notice Emitted when a data fetch is triggered\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier number of the reason that triggered the fetch request\n event StrategicFetch(bytes32 indexed _poolSalt, TriggerReason _reason);\n\n /// @notice Emitted when the owner updates the job cooldown\n /// @param _strategyCooldown The new job cooldown\n event StrategyCooldownSet(uint32 _strategyCooldown);\n\n /// @notice Emitted when the owner updates the job default twap threshold percentage\n /// @param _defaultTwapThreshold The default twap difference threshold used to trigger an update of the oracle\n event DefaultTwapThresholdSet(uint24 _defaultTwapThreshold);\n\n /// @notice Emitted when the owner updates the job twap threshold percentage of a pool\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _twapThreshold The default twap difference threshold used to trigger an update of the oracle\n event TwapThresholdSet(bytes32 _poolSalt, uint24 _twapThreshold);\n\n /// @notice Emitted when the owner updates the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n event TwapLengthSet(uint32 _twapLength);\n\n /// @notice Emitted when the owner updates the job period length\n /// @param _periodDuration The new length of reading resolution periods\n event PeriodDurationSet(uint32 _periodDuration);\n\n // ERRORS\n\n /// @notice Thrown if the tx is not strategic\n error NotStrategic();\n\n /// @notice Thrown if setting breaks strategyCooldown >= twapLength >= periodDuration\n error WrongSetting();\n\n // FUNCTIONS\n\n /// @notice Permisionless, used to update the oracle state\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier of trigger reason (time/twap)\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external;\n\n /// @notice Sets the job cooldown\n /// @param _strategyCooldown The job cooldown to be set\n function setStrategyCooldown(uint32 _strategyCooldown) external;\n\n /// @notice Sets the job default twap threshold percentage\n /// @param _defaultTwapThreshold The default twap difference threshold used to trigger an update of the oracle\n function setDefaultTwapThreshold(uint24 _defaultTwapThreshold) external;\n\n /// @notice Sets the job twap threshold percentage of a pool\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n function setTwapThreshold(bytes32 _poolSalt, uint24 _twapThreshold) external;\n\n /// @notice Sets the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n function setTwapLength(uint32 _twapLength) external;\n\n /// @notice Sets the job period length\n /// @param _periodDuration The new length of reading resolution periods\n function setPeriodDuration(uint32 _periodDuration) external;\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the strategy can be executed\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason);\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the strategy can be executed\n /// @return _isStrategic Whether the tx is strategic or not\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) external view returns (bool _isStrategic);\n\n /// @notice Builds the secondsAgos array with periodDuration between each datapoint\n /// @param _fromSecondsAgo Seconds ago of the timestamp from which to backfill the oracle with\n /// @return _secondsAgos Array of secondsAgo that backfills the history from fromSecondsAgo\n function calculateSecondsAgos(uint32 _fromSecondsAgo) external view returns (uint32[] memory _secondsAgos);\n}\n" - }, - "solidity/interfaces/bridges/IConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeSenderAdapter, IOracleSidechain} from './IBridgeSenderAdapter.sol';\nimport {IDataFeed} from '../IDataFeed.sol';\n\ninterface IConnextSenderAdapter is IBaseErrors, IBridgeSenderAdapter {\n // STATE VARIABLES\n\n /// @notice Gets the address of the DataFeed contract\n /// @return _dataFeed Address of the DataFeed contract\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @notice Gets the ConnextHandler contract on this domain\n /// @return _connext Address of the ConnextHandler contract\n function connext() external view returns (IConnext _connext);\n\n // ERRORS\n\n /// @notice Thrown if the DataFeed contract is not the one calling for bridging observations\n error OnlyDataFeed();\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport {IUniswapV3PoolImmutables} from './pool/IUniswapV3PoolImmutables.sol';\nimport {IUniswapV3PoolState} from './pool/IUniswapV3PoolState.sol';\nimport {IUniswapV3PoolDerivedState} from './pool/IUniswapV3PoolDerivedState.sol';\nimport {IUniswapV3PoolActions} from './pool/IUniswapV3PoolActions.sol';\nimport {IUniswapV3PoolOwnerActions} from './pool/IUniswapV3PoolOwnerActions.sol';\nimport {IUniswapV3PoolErrors} from './pool/IUniswapV3PoolErrors.sol';\nimport {IUniswapV3PoolEvents} from './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolErrors,\n IUniswapV3PoolEvents\n{\n\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolErrors.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Errors emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolErrors {\n error LOK();\n error TLU();\n error TLM();\n error TUM();\n error AI();\n error M0();\n error M1();\n error AS();\n error IIA();\n error L();\n error F0();\n error F1();\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// @return tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// @return observationIndex The index of the last oracle observation that was written,\n /// @return observationCardinality The current maximum number of observations stored in the pool,\n /// @return observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n /// @return The liquidity at the current price of the pool\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper\n /// @return liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// @return feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// @return feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// @return tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// @return secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// @return secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// @return initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return liquidity The amount of liquidity in the position,\n /// @return feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// @return feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// @return tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// @return tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// @return tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {ExecuteArgs, TransferInfo, TokenId, DestinationTransferStatus} from \"../libraries/LibConnextStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {SwapUtils} from \"../libraries/SwapUtils.sol\";\n\nimport {IStableSwap} from \"./IStableSwap.sol\";\n\nimport {IDiamondCut} from \"./IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\ninterface IConnext is IDiamondLoupe, IDiamondCut {\n // TokenFacet\n function canonicalToAdopted(bytes32 _key) external view returns (address);\n\n function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\n\n function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\n\n function canonicalToRepresentation(bytes32 _key) external view returns (address);\n\n function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\n\n function representationToCanonical(address _adopted) external view returns (TokenId memory);\n\n function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\n\n function approvedAssets(bytes32 _key) external view returns (bool);\n\n function approvedAssets(TokenId calldata _canonical) external view returns (bool);\n\n function adoptedToLocalPools(bytes32 _key) external view returns (IStableSwap);\n\n function adoptedToLocalPools(TokenId calldata _canonical) external view returns (IStableSwap);\n\n function getTokenId(address _candidate) external view returns (TokenId memory);\n\n function setupAsset(\n TokenId calldata _canonical,\n uint8 _canonicalDecimals,\n string memory _representationName,\n string memory _representationSymbol,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function setupAssetWithDeployedRepresentation(\n TokenId calldata _canonical,\n address _representation,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\n\n function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\n\n function removeAssetId(\n bytes32 _key,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function removeAssetId(\n TokenId calldata _canonical,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function updateDetails(\n TokenId calldata _canonical,\n string memory _name,\n string memory _symbol\n ) external;\n\n // BaseConnextFacet\n\n // BridgeFacet\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\n\n function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\n\n function remote(uint32 _domain) external view returns (address);\n\n function domain() external view returns (uint256);\n\n function nonce() external view returns (uint256);\n\n function approvedSequencers(address _sequencer) external view returns (bool);\n\n function xAppConnectionManager() external view returns (address);\n\n function addConnextion(uint32 _domain, address _connext) external;\n\n function addSequencer(address _sequencer) external;\n\n function removeSequencer(address _sequencer) external;\n\n function xcall(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function xcallIntoLocal(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\n\n function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\n\n function bumpTransfer(bytes32 _transferId) external payable;\n\n function setXAppConnectionManager(address _xAppConnectionManager) external;\n\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n function enrollCustom(\n uint32 _domain,\n bytes32 _id,\n address _custom\n ) external;\n\n // InboxFacet\n\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external;\n\n // ProposedOwnableFacet\n\n function owner() external view returns (address);\n\n function routerWhitelistRemoved() external view returns (bool);\n\n function assetWhitelistRemoved() external view returns (bool);\n\n function proposed() external view returns (address);\n\n function proposedTimestamp() external view returns (uint256);\n\n function routerWhitelistTimestamp() external view returns (uint256);\n\n function assetWhitelistTimestamp() external view returns (uint256);\n\n function delay() external view returns (uint256);\n\n function proposeRouterWhitelistRemoval() external;\n\n function removeRouterWhitelist() external;\n\n function proposeAssetWhitelistRemoval() external;\n\n function removeAssetWhitelist() external;\n\n function renounced() external view returns (bool);\n\n function proposeNewOwner(address newlyProposed) external;\n\n function renounceOwnership() external;\n\n function acceptProposedOwner() external;\n\n function pause() external;\n\n function unpause() external;\n\n // RelayerFacet\n function approvedRelayers(address _relayer) external view returns (bool);\n\n function relayerFeeVault() external view returns (address);\n\n function setRelayerFeeVault(address _relayerFeeVault) external;\n\n function addRelayer(address _relayer) external;\n\n function removeRelayer(address _relayer) external;\n\n // RoutersFacet\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\n\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\n\n function getRouterApproval(address _router) external view returns (bool);\n\n function getRouterRecipient(address _router) external view returns (address);\n\n function getRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\n\n function maxRoutersPerTransfer() external view returns (uint256);\n\n function routerBalances(address _router, address _asset) external view returns (uint256);\n\n function getRouterApprovalForPortal(address _router) external view returns (bool);\n\n function setupRouter(\n address router,\n address owner,\n address recipient\n ) external;\n\n function removeRouter(address router) external;\n\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\n\n function setLiquidityFeeNumerator(uint256 _numerator) external;\n\n function approveRouterForPortal(address _router) external;\n\n function unapproveRouterForPortal(address _router) external;\n\n function setRouterRecipient(address router, address recipient) external;\n\n function proposeRouterOwner(address router, address proposed) external;\n\n function acceptProposedRouterOwner(address router) external;\n\n function addRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address _router\n ) external payable;\n\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\n\n function removeRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address payable _to,\n address _router\n ) external;\n\n function removeRouterLiquidity(\n uint256 _amount,\n address _local,\n address payable _to\n ) external;\n\n // PortalFacet\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\n\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\n\n function aavePool() external view returns (address);\n\n function aavePortalFee() external view returns (uint256);\n\n function setAavePool(address _aavePool) external;\n\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\n\n function repayAavePortal(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount,\n uint256 _maxIn\n ) external;\n\n function repayAavePortalFor(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount\n ) external;\n\n // StableSwapFacet\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\n\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\n\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\n\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\n\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\n\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\n\n function calculateSwap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapTokenAmount(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n bool deposit\n ) external view returns (uint256);\n\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) external view returns (uint256);\n\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\n\n function swap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n bytes32 canonicalId,\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n bytes32 canonicalId,\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function addSwapLiquidity(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidity(\n bytes32 canonicalId,\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidityImbalance(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n\n // SwapAdminFacet\n\n function initializeSwap(\n bytes32 _canonicalId,\n IERC20[] memory _pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 _a,\n uint256 _fee,\n uint256 _adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\n\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\n\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\n\n function rampA(\n bytes32 canonicalId,\n uint256 futureA,\n uint256 futureTime\n ) external;\n\n function stopRampA(bytes32 canonicalId) external;\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\nimport {IConnectorManager} from \"../../../messaging/interfaces/IConnectorManager.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n// ============= Enum =============\n\n/// @notice Enum representing address role\n// Returns uint\n// None - 0\n// Router - 1\n// Watcher - 2\n// Admin - 3\nenum Role {\n None,\n Router,\n Watcher,\n Admin\n}\n\n/**\n * @notice Enum representing status of destination transfer\n * @dev Status is only assigned on the destination domain, will always be \"none\" for the\n * origin domains\n * @return uint - Index of value in enum\n */\nenum DestinationTransferStatus {\n None, // 0\n Reconciled, // 1\n Executed, // 2\n Completed // 3 - executed + reconciled\n}\n\n// ============= Structs =============\n\nstruct TokenId {\n uint32 domain;\n bytes32 id;\n}\n\n/**\n * @notice These are the parameters that will remain constant between the\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\n * @property to - The account that receives funds, in the event of a crosschain call,\n * will receive funds if the call fails.\n *\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\n * @param canonicalDomain - The canonical domain of the asset you are bridging\n * @param to - The address you are sending funds (and potentially data) to\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\n * a user takes 1% slippage, this is expressed as 1_000)\n * @param originSender - The msg.sender of the xcall\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\n */\nstruct TransferInfo {\n uint32 originDomain;\n uint32 destinationDomain;\n uint32 canonicalDomain;\n address to;\n address delegate;\n bool receiveLocal;\n bytes callData;\n uint256 slippage;\n address originSender;\n uint256 bridgedAmt;\n uint256 normalizedIn;\n uint256 nonce;\n bytes32 canonicalId;\n}\n\n/**\n * @notice\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\n * @param routers - The routers who you are sending the funds on behalf of.\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\n * for the signed transfer ID.\n * @param sequencer - The sequencer who assigned the router path to this transfer.\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\n * for the path that was signed.\n */\nstruct ExecuteArgs {\n TransferInfo params;\n address[] routers;\n bytes[] routerSignatures;\n address sequencer;\n bytes sequencerSignature;\n}\n\n/**\n * @notice Contains RouterFacet related state\n * @param approvedRouters - Mapping of whitelisted router addresses\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\n * (if configured) or the router itself\n * @param routerOwners - Mapping of router owners\n * If set, can update the routerRecipient\n * @param proposedRouterOwners - Mapping of proposed router owners\n * Must wait timeout to set the\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\n * When accepting a proposed owner, must wait for delay to elapse\n */\nstruct RouterPermissionsManagerInfo {\n mapping(address => bool) approvedRouters;\n mapping(address => bool) approvedForPortalRouters;\n mapping(address => address) routerRecipients;\n mapping(address => address) routerOwners;\n mapping(address => address) proposedRouterOwners;\n mapping(address => uint256) proposedRouterTimestamp;\n}\n\nstruct AppStorage {\n //\n // 0\n bool initialized;\n //\n // Connext\n //\n // 1\n uint256 LIQUIDITY_FEE_NUMERATOR;\n /**\n * @notice The local address that is custodying relayer fees\n */\n // 2\n address relayerFeeVault;\n /**\n * @notice Nonce for the contract, used to keep unique transfer ids.\n * @dev Assigned at first interaction (xcall on origin domain).\n */\n // 3\n uint256 nonce;\n /**\n * @notice The domain this contract exists on.\n * @dev Must match the nomad domain, which is distinct from the \"chainId\".\n */\n // 4\n uint32 domain;\n /**\n * @notice Mapping holding the AMMs for swapping in and out of local assets.\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon).\n * This mapping is keyed on the hash of the canonical id + domain for local asset.\n */\n // 6\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\n /**\n * @notice Mapping of whitelisted assets on same domain as contract.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => bool) approvedAssets;\n /**\n * @notice Mapping of liquidity caps of whitelisted assets. If 0, no cap is enforced.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => uint256) caps;\n /**\n * @notice Mapping of adopted to canonical asset information.\n * @dev If the adopted asset is the native asset, the keyed address will\n * be the wrapped asset address.\n */\n // 8\n mapping(address => TokenId) adoptedToCanonical;\n /**\n * @notice Mapping of representation to canonical asset information.\n */\n // 9\n mapping(address => TokenId) representationToCanonical;\n /**\n * @notice Mapping of hash(canonicalId, canonicalDomain) to adopted asset on this domain.\n * @dev If the adopted asset is the native asset, the stored address will be the\n * wrapped asset address.\n */\n // 10\n mapping(bytes32 => address) canonicalToAdopted;\n /**\n * @notice Mapping of canonical to representation asset information.\n * @dev If the token is of local origin (meaning it was originanlly deployed on this chain),\n * this MUST map to address(0).\n */\n // 11\n mapping(bytes32 => address) canonicalToRepresentation;\n /**\n * @notice Mapping to track transfer status on destination domain\n */\n // 12\n mapping(bytes32 => DestinationTransferStatus) transferStatus;\n /**\n * @notice Mapping holding router address that provided fast liquidity.\n */\n // 13\n mapping(bytes32 => address[]) routedTransfers;\n /**\n * @notice Mapping of router to available balance of an asset.\n * @dev Routers should always store liquidity that they can expect to receive via the bridge on\n * this domain (the nomad local asset).\n */\n // 14\n mapping(address => mapping(address => uint256)) routerBalances;\n /**\n * @notice Mapping of approved relayers\n * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\n */\n // 15\n mapping(address => bool) approvedRelayers;\n /**\n * @notice The max amount of routers a payment can be routed through.\n */\n // 18\n uint256 maxRoutersPerTransfer;\n /**\n * @notice Stores a mapping of transfer id to slippage overrides.\n */\n // 20\n mapping(bytes32 => uint256) slippage;\n /**\n * @notice Stores a mapping of remote routers keyed on domains.\n * @dev Addresses are cast to bytes32.\n * This mapping is required because the Connext now contains the BridgeRouter and must implement\n * the remotes interface.\n */\n // 21\n mapping(uint32 => bytes32) remotes;\n //\n // ProposedOwnable\n //\n // 22\n address _proposed;\n // 23\n uint256 _proposedOwnershipTimestamp;\n // 24\n bool _routerWhitelistRemoved;\n // 25\n uint256 _routerWhitelistTimestamp;\n // 26\n bool _assetWhitelistRemoved;\n // 27\n uint256 _assetWhitelistTimestamp;\n /**\n * @notice Stores a mapping of address to Roles\n * @dev returns uint representing the enum Role value\n */\n // 28\n mapping(address => Role) roles;\n //\n // RouterFacet\n //\n // 29\n RouterPermissionsManagerInfo routerPermissionInfo;\n //\n // ReentrancyGuard\n //\n // 30\n uint256 _status;\n //\n // StableSwap\n //\n /**\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\n * Struct storing data responsible for automatic market maker functionalities. In order to\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\n */\n // 31\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\n /**\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\n */\n // 32\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\n /**\n * @notice Stores whether or not bribing, AMMs, have been paused.\n */\n // 33\n bool _paused;\n //\n // AavePortals\n //\n /**\n * @notice Address of Aave Pool contract.\n */\n // 34\n address aavePool;\n /**\n * @notice Fee percentage numerator for using Portal liquidity.\n * @dev Assumes the same basis points as the liquidity fee.\n */\n // 35\n uint256 aavePortalFeeNumerator;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 36\n mapping(bytes32 => uint256) portalDebt;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 37\n mapping(bytes32 => uint256) portalFeeDebt;\n /**\n * @notice Mapping of approved sequencers\n * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\n * for the fast liquidity route.\n */\n // 38\n mapping(address => bool) approvedSequencers;\n /**\n * @notice Remote connection manager for xapp.\n */\n // 39\n IConnectorManager xAppConnectionManager;\n}\n\nlibrary LibConnextStorage {\n function connextStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= 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 > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20, IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {LPToken} from \"../helpers/LPToken.sol\";\n\nimport {AmplificationUtils} from \"./AmplificationUtils.sol\";\nimport {MathUtils} from \"./MathUtils.sol\";\n\n/**\n * @title SwapUtils library\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\n * Admin functions should be protected within contracts using this library.\n */\nlibrary SwapUtils {\n using SafeERC20 for IERC20;\n using MathUtils for uint256;\n\n /*** EVENTS ***/\n\n event TokenSwap(\n bytes32 indexed key,\n address indexed buyer,\n uint256 tokensSold,\n uint256 tokensBought,\n uint128 soldId,\n uint128 boughtId\n );\n event AddLiquidity(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n bytes32 indexed key,\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\n event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\n\n struct Swap {\n // variables around the ramp management of A,\n // the amplification coefficient * n * (n - 1)\n // see https://www.curve.fi/stableswap-paper.pdf for details\n bytes32 key;\n uint256 initialA;\n uint256 futureA;\n uint256 initialATime;\n uint256 futureATime;\n // fee calculation\n uint256 swapFee;\n uint256 adminFee;\n LPToken lpToken;\n // contract references for all tokens being pooled\n IERC20[] pooledTokens;\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\n uint256[] tokenPrecisionMultipliers;\n // the pool balance of each token, in the token's precision\n // the contract's actual token balance might differ\n uint256[] balances;\n // the admin fee balance of each token, in the token's precision\n uint256[] adminFees;\n }\n\n // Struct storing variables used in calculations in the\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\n struct CalculateWithdrawOneTokenDYInfo {\n uint256 d0;\n uint256 d1;\n uint256 newY;\n uint256 feePerToken;\n uint256 preciseA;\n }\n\n // Struct storing variables used in calculations in the\n // {add,remove}Liquidity functions to avoid stack too deep errors\n struct ManageLiquidityInfo {\n uint256 d0;\n uint256 d1;\n uint256 d2;\n uint256 preciseA;\n LPToken lpToken;\n uint256 totalSupply;\n uint256[] balances;\n uint256[] multipliers;\n }\n\n // the precision all pools tokens will be converted to\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\n\n // the denominator used to calculate admin and LP fees. For example, an\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\n uint256 internal constant FEE_DENOMINATOR = 1e10;\n\n // Max swap fee is 1% or 100bps of each swap\n uint256 internal constant MAX_SWAP_FEE = 1e8;\n\n // Max adminFee is 100% of the swapFee\n // adminFee does not add additional fee on top of swapFee\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\n // users but only on the earnings of LPs\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\n\n // Constant value used as max loop limit\n uint256 internal constant MAX_LOOP_LIMIT = 256;\n\n /*** VIEW & PURE FUNCTIONS ***/\n\n function _getAPrecise(Swap storage self) private view returns (uint256) {\n return AmplificationUtils._getAPrecise(self);\n }\n\n /**\n * @notice Calculate the dy, the amount of selected token that user receives and\n * the fee of withdrawing in one token\n * @param tokenAmount the amount to withdraw in the pool's precision\n * @param tokenIndex which token will be withdrawn\n * @param self Swap struct to read from\n * @return the amount of token user will receive\n */\n function calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) internal view returns (uint256) {\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\n self,\n tokenAmount,\n tokenIndex,\n self.lpToken.totalSupply()\n );\n return availableTokenAmount;\n }\n\n function _calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 totalSupply\n ) private view returns (uint256, uint256) {\n uint256 dy;\n uint256 newY;\n uint256 currentY;\n\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\n\n // dy_0 (without fees)\n // dy, dy_0 - dy\n\n uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\n\n return (dy, dySwapFee);\n }\n\n /**\n * @notice Calculate the dy of withdrawing in one token\n * @param self Swap struct to read from\n * @param tokenIndex which token will be withdrawn\n * @param tokenAmount the amount to withdraw in the pools precision\n * @return the d and the new y after withdrawing one token\n */\n function calculateWithdrawOneTokenDY(\n Swap storage self,\n uint8 tokenIndex,\n uint256 tokenAmount,\n uint256 totalSupply\n )\n internal\n view\n returns (\n uint256,\n uint256,\n uint256\n )\n {\n // Get the current D, then solve the stableswap invariant\n // y_i for D - tokenAmount\n uint256[] memory xp = _xp(self);\n\n require(tokenIndex < xp.length, \"index out of range\");\n\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\n v.preciseA = _getAPrecise(self);\n v.d0 = getD(xp, v.preciseA);\n v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\n\n require(tokenAmount <= xp[tokenIndex], \"exceeds available\");\n\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\n\n uint256[] memory xpReduced = new uint256[](xp.length);\n\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\n for (uint256 i; i < xp.length; ) {\n uint256 xpi = xp[i];\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\n xpReduced[i] =\n xpi -\n ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\n FEE_DENOMINATOR);\n\n unchecked {\n ++i;\n }\n }\n\n uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\n dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\n\n return (dy, v.newY, xp[tokenIndex]);\n }\n\n /**\n * @notice Calculate the price of a token in the pool with given\n * precision-adjusted balances and a particular D.\n *\n * @dev This is accomplished via solving the invariant iteratively.\n * See the StableSwap paper and Curve.fi implementation for further details.\n *\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\n * x_1**2 + b*x_1 = c\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\n *\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\n * @param tokenIndex Index of token we are calculating for.\n * @param xp a precision-adjusted set of pool balances. Array should be\n * the same cardinality as the pool.\n * @param d the stableswap invariant\n * @return the price of the token, in the same precision as in xp\n */\n function getYD(\n uint256 a,\n uint8 tokenIndex,\n uint256[] memory xp,\n uint256 d\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndex < numTokens, \"Token not found\");\n\n uint256 c = d;\n uint256 s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < numTokens; ) {\n if (i != tokenIndex) {\n s += xp[i];\n c = (c * d) / (xp[i] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n }\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\n * as the pool.\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\n * See the StableSwap paper for details\n * @return the invariant, at the precision of the pool\n */\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n uint256 s;\n for (uint256 i; i < numTokens; ) {\n s += xp[i];\n\n unchecked {\n ++i;\n }\n }\n if (s == 0) {\n return 0;\n }\n\n uint256 prevD;\n uint256 d = s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n uint256 dP = d;\n for (uint256 j; j < numTokens; ) {\n dP = (dP * d) / (xp[j] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // dP = dP * D * D * D * ... overflow!\n\n unchecked {\n ++j;\n }\n }\n prevD = d;\n d =\n (((nA * s) / AmplificationUtils.A_PRECISION + dP * numTokens) * d) /\n ((((nA - AmplificationUtils.A_PRECISION) * d) / AmplificationUtils.A_PRECISION + (numTokens + 1) * dP));\n if (d.within1(prevD)) {\n return d;\n }\n\n unchecked {\n ++i;\n }\n }\n\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\n // function which does not rely on D.\n revert(\"D does not converge\");\n }\n\n /**\n * @notice Given a set of balances and precision multipliers, return the\n * precision-adjusted balances.\n *\n * @param balances an array of token balances, in their native precisions.\n * These should generally correspond with pooled tokens.\n *\n * @param precisionMultipliers an array of multipliers, corresponding to\n * the amounts in the balances array. When multiplied together they\n * should yield amounts at the pool's precision.\n *\n * @return an array of amounts \"scaled\" to the pool's precision\n */\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\n internal\n pure\n returns (uint256[] memory)\n {\n uint256 numTokens = balances.length;\n require(numTokens == precisionMultipliers.length, \"mismatch multipliers\");\n uint256[] memory xp = new uint256[](numTokens);\n for (uint256 i; i < numTokens; ) {\n xp[i] = balances[i] * precisionMultipliers[i];\n\n unchecked {\n ++i;\n }\n }\n return xp;\n }\n\n /**\n * @notice Return the precision-adjusted balances of all tokens in the pool\n * @param self Swap struct to read from\n * @return the pool balances \"scaled\" to the pool's precision, allowing\n * them to be more easily compared.\n */\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\n return _xp(self.balances, self.tokenPrecisionMultipliers);\n }\n\n /**\n * @notice Get the virtual price, to help calculate profit\n * @param self Swap struct to read from\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\n */\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\n uint256 d = getD(_xp(self), _getAPrecise(self));\n LPToken lpToken = self.lpToken;\n uint256 supply = lpToken.totalSupply();\n if (supply != 0) {\n return (d * (10**uint256(POOL_PRECISION_DECIMALS))) / supply;\n }\n return 0;\n }\n\n /**\n * @notice Calculate the new balances of the tokens given the indexes of the token\n * that is swapped from (FROM) and the token that is swapped to (TO).\n * This function is used as a helper function to calculate how much TO token\n * the user should receive on swap.\n *\n * @param preciseA precise form of amplification coefficient\n * @param tokenIndexFrom index of FROM token\n * @param tokenIndexTo index of TO token\n * @param x the new total amount of FROM token\n * @param xp balances of the tokens in the pool\n * @return the amount of TO token that should remain in the pool\n */\n function getY(\n uint256 preciseA,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 x,\n uint256[] memory xp\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \"token not found\");\n\n uint256 d = getD(xp, preciseA);\n uint256 c = d;\n uint256 s;\n uint256 nA = numTokens * preciseA;\n\n uint256 _x;\n for (uint256 i; i < numTokens; ) {\n if (i == tokenIndexFrom) {\n _x = x;\n } else if (i != tokenIndexTo) {\n _x = xp[i];\n } else {\n unchecked {\n ++i;\n }\n continue;\n }\n s += _x;\n c = (c * d) / (_x * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n\n // iterative approximation\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get\n */\n function calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) internal view returns (uint256 dy) {\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy.\n * @return dx the number of tokens the user have to transfer + fee\n */\n function calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) internal view returns (uint256 dx) {\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\n * @return dyFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256[] memory balances\n ) internal view returns (uint256 dy, uint256 dyFee) {\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\n dy = xp[tokenIndexTo] - y - 1;\n dyFee = (dy * self.swapFee) / FEE_DENOMINATOR;\n dy = (dy - dyFee) / multipliers[tokenIndexTo];\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\n * @return dxFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256[] memory balances\n ) internal view returns (uint256 dx, uint256 dxFee) {\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n\n uint256 a = _getAPrecise(self);\n uint256 d0 = getD(xp, a);\n\n xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\n dx = x - xp[tokenIndexFrom] + 1;\n dxFee = (dx * self.swapFee) / FEE_DENOMINATOR;\n dx = (dx + dxFee) / multipliers[tokenIndexFrom];\n }\n\n /**\n * @notice A simple method to calculate amount of each underlying\n * tokens that is returned upon burning given amount of\n * LP tokens\n *\n * @param amount the amount of LP tokens that would to be burned on\n * withdrawal\n * @return array of amounts of tokens user will receive\n */\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\n }\n\n function _calculateRemoveLiquidity(\n uint256[] memory balances,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (uint256[] memory) {\n require(amount <= totalSupply, \"exceed total supply\");\n\n uint256 numBalances = balances.length;\n uint256[] memory amounts = new uint256[](numBalances);\n\n for (uint256 i; i < numBalances; ) {\n amounts[i] = (balances[i] * amount) / totalSupply;\n\n unchecked {\n ++i;\n }\n }\n return amounts;\n }\n\n /**\n * @notice A simple method to calculate prices from deposits or\n * withdrawals, excluding fees but including slippage. This is\n * helpful as an input into the various \"min\" parameters on calls\n * to fight front-running\n *\n * @dev This shouldn't be used outside frontends for user estimates.\n *\n * @param self Swap struct to read from\n * @param amounts an array of token amounts to deposit or withdrawal,\n * corresponding to pooledTokens. The amount should be in each\n * pooled token's native precision. If a token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @param deposit whether this is a deposit or a withdrawal\n * @return if deposit was true, total amount of lp token that will be minted and if\n * deposit was false, total amount of lp token that will be burned\n */\n function calculateTokenAmount(\n Swap storage self,\n uint256[] calldata amounts,\n bool deposit\n ) internal view returns (uint256) {\n uint256 a = _getAPrecise(self);\n uint256[] memory balances = self.balances;\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n\n uint256 numBalances = balances.length;\n uint256 d0 = getD(_xp(balances, multipliers), a);\n for (uint256 i; i < numBalances; ) {\n if (deposit) {\n balances[i] = balances[i] + amounts[i];\n } else {\n balances[i] = balances[i] - amounts[i];\n }\n\n unchecked {\n ++i;\n }\n }\n uint256 d1 = getD(_xp(balances, multipliers), a);\n uint256 totalSupply = self.lpToken.totalSupply();\n\n if (deposit) {\n return ((d1 - d0) * totalSupply) / d0;\n } else {\n return ((d0 - d1) * totalSupply) / d0;\n }\n }\n\n /**\n * @notice return accumulated amount of admin fees of the token with given index\n * @param self Swap struct to read from\n * @param index Index of the pooled token\n * @return admin balance in the token's precision\n */\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\n require(index < self.pooledTokens.length, \"index out of range\");\n return self.adminFees[index];\n }\n\n /**\n * @notice internal helper function to calculate fee per token multiplier used in\n * swap fee calculations\n * @param swapFee swap fee for the tokens\n * @param numTokens number of tokens pooled\n */\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\n return (swapFee * numTokens) / ((numTokens - 1) * 4);\n }\n\n /*** STATE MODIFYING FUNCTIONS ***/\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"swap more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"no fee token support\");\n }\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dy the amount of tokens the user wants to buy\n * @param maxDx the max amount the user would like to send.\n * @return amount of token user have to transfer on swap\n */\n function swapOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \">pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"not support fee token\");\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice swap two tokens in the pool internally\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swapInternal(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n require(dx <= self.balances[tokenIndexFrom], \"more than pool balance\");\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice Should get exact amount out of AMM for asset put in\n */\n function swapInternalOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \"more than pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice Add liquidity to the pool\n * @param self Swap struct to read from and write to\n * @param amounts the amounts of each token to add, in their native precision\n * @param minToMint the minimum LP tokens adding this amount of liquidity\n * should mint, otherwise revert. Handy for front-running mitigation\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\n * @return amount of LP token user received\n */\n function addLiquidity(\n Swap storage self,\n uint256[] memory amounts,\n uint256 minToMint\n ) internal returns (uint256) {\n uint256 numTokens = self.pooledTokens.length;\n require(amounts.length == numTokens, \"mismatch pooled tokens\");\n\n // current state\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n if (v.totalSupply != 0) {\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n }\n\n uint256[] memory newBalances = new uint256[](numTokens);\n\n for (uint256 i; i < numTokens; ) {\n require(v.totalSupply != 0 || amounts[i] != 0, \"!supply all tokens\");\n\n // Transfer tokens first to see if a fee was charged on transfer\n if (amounts[i] != 0) {\n IERC20 token = self.pooledTokens[i];\n uint256 beforeBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), amounts[i]);\n\n // Update the amounts[] with actual transfer amount\n amounts[i] = token.balanceOf(address(this)) - beforeBalance;\n }\n\n newBalances[i] = v.balances[i] + amounts[i];\n\n unchecked {\n ++i;\n }\n }\n\n // invariant after change\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n require(v.d1 > v.d0, \"D should increase\");\n\n // updated to reflect fees and calculate the user's LP tokens\n v.d2 = v.d1;\n uint256[] memory fees = new uint256[](numTokens);\n\n if (v.totalSupply != 0) {\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n for (uint256 i; i < numTokens; ) {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / FEE_DENOMINATOR;\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = newBalances[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n newBalances[i] = newBalances[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n } else {\n // the initial depositor doesn't pay fees\n self.balances = newBalances;\n }\n\n uint256 toMint;\n if (v.totalSupply == 0) {\n toMint = v.d1;\n } else {\n toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\n }\n\n require(toMint >= minToMint, \"mint < min\");\n\n // mint the user's LP tokens\n v.lpToken.mint(msg.sender, toMint);\n\n emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\n\n return toMint;\n }\n\n /**\n * @notice Burn LP tokens to remove liquidity from the pool.\n * @dev Liquidity can always be removed, even when the pool is paused.\n * @param self Swap struct to read from and write to\n * @param amount the amount of LP tokens to burn\n * @param minAmounts the minimum amounts of each token in the pool\n * acceptable for this burn. Useful as a front-running mitigation\n * @return amounts of tokens the user received\n */\n function removeLiquidity(\n Swap storage self,\n uint256 amount,\n uint256[] calldata minAmounts\n ) internal returns (uint256[] memory) {\n LPToken lpToken = self.lpToken;\n require(amount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(minAmounts.length == numTokens, \"mismatch poolTokens\");\n\n uint256[] memory balances = self.balances;\n uint256 totalSupply = lpToken.totalSupply();\n\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\n\n uint256 numAmounts = amounts.length;\n for (uint256 i; i < numAmounts; ) {\n require(amounts[i] >= minAmounts[i], \"amounts[i] < minAmounts[i]\");\n self.balances[i] = balances[i] - amounts[i];\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n lpToken.burnFrom(msg.sender, amount);\n\n emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\n\n return amounts;\n }\n\n /**\n * @notice Remove liquidity from the pool all in one token.\n * @param self Swap struct to read from and write to\n * @param tokenAmount the amount of the lp tokens to burn\n * @param tokenIndex the index of the token you want to receive\n * @param minAmount the minimum amount to withdraw, otherwise revert\n * @return amount chosen token that user received\n */\n function removeLiquidityOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount\n ) internal returns (uint256) {\n LPToken lpToken = self.lpToken;\n\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(tokenIndex < numTokens, \"not found\");\n\n uint256 totalSupply = lpToken.totalSupply();\n\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\n\n require(dy >= minAmount, \"dy < minAmount\");\n\n uint256 adminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR;\n self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\n if (adminFee != 0) {\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\n }\n lpToken.burnFrom(msg.sender, tokenAmount);\n self.pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\n\n emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\n\n return dy;\n }\n\n /**\n * @notice Remove liquidity from the pool, weighted differently than the\n * pool's current balances.\n *\n * @param self Swap struct to read from and write to\n * @param amounts how much of each token to withdraw\n * @param maxBurnAmount the max LP token provider is willing to pay to\n * remove liquidity. Useful as a front-running mitigation.\n * @return actual amount of LP tokens burned in the withdrawal\n */\n function removeLiquidityImbalance(\n Swap storage self,\n uint256[] memory amounts,\n uint256 maxBurnAmount\n ) internal returns (uint256) {\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n\n uint256 numTokens = self.pooledTokens.length;\n uint256 numAmounts = amounts.length;\n require(numAmounts == numTokens, \"mismatch pool tokens\");\n\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \">LP.balanceOf\");\n\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n uint256[] memory fees = new uint256[](numTokens);\n {\n uint256[] memory balances1 = new uint256[](numTokens);\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n for (uint256 i; i < numTokens; ) {\n require(v.balances[i] >= amounts[i], \"withdraw more than available\");\n\n unchecked {\n balances1[i] = v.balances[i] - amounts[i];\n ++i;\n }\n }\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\n\n for (uint256 i; i < numTokens; ) {\n {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n uint256 difference = idealBalance.difference(balances1[i]);\n fees[i] = (feePerToken * difference) / FEE_DENOMINATOR;\n }\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = balances1[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n balances1[i] = balances1[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\n }\n uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\n require(tokenAmount != 0, \"!zero amount\");\n tokenAmount = tokenAmount + 1;\n\n require(tokenAmount <= maxBurnAmount, \"tokenAmount > maxBurnAmount\");\n\n v.lpToken.burnFrom(msg.sender, tokenAmount);\n\n for (uint256 i; i < numTokens; ) {\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\n\n return tokenAmount;\n }\n\n /**\n * @notice withdraw all admin fees to a given address\n * @param self Swap struct to withdraw fees from\n * @param to Address to send the fees to\n */\n function withdrawAdminFees(Swap storage self, address to) internal {\n uint256 numTokens = self.pooledTokens.length;\n for (uint256 i; i < numTokens; ) {\n IERC20 token = self.pooledTokens[i];\n uint256 balance = self.adminFees[i];\n if (balance != 0) {\n self.adminFees[i] = 0;\n token.safeTransfer(to, balance);\n }\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Sets the admin fee\n * @dev adminFee cannot be higher than 100% of the swap fee\n * @param self Swap struct to update\n * @param newAdminFee new admin fee to be applied on future transactions\n */\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\n require(newAdminFee <= MAX_ADMIN_FEE, \"too high\");\n self.adminFee = newAdminFee;\n\n emit NewAdminFee(self.key, newAdminFee);\n }\n\n /**\n * @notice update the swap fee\n * @dev fee cannot be higher than 1% of each swap\n * @param self Swap struct to update\n * @param newSwapFee new swap fee to be applied on future transactions\n */\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\n require(newSwapFee <= MAX_SWAP_FEE, \"too high\");\n self.swapFee = newSwapFee;\n\n emit NewSwapFee(self.key, newSwapFee);\n }\n\n /**\n * @notice Check if this stableswap pool exists and is valid (i.e. has been\n * initialized and tokens have been added).\n * @return bool true if this stableswap pool is valid, false if not.\n */\n function exists(Swap storage self) internal view returns (bool) {\n return self.pooledTokens.length != 0;\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n // hash of proposed facets => acceptance time\n mapping(bytes32 => uint256) acceptanceTimes;\n // acceptance delay for upgrading facets\n uint256 acceptanceDelay;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function acceptanceDelay() internal view returns (uint256) {\n return diamondStorage().acceptanceDelay;\n }\n\n function acceptanceTime(bytes32 _key) internal view returns (uint256) {\n return diamondStorage().acceptanceTimes[_key];\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, \"LibDiamond: !contract owner\");\n }\n\n event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n function proposeDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 acceptance = block.timestamp + ds.acceptanceDelay;\n ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\n emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\n }\n\n event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n function rescindDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\n // period or befor the delay elpases\n diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = 0;\n emit DiamondCutRescinded(_diamondCut, _init, _calldata);\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n if (ds.facetAddresses.length != 0) {\n uint256 time = ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\n require(time != 0 && time <= block.timestamp, \"LibDiamond: delay not elapsed\");\n } // Otherwise, this is the first instance of deployment and it can be set automatically\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress != _facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, \"LibDiamondCut: New facet has no code\");\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n require(_calldata.length == 0, \"LibDiamondCut: _init is address(0) but_calldata is not empty\");\n } else {\n require(_calldata.length != 0, \"LibDiamondCut: _calldata is empty but _init is not address(0)\");\n if (_init != address(this)) {\n enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");\n }\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length != 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize != 0, _errorMessage);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IStableSwap {\n /*** EVENTS ***/\n\n // events replicated from SwapUtils to make the ABI easier for dumb\n // clients\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\n event AddLiquidity(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(uint256 newAdminFee);\n event NewSwapFee(uint256 newSwapFee);\n event NewWithdrawFee(uint256 newWithdrawFee);\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n function swap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function getA() external view returns (uint256);\n\n function getToken(uint8 index) external view returns (IERC20);\n\n function getTokenIndex(address tokenAddress) external view returns (uint8);\n\n function getTokenBalance(uint8 index) external view returns (uint256);\n\n function getVirtualPrice() external view returns (uint256);\n\n // min return calculation functions\n function calculateSwap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapOut(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) external view returns (uint256);\n\n function calculateSwapFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountIn\n ) external view returns (uint256);\n\n function calculateSwapOutFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountOut\n ) external view returns (uint256);\n\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\n\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\n external\n view\n returns (uint256 availableTokenAmount);\n\n // state modifying functions\n function initialize(\n IERC20[] memory pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 a,\n uint256 fee,\n uint256 adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function addLiquidity(\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidity(\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeLiquidityOneToken(\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidityImbalance(\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function proposeDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function rescindDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\nimport {IOutbox} from \"./IOutbox.sol\";\n\n/**\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\n * allows an admin to call `setXAppConnectionManager` to update the underlying\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\n *\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\n * will interface with.\n */\ninterface IConnectorManager {\n /**\n * @notice Get the local inbox contract from the xAppConnectionManager\n * @return The local inbox contract\n * @dev The local inbox contract is a SpokeConnector with AMBs, and a\n * Home contract with nomad\n */\n function home() external view returns (IOutbox);\n\n /**\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\n * @return True if _potentialReplica is an enrolled Replica\n */\n function isReplica(address _potentialReplica) external view returns (bool);\n\n /**\n * @notice Get the local domain from the xAppConnectionManager\n * @return The local domain\n */\n function localDomain() external view returns (uint32);\n}\n" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\n/**\n * @notice Interface for all contracts sending messages originating on their\n * current domain.\n *\n * @dev These are the Home.sol interface methods used by the `Router`\n * and exposed via `home()` on the `XAppConnectionClient`\n */\ninterface IOutbox {\n /**\n * @notice Emitted when a new message is added to an outbound message merkle root\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination << 32) & nonce)\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\n * @param committedRoot the latest notarized root submitted in the last signed Update\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes32 committedRoot,\n bytes message\n );\n\n /**\n * @notice Dispatch the message it to the destination domain & recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n * @return bytes32 The leaf added to the tree\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n bytes memory _messageBody\n ) external returns (bytes32);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n/**\n * @title AmplificationUtils library\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\n * This library assumes the struct is fully validated.\n */\nlibrary AmplificationUtils {\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n // Constant values used in ramping A calculations\n uint256 public constant A_PRECISION = 100;\n uint256 public constant MAX_A = 10**6;\n uint256 private constant MAX_A_CHANGE = 2;\n uint256 private constant MIN_RAMP_TIME = 14 days;\n\n /**\n * @notice Return A, the amplification coefficient * n * (n - 1)\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter\n */\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self) / A_PRECISION;\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self);\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n uint256 t1 = self.futureATime; // time when ramp is finished\n uint256 a1 = self.futureA; // final A value when ramp is finished\n\n if (block.timestamp < t1) {\n uint256 t0 = self.initialATime; // time when ramp is started\n uint256 a0 = self.initialA; // initial A value when ramp is started\n if (a1 > a0) {\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\n return a0 + ((a1 - a0) * (block.timestamp - t0)) / (t1 - t0);\n } else {\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\n return a0 - ((a0 - a1) * (block.timestamp - t0)) / (t1 - t0);\n }\n } else {\n return a1;\n }\n }\n\n /**\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\n * Checks if the change is too rapid, and commits the new A value only when it falls under\n * the limit range.\n * @param self Swap struct to update\n * @param futureA_ the new A to ramp towards\n * @param futureTime_ timestamp when the new A should be reached\n */\n function rampA(\n SwapUtils.Swap storage self,\n uint256 futureA_,\n uint256 futureTime_\n ) internal {\n require(block.timestamp >= self.initialATime + 1 days, \"Wait 1 day before starting ramp\");\n require(futureTime_ >= block.timestamp + MIN_RAMP_TIME, \"Insufficient ramp time\");\n require(futureA_ != 0 && futureA_ < MAX_A, \"futureA_ must be > 0 and < MAX_A\");\n\n uint256 initialAPrecise = _getAPrecise(self);\n uint256 futureAPrecise = futureA_ * A_PRECISION;\n\n if (futureAPrecise < initialAPrecise) {\n require(futureAPrecise * MAX_A_CHANGE >= initialAPrecise, \"futureA_ is too small\");\n } else {\n require(futureAPrecise <= initialAPrecise * MAX_A_CHANGE, \"futureA_ is too large\");\n }\n\n self.initialA = initialAPrecise;\n self.futureA = futureAPrecise;\n self.initialATime = block.timestamp;\n self.futureATime = futureTime_;\n\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\n }\n\n /**\n * @notice Stops ramping A immediately. Once this function is called, rampA()\n * cannot be called for another 24 hours\n * @param self Swap struct to update\n */\n function stopRampA(SwapUtils.Swap storage self) internal {\n require(self.futureATime > block.timestamp, \"Ramp is already stopped\");\n\n uint256 currentA = _getAPrecise(self);\n self.initialA = currentA;\n self.futureA = currentA;\n self.initialATime = block.timestamp;\n self.futureATime = block.timestamp;\n\n emit StopRampA(currentA, block.timestamp);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title Liquidity Provider Token\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\n * It is used to represent user's shares when providing liquidity to swap contracts.\n * @dev Only Swap contracts should initialize and own LPToken contracts.\n */\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\n // ============ Upgrade Gap ============\n\n uint256[49] private __GAP; // gap for upgrade safety\n\n // ============ Storage ============\n\n /**\n * @notice Used to enforce proper token dilution\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\n * See audit recommendations here:\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\n * and uniswap v2 implementation here:\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\n */\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\n\n // ============ Initializer ============\n\n /**\n * @notice Initializes this LPToken contract with the given name and symbol\n * @dev The caller of this function will become the owner. A Swap contract should call this\n * in its initializer function.\n * @param name name of this token\n * @param symbol symbol of this token\n */\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\n __Context_init_unchained();\n __ERC20_init_unchained(name, symbol);\n __Ownable_init_unchained();\n return true;\n }\n\n // ============ External functions ============\n\n /**\n * @notice Mints the given amount of LPToken to the recipient.\n * @dev only owner can call this mint function\n * @param recipient address of account to receive the tokens\n * @param amount amount of tokens to mint\n */\n function mint(address recipient, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot mint 0\");\n if (totalSupply() == 0) {\n // NOTE: using the _mint function directly will error because it is going\n // to the 0 address. fix by using the address(1) here instead\n _mint(address(1), MINIMUM_LIQUIDITY);\n }\n _mint(recipient, amount);\n }\n\n /**\n * @notice Burns the given amount of LPToken from provided account\n * @dev only owner can call this burn function\n * @param account address of account from which to burn token\n * @param amount amount of tokens to mint\n */\n function burnFrom(address account, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot burn 0\");\n _burn(account, amount);\n }\n\n // ============ Internal functions ============\n\n /**\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\n * This assumes the owner is set to a Swap contract's address.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20Upgradeable) {\n super._beforeTokenTransfer(from, to, amount);\n require(to != address(this), \"LPToken: cannot send to itself\");\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\n/**\n * @title MathUtils library\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\n * differences between two uint256.\n */\nlibrary MathUtils {\n /**\n * @notice Compares a and b and returns true if the difference between a and b\n * is less than 1 or equal to each other.\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return True if the difference between a and b is less than 1 or equal,\n * otherwise return false\n */\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\n return (difference(a, b) <= 1);\n }\n\n /**\n * @notice Calculates absolute difference between a and b\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return Difference between a and b\n */\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a > b) {\n return a - b;\n }\n return b - a;\n }\n}\n" - }, - "@openzeppelin/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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/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" - }, - "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.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 IERC20Upgradeable {\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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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" - }, - "solidity/for-test/DataReceiverForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {DataReceiver} from '../contracts/DataReceiver.sol';\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\n\ncontract DataReceiverForTest is DataReceiver {\n constructor(address _governor, IOracleFactory _oracleFactory) DataReceiver(_governor, _oracleFactory) {}\n\n function internalAddObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "solidity/contracts/DataReceiver.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\n\n/// @title The DataReceiver contract\n/// @notice Handles reception of broadcast data and delivers it to correspondant oracle\ncontract DataReceiver is IDataReceiver, Governable {\n /// @inheritdoc IDataReceiver\n IOracleFactory public immutable oracleFactory;\n\n /// @inheritdoc IDataReceiver\n mapping(bytes32 => IOracleSidechain) public deployedOracles;\n\n /// @inheritdoc IDataReceiver\n mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters;\n\n constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) {\n if (address(_oracleFactory) == address(0)) revert ZeroAddress();\n oracleFactory = _oracleFactory;\n }\n\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external onlyWhitelistedAdapters {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n // Read, store or deploy oracle given poolSalt\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.getPool(_poolSalt);\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.deployOracle(_poolSalt, _poolNonce);\n }\n deployedOracles[_poolSalt] = _oracle;\n }\n // Try to write observations data into oracle\n if (_oracle.write(_observationsData, _poolNonce)) {\n emit ObservationsAdded(_poolSalt, _poolNonce, _observationsData, msg.sender);\n } else {\n revert ObservationsNotWritable();\n }\n }\n\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_receiverAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IDataReceiver\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _receiverAdapterLength = _receiverAdapters.length;\n if (_receiverAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _receiverAdapterLength; ++_i) {\n _whitelistAdapter(_receiverAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n function _whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_receiverAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_receiverAdapter, _isWhitelisted);\n }\n\n modifier onlyWhitelistedAdapters() {\n if (!whitelistedAdapters[IBridgeReceiverAdapter(msg.sender)]) revert UnallowedAdapter();\n _;\n }\n}\n" - }, - "solidity/contracts/OracleSidechain.sol": { - "content": "//SPDX-License-Identifier: MIT\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\n\n/// @title The SidechainOracle contract\n/// @notice Computes and stores on-chain price data from Mainnet\ncontract OracleSidechain is IOracleSidechain {\n using Oracle for Oracle.Observation[65535];\n\n /// @inheritdoc IOracleSidechain\n IOracleFactory public immutable factory;\n\n struct Slot0 {\n // the current price\n uint160 sqrtPriceX96;\n // the current tick\n int24 tick;\n // the most-recently updated index of the observations array\n uint16 observationIndex;\n // the current maximum number of observations that are being stored\n uint16 observationCardinality;\n // the next maximum number of observations to store, triggered in observations.write\n uint16 observationCardinalityNext;\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\n // represented as an integer denominator (1/x)%\n uint8 feeProtocol;\n // whether the pool is locked\n bool unlocked;\n }\n /// @inheritdoc IOracleSidechain\n Slot0 public slot0;\n\n /// @inheritdoc IOracleSidechain\n Oracle.Observation[65535] public observations;\n\n /// @inheritdoc IOracleSidechain\n bytes32 public immutable poolSalt;\n\n uint24 public poolNonce;\n /// @inheritdoc IOracleSidechain\n address public token0;\n /// @inheritdoc IOracleSidechain\n address public token1;\n /// @inheritdoc IOracleSidechain\n uint24 public fee;\n\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\n function _getBlockTimestamp() internal view virtual returns (uint32) {\n return uint32(block.timestamp); // truncation is desired\n }\n\n constructor() {\n factory = IOracleFactory(msg.sender);\n uint16 _cardinality;\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\n\n slot0 = Slot0({\n sqrtPriceX96: 0,\n tick: 0,\n observationIndex: _cardinality - 1,\n observationCardinality: _cardinality,\n observationCardinalityNext: _cardinality,\n feeProtocol: 0,\n unlocked: true\n });\n }\n\n /// @inheritdoc IOracleSidechain\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external {\n if (!slot0.unlocked) revert AI();\n\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\n\n token0 = _token0;\n token1 = _token1;\n fee = _fee;\n slot0.unlocked = false;\n\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\n }\n\n /// @inheritdoc IOracleSidechain\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\n {\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\n }\n\n /// @inheritdoc IOracleSidechain\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\n if (_poolNonce != poolNonce++) return false;\n\n uint256 _observationsDataLength = _observationsData.length;\n for (uint256 _i; _i < _observationsDataLength; ) {\n _write(_observationsData[_i]);\n unchecked {\n ++_i;\n }\n }\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\n\n // emits UniV3 Swap event topic with minimal data\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\n return true;\n }\n\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\n if (_observationCardinalityNext <= _observationCardinalityNextOld) revert AI();\n slot0.observationCardinalityNext = _observationCardinalityNext;\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\n }\n\n function _write(ObservationData memory _observationData) private {\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\n slot0.observationIndex,\n _observationData.blockTimestamp,\n slot0.tick,\n 0,\n slot0.observationCardinality,\n slot0.observationCardinalityNext\n );\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\n slot0.tick = _observationData.tick;\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\n _;\n }\n\n modifier onlyFactory() {\n if (msg.sender != address(factory)) revert OnlyFactory();\n _;\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/Oracle.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/// @title Oracle\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\n/// @dev Instances of stored oracle data, \"observations\", are collected in the oracle array\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\n/// Observations are overwritten when the full length of the oracle array is populated.\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\nlibrary Oracle {\n error I();\n error OLD();\n\n struct Observation {\n // the block timestamp of the observation\n uint32 blockTimestamp;\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\n int56 tickCumulative;\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\n uint160 secondsPerLiquidityCumulativeX128;\n // whether or not the observation is initialized\n bool initialized;\n }\n\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\n /// @param last The specified observation to be transformed\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @return Observation The newly populated observation\n function transform(\n Observation memory last,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity\n ) private pure returns (Observation memory) {\n unchecked {\n uint32 delta = blockTimestamp - last.blockTimestamp;\n return\n Observation({\n blockTimestamp: blockTimestamp,\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\n initialized: true\n });\n }\n }\n\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\n /// @param self The stored oracle array\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\n /// @return cardinality The number of populated elements in the oracle array\n /// @return cardinalityNext The new length of the oracle array, independent of population\n function initialize(Observation[65535] storage self, uint32 time)\n internal\n returns (uint16 cardinality, uint16 cardinalityNext)\n {\n self[0] = Observation({\n blockTimestamp: time,\n tickCumulative: 0,\n secondsPerLiquidityCumulativeX128: 0,\n initialized: true\n });\n return (1, 1);\n }\n\n /// @notice Writes an oracle observation to the array\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\n /// @param self The stored oracle array\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @param cardinality The number of populated elements in the oracle array\n /// @param cardinalityNext The new length of the oracle array, independent of population\n /// @return indexUpdated The new index of the most recently written element in the oracle array\n /// @return cardinalityUpdated The new cardinality of the oracle array\n function write(\n Observation[65535] storage self,\n uint16 index,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity,\n uint16 cardinality,\n uint16 cardinalityNext\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\n unchecked {\n Observation memory last = self[index];\n\n // early return if we've already written an observation this block\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\n\n // if the conditions are right, we can bump the cardinality\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\n cardinalityUpdated = cardinalityNext;\n } else {\n cardinalityUpdated = cardinality;\n }\n\n indexUpdated = (index + 1) % cardinalityUpdated;\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\n }\n }\n\n /// @notice Prepares the oracle array to store up to `next` observations\n /// @param self The stored oracle array\n /// @param current The current next cardinality of the oracle array\n /// @param next The proposed next cardinality which will be populated in the oracle array\n /// @return next The next cardinality which will be populated in the oracle array\n function grow(\n Observation[65535] storage self,\n uint16 current,\n uint16 next\n ) internal returns (uint16) {\n unchecked {\n if (current <= 0) revert I();\n // no-op if the passed next value isn't greater than the current next value\n if (next <= current) return current;\n // store in each slot to prevent fresh SSTOREs in swaps\n // this data will not be used because the initialized boolean is still false\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\n return next;\n }\n }\n\n /// @notice comparator for 32-bit timestamps\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\n /// @param time A timestamp truncated to 32 bits\n /// @param a A comparison timestamp from which to determine the relative position of `time`\n /// @param b From which to determine the relative position of `time`\n /// @return Whether `a` is chronologically <= `b`\n function lte(\n uint32 time,\n uint32 a,\n uint32 b\n ) private pure returns (bool) {\n unchecked {\n // if there hasn't been overflow, no need to adjust\n if (a <= time && b <= time) return a <= b;\n\n uint256 aAdjusted = a > time ? a : a + 2**32;\n uint256 bAdjusted = b > time ? b : b + 2**32;\n\n return aAdjusted <= bAdjusted;\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\n /// The result may be the same observation, or adjacent observations.\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation recorded before, or at, the target\n /// @return atOrAfter The observation recorded at, or after, the target\n function binarySearch(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n uint16 index,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n uint256 l = (index + 1) % cardinality; // oldest observation\n uint256 r = l + cardinality - 1; // newest observation\n uint256 i;\n while (true) {\n i = (l + r) / 2;\n\n beforeOrAt = self[i % cardinality];\n\n // we've landed on an uninitialized tick, keep searching higher (more recently)\n if (!beforeOrAt.initialized) {\n l = i + 1;\n continue;\n }\n\n atOrAfter = self[(i + 1) % cardinality];\n\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\n\n // check if we've found the answer!\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\n\n if (!targetAtOrAfter) r = i - 1;\n else l = i + 1;\n }\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\n /// @dev Assumes there is at least 1 initialized observation.\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param tick The active tick at the time of the returned or simulated observation\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The total pool liquidity at the time of the call\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\n function getSurroundingObservations(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n // optimistically set before to the newest observation\n beforeOrAt = self[index];\n\n // if the target is chronologically at or after the newest observation, we can early return\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\n if (beforeOrAt.blockTimestamp == target) {\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\n return (beforeOrAt, atOrAfter);\n } else {\n // otherwise, we need to transform\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\n }\n }\n\n // now, set before to the oldest observation\n beforeOrAt = self[(index + 1) % cardinality];\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\n\n // ensure that the target is chronologically at or after the oldest observation\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\n\n // if we've reached this point, we have to binary search\n return binarySearch(self, time, target, index, cardinality);\n }\n }\n\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\n /// at exactly the timestamp between the two observations.\n /// @param self The stored oracle array\n /// @param time The current block timestamp\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\n function observeSingle(\n Observation[65535] storage self,\n uint32 time,\n uint32 secondsAgo,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\n unchecked {\n if (secondsAgo == 0) {\n Observation memory last = self[index];\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\n }\n\n uint32 target = time - secondsAgo;\n\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\n self,\n time,\n target,\n tick,\n index,\n liquidity,\n cardinality\n );\n\n if (target == beforeOrAt.blockTimestamp) {\n // we're at the left boundary\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\n } else if (target == atOrAfter.blockTimestamp) {\n // we're at the right boundary\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\n } else {\n // we're in the middle\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\n return (\n beforeOrAt.tickCumulative +\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\n int56(uint56(targetDelta)),\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\n uint160(\n (uint256(\n atOrAfter.secondsPerLiquidityCumulativeX128 -\n beforeOrAt.secondsPerLiquidityCumulativeX128\n ) * targetDelta) / observationTimeDelta\n )\n );\n }\n }\n }\n\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\n /// @dev Reverts if `secondsAgos` > oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\n function observe(\n Observation[65535] storage self,\n uint32 time,\n uint32[] memory secondsAgos,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\n unchecked {\n if (cardinality <= 0) revert I();\n\n tickCumulatives = new int56[](secondsAgos.length);\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\n for (uint256 i = 0; i < secondsAgos.length; i++) {\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\n self,\n time,\n secondsAgos[i],\n tick,\n index,\n liquidity,\n cardinality\n );\n }\n }\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/TickMath.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n error T();\n error R();\n\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n unchecked {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n if (absTick > uint256(int256(MAX_TICK))) revert T();\n\n uint256 ratio = absTick & 0x1 != 0\n ? 0xfffcb933bd6fad37aa2d162d1a594001\n : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\n /// ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n unchecked {\n // second inequality must be < because the price can never reach the price at the max tick\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n }\n}\n" - }, - "solidity/contracts/bridges/ConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext, IConnextSenderAdapter, IBridgeSenderAdapter, IDataFeed, IOracleSidechain} from '../../interfaces/bridges/IConnextSenderAdapter.sol';\nimport {LibConnextStorage, TransferInfo} from '@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol';\n\ncontract ConnextSenderAdapter is IConnextSenderAdapter {\n /// @inheritdoc IConnextSenderAdapter\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IConnextSenderAdapter\n IConnext public immutable connext;\n\n constructor(IDataFeed _dataFeed, IConnext _connext) {\n if (address(_dataFeed) == address(0) || address(_connext) == address(0)) revert ZeroAddress();\n dataFeed = _dataFeed;\n connext = _connext;\n }\n\n /// @inheritdoc IBridgeSenderAdapter\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable onlyDataFeed {\n bytes memory _callData = abi.encode(_observationsData, _poolSalt, _poolNonce);\n\n connext.xcall{value: msg.value}({\n _destination: _destinationDomainId, // unique identifier for destination domain\n _to: _to, // recipient of funds, where calldata will be executed\n _asset: address(0), // asset being transferred\n _delegate: address(0), // permissioned address to recover in edgecases on destination domain\n _amount: 0, // amount being transferred\n _slippage: 0, // slippage in bps\n _callData: _callData // to be executed on _to on the destination domain\n });\n }\n\n modifier onlyDataFeed() {\n if (msg.sender != address(dataFeed)) revert OnlyDataFeed();\n _;\n }\n}\n" - }, - "solidity/interfaces/bridges/IConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from './IBridgeReceiverAdapter.sol';\n\ninterface IConnextReceiverAdapter is IXReceiver, IBridgeReceiverAdapter {\n // STATE VARIABLES\n\n /// @notice Gets the ConnextHandler contract on this domain\n /// @return _connext Address of the ConnextHandler contract\n function connext() external view returns (IConnext _connext);\n\n /// @notice Gets the DAO that is expected as the xcaller\n /// @return _originContract Address of the xcaller contract\n function source() external view returns (address _originContract);\n\n /// @notice Gets the origin domain id\n /// @return _originDomain The origin domain id\n function originDomain() external view returns (uint32 _originDomain);\n\n // ERRORS\n\n /// @notice Thrown if a caller is not authorized\n error UnauthorizedCaller();\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface IXReceiver {\n function xReceive(\n bytes32 _transferId,\n uint256 _amount,\n address _asset,\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external returns (bytes memory);\n}\n" - }, - "solidity/for-test/ConnextHandlerForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextHandlerForTest {\n uint32 public origin;\n\n constructor() {\n origin = 1111;\n }\n\n function xcall(\n uint32, // _destination, unique identifier for destination domain\n address _to, // recipient of funds, where calldata will be executed\n address, // _asset, asset being transferred\n address, // _delegate, permissioned address to recover in edgecases on destination domain\n uint256, // _amount, amount being transferred\n uint256, // _slippage, slippage in bps\n bytes calldata _callData // to be executed on _to on the destination domain\n ) external payable returns (bytes32) {\n IXReceiver(_to).xReceive({_transferId: 0, _amount: 0, _asset: address(0), _originSender: msg.sender, _origin: origin, _callData: _callData});\n\n return bytes32(abi.encode('random'));\n }\n}\n" - }, - "solidity/interfaces/IStrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IKeep3rJob} from './peripherals/IKeep3rJob.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IStrategyJob is IKeep3rJob {\n // STATE VARIABLES\n\n /// @return _dataFeedStrategy The address of the current DataFeedStrategy\n function dataFeedStrategy() external view returns (IDataFeedStrategy _dataFeedStrategy);\n\n /// @return _dataFeed The address of the DataFeed\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _defaultBridgeSenderAdapter The address of the job bridge sender adapter\n function defaultBridgeSenderAdapter() external view returns (IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n /// @param _chainId The identifier of the chain\n /// @param _poolSalt The identifier of both the pool and oracle\n /// @return _lastPoolNonceBridged Last nonce of the oracle observed\n function lastPoolNonceBridged(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _lastPoolNonceBridged);\n\n // EVENTS\n\n /// @notice Emitted when a new default bridge sender adapter is set\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n event DefaultBridgeSenderAdapterSet(IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n // ERRORS\n\n /// @notice Thrown when the job is not workable\n error NotWorkable();\n\n // FUNCTIONS\n\n /// @notice Calls to send observations in the DataFeed contract\n /// @param _chainId The Ethereum chain identification\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Calls to fetch observations and update the oracle state in the DataFeed contract\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The identifier of the reason to trigger an update\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external;\n\n /// @notice Allows governor to set a new default bridge sender adapter\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external;\n\n /// @notice Returns if the job can be worked\n /// @param _chainId The destination chain ID\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n /// @return _isWorkable Whether the job is workable or not\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external view returns (bool _isWorkable);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the job can be worked\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the job can be worked\n /// @return _isWorkable Whether the job is workable or not\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external view returns (bool _isWorkable);\n}\n" - }, - "solidity/interfaces/peripherals/IKeep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IKeep3r} from '@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol';\n\ninterface IKeep3rJob is IGovernable {\n // STATE VARIABLES\n\n /// @return _keep3r Address of the Keep3r contract\n function keep3r() external view returns (IKeep3r _keep3r);\n\n // EVENTS\n\n /// @notice Emitted when a new Keep3r contract is set\n /// @param _keep3r Address of the new Keep3r contract\n event Keep3rSet(IKeep3r _keep3r);\n\n // ERRORS\n\n /// @notice Throws when a keeper fails the validation\n error KeeperNotValid();\n\n // FUNCTIONS\n\n /// @notice Allows governor to set a new Keep3r contract\n /// @param _keep3r Address of the new Keep3r contract\n function setKeep3r(IKeep3r _keep3r) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rParameters.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rKeepers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rJobs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rAccountance.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rRoles.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IBaseErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IGovernable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IDustCollector.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rDisputable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" - }, - "@uniswap/v3-periphery/contracts/libraries/OracleLibrary.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/libraries/FullMath.sol';\nimport '@uniswap/v3-core/contracts/libraries/TickMath.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n/// @title Oracle library\n/// @notice Provides functions to integrate with V3 pool oracle\nlibrary OracleLibrary {\n /// @notice Calculates time-weighted means of tick and liquidity for a given Uniswap V3 pool\n /// @param pool Address of the pool that we want to observe\n /// @param secondsAgo Number of seconds in the past from which to calculate the time-weighted means\n /// @return arithmeticMeanTick The arithmetic mean tick from (block.timestamp - secondsAgo) to block.timestamp\n /// @return harmonicMeanLiquidity The harmonic mean liquidity from (block.timestamp - secondsAgo) to block.timestamp\n function consult(address pool, uint32 secondsAgo)\n internal\n view\n returns (int24 arithmeticMeanTick, uint128 harmonicMeanLiquidity)\n {\n require(secondsAgo != 0, 'BP');\n\n uint32[] memory secondsAgos = new uint32[](2);\n secondsAgos[0] = secondsAgo;\n secondsAgos[1] = 0;\n\n (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) = IUniswapV3Pool(pool)\n .observe(secondsAgos);\n\n int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0];\n uint160 secondsPerLiquidityCumulativesDelta = secondsPerLiquidityCumulativeX128s[1] -\n secondsPerLiquidityCumulativeX128s[0];\n\n arithmeticMeanTick = int24(tickCumulativesDelta / int56(uint56(secondsAgo)));\n // Always round to negative infinity\n if (tickCumulativesDelta < 0 && (tickCumulativesDelta % int56(uint56(secondsAgo)) != 0)) arithmeticMeanTick--;\n\n // We are multiplying here instead of shifting to ensure that harmonicMeanLiquidity doesn't overflow uint128\n uint192 secondsAgoX160 = uint192(secondsAgo) * type(uint160).max;\n harmonicMeanLiquidity = uint128(secondsAgoX160 / (uint192(secondsPerLiquidityCumulativesDelta) << 32));\n }\n\n /// @notice Given a tick and a token amount, calculates the amount of token received in exchange\n /// @param tick Tick value used to calculate the quote\n /// @param baseAmount Amount of token to be converted\n /// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination\n /// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination\n /// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken\n function getQuoteAtTick(\n int24 tick,\n uint128 baseAmount,\n address baseToken,\n address quoteToken\n ) internal pure returns (uint256 quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick);\n\n // Calculate quoteAmount with better precision if it doesn't overflow when multiplied by itself\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n quoteAmount = baseToken < quoteToken\n ? FullMath.mulDiv(ratioX192, baseAmount, 1 << 192)\n : FullMath.mulDiv(1 << 192, baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n quoteAmount = baseToken < quoteToken\n ? FullMath.mulDiv(ratioX128, baseAmount, 1 << 128)\n : FullMath.mulDiv(1 << 128, baseAmount, ratioX128);\n }\n }\n\n /// @notice Given a pool, it returns the number of seconds ago of the oldest stored observation\n /// @param pool Address of Uniswap V3 pool that we want to observe\n /// @return secondsAgo The number of seconds ago of the oldest observation stored for the pool\n function getOldestObservationSecondsAgo(address pool) internal view returns (uint32 secondsAgo) {\n (, , uint16 observationIndex, uint16 observationCardinality, , , ) = IUniswapV3Pool(pool).slot0();\n require(observationCardinality > 0, 'NI');\n\n (uint32 observationTimestamp, , , bool initialized) = IUniswapV3Pool(pool).observations(\n (observationIndex + 1) % observationCardinality\n );\n\n // The next index might not be initialized if the cardinality is in the process of increasing\n // In this case the oldest observation is always in index 0\n if (!initialized) {\n (observationTimestamp, , , ) = IUniswapV3Pool(pool).observations(0);\n }\n\n unchecked {\n secondsAgo = uint32(block.timestamp) - observationTimestamp;\n }\n }\n\n /// @notice Given a pool, it returns the tick value as of the start of the current block\n /// @param pool Address of Uniswap V3 pool\n /// @return The tick that the pool was in at the start of the current block\n function getBlockStartingTickAndLiquidity(address pool) internal view returns (int24, uint128) {\n (, int24 tick, uint16 observationIndex, uint16 observationCardinality, , , ) = IUniswapV3Pool(pool).slot0();\n\n // 2 observations are needed to reliably calculate the block starting tick\n require(observationCardinality > 1, 'NEO');\n\n // If the latest observation occurred in the past, then no tick-changing trades have happened in this block\n // therefore the tick in `slot0` is the same as at the beginning of the current block.\n // We don't need to check if this observation is initialized - it is guaranteed to be.\n (\n uint32 observationTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n\n ) = IUniswapV3Pool(pool).observations(observationIndex);\n if (observationTimestamp != uint32(block.timestamp)) {\n return (tick, IUniswapV3Pool(pool).liquidity());\n }\n\n uint256 prevIndex = (uint256(observationIndex) + observationCardinality - 1) % observationCardinality;\n (\n uint32 prevObservationTimestamp,\n int56 prevTickCumulative,\n uint160 prevSecondsPerLiquidityCumulativeX128,\n bool prevInitialized\n ) = IUniswapV3Pool(pool).observations(prevIndex);\n\n require(prevInitialized, 'ONI');\n\n uint32 delta = observationTimestamp - prevObservationTimestamp;\n tick = int24((tickCumulative - int56(uint56(prevTickCumulative))) / int56(uint56(delta)));\n uint128 liquidity = uint128(\n (uint192(delta) * type(uint160).max) /\n (uint192(secondsPerLiquidityCumulativeX128 - prevSecondsPerLiquidityCumulativeX128) << 32)\n );\n return (tick, liquidity);\n }\n\n /// @notice Information for calculating a weighted arithmetic mean tick\n struct WeightedTickData {\n int24 tick;\n uint128 weight;\n }\n\n /// @notice Given an array of ticks and weights, calculates the weighted arithmetic mean tick\n /// @param weightedTickData An array of ticks and weights\n /// @return weightedArithmeticMeanTick The weighted arithmetic mean tick\n /// @dev Each entry of `weightedTickData` should represents ticks from pools with the same underlying pool tokens. If they do not,\n /// extreme care must be taken to ensure that ticks are comparable (including decimal differences).\n /// @dev Note that the weighted arithmetic mean tick corresponds to the weighted geometric mean price.\n function getWeightedArithmeticMeanTick(WeightedTickData[] memory weightedTickData)\n internal\n pure\n returns (int24 weightedArithmeticMeanTick)\n {\n // Accumulates the sum of products between each tick and its weight\n int256 numerator;\n\n // Accumulates the sum of the weights\n uint256 denominator;\n\n // Products fit in 152 bits, so it would take an array of length ~2**104 to overflow this logic\n for (uint256 i; i < weightedTickData.length; i++) {\n numerator += weightedTickData[i].tick * int256(uint256(weightedTickData[i].weight));\n denominator += weightedTickData[i].weight;\n }\n\n weightedArithmeticMeanTick = int24(numerator / int256(denominator));\n // Always round to negative infinity\n if (numerator < 0 && (numerator % int256(denominator) != 0)) weightedArithmeticMeanTick--;\n }\n\n /// @notice Returns the \"synthetic\" tick which represents the price of the first entry in `tokens` in terms of the last\n /// @dev Useful for calculating relative prices along routes.\n /// @dev There must be one tick for each pairwise set of tokens.\n /// @param tokens The token contract addresses\n /// @param ticks The ticks, representing the price of each token pair in `tokens`\n /// @return syntheticTick The synthetic tick, representing the relative price of the outermost tokens in `tokens`\n function getChainedPrice(address[] memory tokens, int24[] memory ticks)\n internal\n pure\n returns (int256 syntheticTick)\n {\n require(tokens.length - 1 == ticks.length, 'DL');\n for (uint256 i = 1; i <= ticks.length; i++) {\n // check the tokens for address sort order, then accumulate the\n // ticks into the running synthetic tick, ensuring that intermediate tokens \"cancel out\"\n tokens[i - 1] < tokens[i] ? syntheticTick += ticks[i - 1] : syntheticTick -= ticks[i - 1];\n }\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/FullMath.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (0 - denominator) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" - }, - "solidity/for-test/DummyAdapterForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\nimport {IDataReceiver} from '../interfaces/IDataReceiver.sol';\nimport {IBridgeSenderAdapter} from '../interfaces/bridges/IBridgeSenderAdapter.sol';\n\ncontract DummyAdapterForTest is IBridgeSenderAdapter {\n event Create2Hash(bytes32);\n\n bool public ignoreTxs;\n\n constructor() {\n /// @dev Emitted to validate correct calculation of ORACLE_INIT_CODE_HASH\n emit Create2Hash(keccak256(type(OracleSidechain).creationCode));\n }\n\n function bridgeObservations(\n address _to,\n uint32,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable {\n if (!ignoreTxs) {\n IDataReceiver(_to).addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n }\n\n function setIgnoreTxs(bool _ignoreTxs) external {\n ignoreTxs = _ignoreTxs;\n }\n}\n" - }, - "solidity/contracts/OracleFactory.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IOracleFactory, IOracleSidechain, IDataReceiver} from '../interfaces/IOracleFactory.sol';\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\n\n/// @title The OracleFactory contract\n/// @notice Handles the deployment of new OracleSidechains\ncontract OracleFactory is IOracleFactory, Governable {\n /// @inheritdoc IOracleFactory\n IDataReceiver public dataReceiver;\n\n /// @inheritdoc IOracleFactory\n OracleParameters public oracleParameters;\n\n /// @inheritdoc IOracleFactory\n uint16 public initialCardinality = 144;\n\n /// @inheritdoc IOracleFactory\n bytes32 public constant ORACLE_INIT_CODE_HASH = keccak256(type(OracleSidechain).creationCode);\n\n constructor(address _governor, IDataReceiver _dataReceiver) Governable(_governor) {\n _setDataReceiver(_dataReceiver);\n }\n\n /// @inheritdoc IOracleFactory\n function deployOracle(bytes32 _poolSalt, uint24 _initialNonce) external onlyDataReceiver returns (IOracleSidechain _oracle) {\n oracleParameters = OracleParameters({poolSalt: _poolSalt, poolNonce: _initialNonce, cardinality: initialCardinality});\n _oracle = new OracleSidechain{salt: _poolSalt}();\n\n delete oracleParameters;\n emit OracleDeployed(_poolSalt, address(_oracle), _initialNonce);\n }\n\n /// @inheritdoc IOracleFactory\n function setDataReceiver(IDataReceiver _dataReceiver) external onlyGovernor {\n _setDataReceiver(_dataReceiver);\n }\n\n /// @inheritdoc IOracleFactory\n function setInitialCardinality(uint16 _initialCardinality) external onlyGovernor {\n if (_initialCardinality == 0) revert ZeroAmount();\n\n initialCardinality = _initialCardinality;\n emit InitialCardinalitySet(_initialCardinality);\n }\n\n function increaseOracleCardinality(bytes32 _poolSalt, uint16 _observationCardinalityNext) external onlyGovernor {\n IOracleSidechain _oracle = getPool(_poolSalt);\n _oracle.increaseObservationCardinalityNext(_observationCardinalityNext);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle) {\n bytes32 _poolSalt = getPoolSalt(_tokenA, _tokenB, _fee);\n _oracle = getPool(_poolSalt);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(bytes32 _poolSalt) public view returns (IOracleSidechain _oracle) {\n _oracle = IOracleSidechain(Create2Address.computeAddress(address(this), _poolSalt, ORACLE_INIT_CODE_HASH));\n if (address(_oracle).code.length == 0) return IOracleSidechain(address(0));\n }\n\n /// @inheritdoc IOracleFactory\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) public pure returns (bytes32 _poolSalt) {\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n _poolSalt = keccak256(abi.encode(_token0, _token1, _fee));\n }\n\n function _setDataReceiver(IDataReceiver _dataReceiver) private {\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\n\n dataReceiver = _dataReceiver;\n emit DataReceiverSet(_dataReceiver);\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(dataReceiver)) revert OnlyDataReceiver();\n _;\n }\n}\n" - }, - "solidity/contracts/peripherals/Keep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {IKeep3rJob, IKeep3r} from '../../interfaces/peripherals/IKeep3rJob.sol';\n\nabstract contract Keep3rJob is IKeep3rJob, Governable {\n /// @inheritdoc IKeep3rJob\n IKeep3r public keep3r = IKeep3r(0xeb02addCfD8B773A5FFA6B9d1FE99c566f8c44CC);\n\n /// @inheritdoc IKeep3rJob\n function setKeep3r(IKeep3r _keep3r) external onlyGovernor {\n _setKeep3r(_keep3r);\n }\n\n function _setKeep3r(IKeep3r _keep3r) internal {\n keep3r = _keep3r;\n emit Keep3rSet(_keep3r);\n }\n\n function _isValidKeeper(address _keeper) internal virtual {\n if (!keep3r.isKeeper(_keeper)) revert KeeperNotValid();\n }\n\n modifier upkeep() {\n _isValidKeeper(msg.sender);\n _;\n keep3r.worked(msg.sender);\n }\n}\n" - }, - "solidity/for-test/Keep3rJobForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from '../contracts/peripherals/Keep3rJob.sol';\n\ncontract Keep3rJobForTest is Keep3rJob {\n constructor(address _governor) Governable(_governor) {}\n\n function internalIsValidKeeper(address _keeper) external {\n _isValidKeeper(_keeper);\n }\n}\n" - }, - "solidity/contracts/StrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from './peripherals/Keep3rJob.sol';\nimport {IStrategyJob, IDataFeedStrategy, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IStrategyJob.sol';\n\n/// @title The StrategyJob contract\n/// @notice Adds a reward layer for triggering fetch and bridge transactions\ncontract StrategyJob is IStrategyJob, Keep3rJob {\n /// @inheritdoc IStrategyJob\n IDataFeedStrategy public immutable dataFeedStrategy;\n\n /// @inheritdoc IStrategyJob\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IStrategyJob\n IBridgeSenderAdapter public defaultBridgeSenderAdapter;\n\n /// @inheritdoc IStrategyJob\n mapping(uint32 => mapping(bytes32 => uint24)) public lastPoolNonceBridged;\n\n constructor(\n address _governor,\n IDataFeedStrategy _dataFeedStrategy,\n IDataFeed _dataFeed,\n IBridgeSenderAdapter _defaultBridgeSenderAdapter\n ) Governable(_governor) {\n if (address(_dataFeedStrategy) == address(0) || address(_dataFeed) == address(0)) revert ZeroAddress();\n dataFeedStrategy = _dataFeedStrategy;\n dataFeed = _dataFeed;\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external upkeep {\n if (!_workable(_chainId, _poolSalt, _poolNonce)) revert NotWorkable();\n lastPoolNonceBridged[_chainId][_poolSalt] = _poolNonce;\n dataFeed.sendObservations(defaultBridgeSenderAdapter, _chainId, _poolSalt, _poolNonce, _observationsData);\n }\n\n /// @inheritdoc IStrategyJob\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external upkeep {\n dataFeedStrategy.strategicFetchObservations(_poolSalt, _reason);\n }\n\n /// @inheritdoc IStrategyJob\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external onlyGovernor {\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external view returns (bool _isWorkable) {\n uint24 _whitelistedNonce = dataFeed.whitelistedNonces(_chainId, _poolSalt);\n if (_whitelistedNonce != 0 && _whitelistedNonce <= _poolNonce) return _workable(_chainId, _poolSalt, _poolNonce);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external view returns (bool _isWorkable) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt, _reason);\n }\n\n function _workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal view returns (bool _isWorkable) {\n uint24 _lastPoolNonceBridged = lastPoolNonceBridged[_chainId][_poolSalt];\n if (_lastPoolNonceBridged == 0) {\n (uint24 _lastPoolNonceObserved, , , ) = dataFeed.lastPoolStateObserved(_poolSalt);\n return _poolNonce == _lastPoolNonceObserved;\n } else {\n return _poolNonce == ++_lastPoolNonceBridged;\n }\n }\n\n function _setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) private {\n if (address(_defaultBridgeSenderAdapter) == address(0)) revert ZeroAddress();\n\n defaultBridgeSenderAdapter = _defaultBridgeSenderAdapter;\n emit DefaultBridgeSenderAdapterSet(_defaultBridgeSenderAdapter);\n }\n}\n" - }, - "solidity/contracts/DataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {IDataFeedStrategy, IUniswapV3Pool, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeedStrategy.sol';\nimport {OracleLibrary} from '@uniswap/v3-periphery/contracts/libraries/OracleLibrary.sol';\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\n\n/// @title The DataFeed Strategy contract\n/// @notice Handles when and how a history of a pool should be updated\ncontract DataFeedStrategy is IDataFeedStrategy, Governable {\n /// @inheritdoc IDataFeedStrategy\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public periodDuration;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public strategyCooldown;\n\n /// @inheritdoc IDataFeedStrategy\n uint24 public defaultTwapThreshold;\n\n mapping(bytes32 => uint24) internal _twapThreshold;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public twapLength;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(\n address _governor,\n IDataFeed _dataFeed,\n StrategySettings memory _params\n ) Governable(_governor) {\n if (address(_dataFeed) == address(0)) revert ZeroAddress();\n dataFeed = _dataFeed;\n _setStrategyCooldown(_params.strategyCooldown);\n _setDefaultTwapThreshold(_params.defaultTwapThreshold);\n _setTwapLength(_params.twapLength);\n _setPeriodDuration(_params.periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _fromSecondsAgo;\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n\n if (_reason == TriggerReason.OLD) {\n uint32 _timeSinceLastObservation = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n uint32 _poolOldestSecondsAgo = _getPoolOldestSecondsAgo(_poolSalt);\n if (!(_timeSinceLastObservation > _poolOldestSecondsAgo)) revert NotStrategic();\n _fromSecondsAgo = _poolOldestSecondsAgo;\n } else {\n if (!_isStrategic(_poolSalt, _lastPoolStateObserved, _reason)) revert NotStrategic();\n _fromSecondsAgo = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n }\n\n uint32[] memory _secondsAgos = calculateSecondsAgos(_fromSecondsAgo);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n emit StrategicFetch(_poolSalt, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setStrategyCooldown(uint32 _strategyCooldown) external onlyGovernor {\n _setStrategyCooldown(_strategyCooldown);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setDefaultTwapThreshold(uint24 _defaultTwapThreshold) external onlyGovernor {\n _setDefaultTwapThreshold(_defaultTwapThreshold);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapThreshold(bytes32 _poolSalt, uint24 _poolTwapThreshold) external onlyGovernor {\n _setTwapThreshold(_poolSalt, _poolTwapThreshold);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapLength(uint32 _twapLength) external onlyGovernor {\n _setTwapLength(_twapLength);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setPeriodDuration(uint32 _periodDuration) external onlyGovernor {\n _setPeriodDuration(_periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function twapThreshold(bytes32 _poolSalt) external view returns (uint24 _poolTwapThreshold) {\n _poolTwapThreshold = _twapThreshold[_poolSalt];\n if (_poolTwapThreshold == 0) return defaultTwapThreshold;\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason) {\n if (isStrategic(_poolSalt, TriggerReason.TIME)) return TriggerReason.TIME;\n if (isStrategic(_poolSalt, TriggerReason.TWAP)) return TriggerReason.TWAP;\n if (isStrategic(_poolSalt, TriggerReason.OLD)) return TriggerReason.OLD;\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) public view returns (bool _strategic) {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n return _isStrategic(_poolSalt, _lastPoolStateObserved, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function calculateSecondsAgos(uint32 _fromSecondsAgo) public view returns (uint32[] memory _secondsAgos) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n if (_fromSecondsAgo == _secondsNow) return _initializeSecondsAgos();\n\n uint32 _periodDuration = periodDuration;\n uint32 _maxPeriods = strategyCooldown / _periodDuration;\n uint32 _periods = _fromSecondsAgo / _periodDuration;\n uint32 _remainder = _fromSecondsAgo % _periodDuration;\n uint32 _i;\n\n if (_periods > _maxPeriods) {\n _remainder += (_periods - _maxPeriods) * _periodDuration;\n _periods = _maxPeriods;\n }\n\n if (_remainder != 0) {\n _secondsAgos = new uint32[](++_periods);\n _fromSecondsAgo -= _remainder;\n _secondsAgos[_i++] = _fromSecondsAgo;\n } else {\n _secondsAgos = new uint32[](_periods);\n }\n\n while (_fromSecondsAgo > 0) {\n _fromSecondsAgo -= _periodDuration;\n _secondsAgos[_i++] = _fromSecondsAgo;\n }\n }\n\n function _isStrategic(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n TriggerReason _reason\n ) internal view returns (bool _strategic) {\n if (_reason == TriggerReason.TIME) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n return _secondsNow >= _lastPoolStateObserved.blockTimestamp + strategyCooldown;\n } else if (_reason == TriggerReason.TWAP) {\n return _twapIsOutOfThresholds(_poolSalt, _lastPoolStateObserved);\n } else if (_reason == TriggerReason.OLD) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _timeSinceLastObservation = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n uint32 _poolOldestSecondsAgo = _getPoolOldestSecondsAgo(_poolSalt);\n return _timeSinceLastObservation > _poolOldestSecondsAgo;\n }\n }\n\n function _twapIsOutOfThresholds(bytes32 _poolSalt, IDataFeed.PoolState memory _lastPoolStateObserved)\n internal\n view\n returns (bool _isOutOfThresholds)\n {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _twapLength = twapLength;\n\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[0] = _twapLength;\n _secondsAgos[1] = 0;\n\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _poolTickCumulatives, ) = _pool.observe(_secondsAgos);\n\n int24 _poolArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _poolTickCumulatives[1], _twapLength);\n\n uint32 _oracleDelta = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n int56 _oracleTickCumulative = _lastPoolStateObserved.tickCumulative + int56(_lastPoolStateObserved.arithmeticMeanTick) * int32(_oracleDelta);\n\n int24 _oracleArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _oracleTickCumulative, _twapLength);\n\n uint24 _poolTwapThreshold = _twapThreshold[_poolSalt];\n if (_poolTwapThreshold == 0) _poolTwapThreshold = defaultTwapThreshold;\n\n return\n _poolArithmeticMeanTick > _oracleArithmeticMeanTick + int24(_poolTwapThreshold) ||\n _poolArithmeticMeanTick < _oracleArithmeticMeanTick - int24(_poolTwapThreshold);\n }\n\n function _computeTwap(\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n uint32 _delta\n ) internal pure returns (int24 _arithmeticMeanTick) {\n int56 _tickCumulativesDelta = _tickCumulative2 - _tickCumulative1;\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n }\n\n function _getPoolOldestSecondsAgo(bytes32 _poolSalt) internal view returns (uint32 _poolOldestSecondsAgo) {\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n _poolOldestSecondsAgo = OracleLibrary.getOldestObservationSecondsAgo(address(_pool));\n }\n\n function _initializeSecondsAgos() internal view returns (uint32[] memory _secondsAgos) {\n _secondsAgos = new uint32[](2);\n _secondsAgos[0] = periodDuration;\n _secondsAgos[1] = 0;\n }\n\n function _setStrategyCooldown(uint32 _strategyCooldown) private {\n if (_strategyCooldown < twapLength) revert WrongSetting();\n\n strategyCooldown = _strategyCooldown;\n emit StrategyCooldownSet(_strategyCooldown);\n }\n\n function _setDefaultTwapThreshold(uint24 _defaultTwapThreshold) private {\n if (_defaultTwapThreshold == 0) revert ZeroAmount();\n\n defaultTwapThreshold = _defaultTwapThreshold;\n emit DefaultTwapThresholdSet(_defaultTwapThreshold);\n }\n\n function _setTwapThreshold(bytes32 _poolSalt, uint24 _poolTwapThreshold) private {\n _twapThreshold[_poolSalt] = _poolTwapThreshold;\n emit TwapThresholdSet(_poolSalt, _poolTwapThreshold);\n }\n\n function _setTwapLength(uint32 _twapLength) private {\n if ((_twapLength > strategyCooldown) || (_twapLength < periodDuration)) revert WrongSetting();\n\n twapLength = _twapLength;\n emit TwapLengthSet(_twapLength);\n }\n\n function _setPeriodDuration(uint32 _periodDuration) private {\n if (_periodDuration > twapLength || _periodDuration == 0) revert WrongSetting();\n\n periodDuration = _periodDuration;\n emit PeriodDurationSet(_periodDuration);\n }\n}\n" - }, - "solidity/contracts/bridges/BridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IBridgeReceiverAdapter.sol';\n\nabstract contract BridgeReceiverAdapter is IBridgeReceiverAdapter {\n /// @inheritdoc IBridgeReceiverAdapter\n IDataReceiver public immutable dataReceiver;\n\n constructor(IDataReceiver _dataReceiver) {\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\n dataReceiver = _dataReceiver;\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n dataReceiver.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "solidity/contracts/bridges/ConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {BridgeReceiverAdapter} from './BridgeReceiverAdapter.sol';\nimport {IConnext, IXReceiver, IConnextReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IConnextReceiverAdapter.sol';\n\ncontract ConnextReceiverAdapter is IConnextReceiverAdapter, BridgeReceiverAdapter {\n /// @inheritdoc IConnextReceiverAdapter\n IConnext public immutable connext;\n\n /// @inheritdoc IConnextReceiverAdapter\n address public immutable source;\n\n /// @inheritdoc IConnextReceiverAdapter\n uint32 public immutable originDomain;\n\n constructor(\n IDataReceiver _dataReceiver,\n IConnext _connext,\n address _source,\n uint32 _originDomain\n ) BridgeReceiverAdapter(_dataReceiver) {\n if (address(_connext) == address(0) || _source == address(0)) revert ZeroAddress();\n connext = _connext;\n source = _source;\n originDomain = _originDomain;\n }\n\n /// @inheritdoc IXReceiver\n function xReceive(\n bytes32, // _transferId\n uint256, // _amount\n address, // _asset\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external onlyExecutor(_originSender, _origin) returns (bytes memory) {\n (IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, uint24 _poolNonce) = abi.decode(\n _callData,\n (IOracleSidechain.ObservationData[], bytes32, uint24)\n );\n\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n\n modifier onlyExecutor(address _originSender, uint32 _originDomain) {\n if (msg.sender != address(connext) || _originSender != source || _originDomain != originDomain) revert UnauthorizedCaller();\n _;\n }\n}\n" - }, - "solidity/for-test/UniswapV3Importer.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Factory} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';\nimport {ISwapRouter} from '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';\n\ninterface INFTPositionManager {\n struct MintParams {\n address token0;\n address token1;\n uint24 fee;\n int24 tickLower;\n int24 tickUpper;\n uint256 amount0Desired;\n uint256 amount1Desired;\n uint256 amount0Min;\n uint256 amount1Min;\n address recipient;\n uint256 deadline;\n }\n\n function mint(MintParams calldata _params)\n external\n payable\n returns (\n uint256 _tokenId,\n uint128 _liquidity,\n uint256 _amount0,\n uint256 _amount1\n );\n}\n\n// solhint-disable-next-line no-empty-blocks\ncontract UniswapV3Importer {\n\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title The interface for the Uniswap V3 Factory\n/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees\ninterface IUniswapV3Factory {\n /// @notice Emitted when the owner of the factory is changed\n /// @param oldOwner The owner before the owner was changed\n /// @param newOwner The owner after the owner was changed\n event OwnerChanged(address indexed oldOwner, address indexed newOwner);\n\n /// @notice Emitted when a pool is created\n /// @param token0 The first token of the pool by address sort order\n /// @param token1 The second token of the pool by address sort order\n /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip\n /// @param tickSpacing The minimum number of ticks between initialized ticks\n /// @param pool The address of the created pool\n event PoolCreated(\n address indexed token0,\n address indexed token1,\n uint24 indexed fee,\n int24 tickSpacing,\n address pool\n );\n\n /// @notice Emitted when a new fee amount is enabled for pool creation via the factory\n /// @param fee The enabled fee, denominated in hundredths of a bip\n /// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee\n event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing);\n\n /// @notice Returns the current owner of the factory\n /// @dev Can be changed by the current owner via setOwner\n /// @return The address of the factory owner\n function owner() external view returns (address);\n\n /// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled\n /// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context\n /// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee\n /// @return The tick spacing\n function feeAmountTickSpacing(uint24 fee) external view returns (int24);\n\n /// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist\n /// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order\n /// @param tokenA The contract address of either token0 or token1\n /// @param tokenB The contract address of the other token\n /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip\n /// @return pool The pool address\n function getPool(\n address tokenA,\n address tokenB,\n uint24 fee\n ) external view returns (address pool);\n\n /// @notice Creates a pool for the given two tokens and fee\n /// @param tokenA One of the two tokens in the desired pool\n /// @param tokenB The other of the two tokens in the desired pool\n /// @param fee The desired fee for the pool\n /// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved\n /// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments\n /// are invalid.\n /// @return pool The address of the newly created pool\n function createPool(\n address tokenA,\n address tokenB,\n uint24 fee\n ) external returns (address pool);\n\n /// @notice Updates the owner of the factory\n /// @dev Must be called by the current owner\n /// @param _owner The new owner of the factory\n function setOwner(address _owner) external;\n\n /// @notice Enables a fee amount with the given tickSpacing\n /// @dev Fee amounts may never be removed once enabled\n /// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6)\n /// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount\n function enableFeeAmount(uint24 fee, int24 tickSpacing) external;\n}\n" - }, - "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\npragma abicoder v2;\n\nimport '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface ISwapRouter is IUniswapV3SwapCallback {\n struct ExactInputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactOutputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);\n\n struct ExactOutputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Callback for IUniswapV3PoolActions#swap\n/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface\ninterface IUniswapV3SwapCallback {\n /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n /// @dev In the implementation you must pay the pool tokens owed for the swap.\n /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n function uniswapV3SwapCallback(\n int256 amount0Delta,\n int256 amount1Delta,\n bytes calldata data\n ) external;\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file diff --git a/deployments/ethereum/solcInputs/c13a9c9fec104b95e6c1800beae11ff9.json b/deployments/ethereum/solcInputs/c13a9c9fec104b95e6c1800beae11ff9.json deleted file mode 100644 index 8670d9a..0000000 --- a/deployments/ethereum/solcInputs/c13a9c9fec104b95e6c1800beae11ff9.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "solidity/contracts/DataFeed.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {PipelineManagement, Governable} from './peripherals/PipelineManagement.sol';\nimport {IDataFeed, IDataFeedStrategy, IUniswapV3Pool, IConnextSenderAdapter, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeed.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The DataFeed interface\n/// @notice Queries UniV3Pools, stores history proofs on chain, handles data broadcast\ncontract DataFeed is IDataFeed, PipelineManagement {\n /// @inheritdoc IDataFeed\n IDataFeedStrategy public strategy;\n\n /// @inheritdoc IDataFeed\n mapping(bytes32 => PoolState) public lastPoolStateObserved;\n\n mapping(bytes32 => bool) internal _observedKeccak;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(address _governor, IDataFeedStrategy _strategy) Governable(_governor) {\n _setStrategy(_strategy);\n }\n\n /// @inheritdoc IDataFeed\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external validatePipeline(_chainId, _poolSalt, _poolNonce) {\n (uint32 _destinationDomainId, address _dataReceiver) = validateSenderAdapter(_bridgeSenderAdapter, _chainId);\n\n {\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _poolNonce, _observationsData));\n if (!_observedKeccak[_resultingKeccak]) revert UnknownHash();\n }\n\n _bridgeSenderAdapter.bridgeObservations(_dataReceiver, _destinationDomainId, _observationsData, _poolSalt, _poolNonce);\n emit DataBroadcast(_poolSalt, _poolNonce, _chainId, _dataReceiver, _bridgeSenderAdapter);\n }\n\n /// @inheritdoc IDataFeed\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external onlyStrategy validatePool(_poolSalt) {\n IOracleSidechain.ObservationData[] memory _observationsData;\n PoolState memory _lastPoolStateObserved = lastPoolStateObserved[_poolSalt];\n\n {\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _tickCumulatives, ) = _pool.observe(_secondsAgos);\n\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _secondsAgo;\n int56 _tickCumulative;\n int24 _arithmeticMeanTick;\n uint256 _secondsAgosLength = _secondsAgos.length;\n uint256 _i;\n\n // If first fetched observation\n if (_lastPoolStateObserved.blockTimestamp == 0) {\n if (_secondsAgosLength == 1) revert InvalidSecondsAgos();\n // Initializes timestamp and cumulative with first item\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength - 1);\n _secondsAgo = _secondsAgos[0];\n _tickCumulative = _tickCumulatives[0];\n // Skips first loop iteration\n // Cannot not calculate twap (there is no last tickCumulative)\n unchecked {\n ++_i;\n }\n } else {\n // Initializes timestamp and cumulative with cache\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength);\n _secondsAgo = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n _tickCumulative = _lastPoolStateObserved.tickCumulative;\n }\n\n uint32 _delta;\n int56 _tickCumulativesDelta;\n uint256 _observationsDataIndex;\n\n for (; _i < _secondsAgosLength; ) {\n // Twap is calculated using the last recorded tickCumulative and time\n _tickCumulativesDelta = _tickCumulatives[_i] - _tickCumulative;\n _delta = _secondsAgo - _secondsAgos[_i];\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n\n // Stores blockTimestamp and tick in observations array\n _observationsData[_observationsDataIndex++] = IOracleSidechain.ObservationData({\n blockTimestamp: _secondsNow - _secondsAgo,\n tick: _arithmeticMeanTick\n });\n\n // Updates state for next iteration calculation\n _secondsAgo = _secondsAgos[_i];\n _tickCumulative = _tickCumulatives[_i];\n\n unchecked {\n ++_i;\n }\n }\n\n _lastPoolStateObserved = PoolState({\n poolNonce: _lastPoolStateObserved.poolNonce + 1,\n blockTimestamp: _secondsNow - _secondsAgo,\n tickCumulative: _tickCumulative,\n arithmeticMeanTick: _arithmeticMeanTick\n });\n }\n\n // Stores last pool state in the contract cache\n lastPoolStateObserved[_poolSalt] = _lastPoolStateObserved;\n\n // Whitelists keccak256 to be broadcast to other chains\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData));\n _observedKeccak[_resultingKeccak] = true;\n\n // Emits event with data to be read off-chain and used as broadcast input parameters\n emit PoolObserved(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData);\n }\n\n /// @inheritdoc IDataFeed\n function setStrategy(IDataFeedStrategy _strategy) external onlyGovernor {\n _setStrategy(_strategy);\n }\n\n function _setStrategy(IDataFeedStrategy _strategy) private {\n strategy = _strategy;\n emit StrategySet(_strategy);\n }\n\n modifier onlyStrategy() {\n if (msg.sender != address(strategy)) revert OnlyStrategy();\n _;\n }\n}\n" - }, - "solidity/contracts/peripherals/PipelineManagement.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './Governable.sol';\nimport {IPipelineManagement, IBridgeSenderAdapter} from '../../interfaces/peripherals/IPipelineManagement.sol';\nimport {IDataFeed} from '../../interfaces/IDataFeed.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\n\nabstract contract PipelineManagement is IPipelineManagement, Governable {\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n EnumerableSet.Bytes32Set private _whitelistedPools;\n\n /// @inheritdoc IPipelineManagement\n mapping(uint32 => mapping(bytes32 => uint24)) public whitelistedNonces;\n\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => bool) public whitelistedAdapters;\n\n // adapter => chainId => destinationDomain\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => uint32)) public destinationDomainIds;\n\n // adapter => destinationDomainId => dataReceiver\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => address)) public receivers;\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external onlyGovernor {\n _whitelistPipeline(_chainId, _poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external onlyGovernor {\n uint256 _chainIdsLength = _chainIds.length;\n if (_chainIdsLength != _poolSalts.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _chainIdsLength; ++_i) {\n _whitelistPipeline(_chainIds[_i], _poolSalts[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _whitelistAdapter(_bridgeSenderAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external onlyGovernor {\n _setDestinationDomainId(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _chainIds,\n uint32[] calldata _destinationDomainIds\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _chainIds.length || _bridgeSenderAdapterLength != _destinationDomainIds.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setDestinationDomainId(_bridgeSenderAdapters[_i], _chainIds[_i], _destinationDomainIds[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external onlyGovernor {\n _setReceiver(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _destinationDomainIds.length || _bridgeSenderAdapterLength != _dataReceivers.length)\n revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setReceiver(_bridgeSenderAdapters[_i], _destinationDomainIds[_i], _dataReceivers[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistedPools() external view returns (bytes32[] memory) {\n return _whitelistedPools.values();\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return _whitelistedPools.contains(_poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return whitelistedNonces[_chainId][_poolSalt] != 0;\n }\n\n /// @inheritdoc IPipelineManagement\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n public\n view\n returns (uint32 _destinationDomainId, address _dataReceiver)\n {\n if (!whitelistedAdapters[_bridgeSenderAdapter]) revert UnallowedAdapter();\n\n _destinationDomainId = destinationDomainIds[_bridgeSenderAdapter][_chainId];\n if (_destinationDomainId == 0) revert DestinationDomainIdNotSet();\n\n _dataReceiver = receivers[_bridgeSenderAdapter][_destinationDomainId];\n if (_dataReceiver == address(0)) revert ReceiverNotSet();\n }\n\n function _whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) internal {\n (uint24 _lastPoolNonceObserved, , , ) = IDataFeed(address(this)).lastPoolStateObserved(_poolSalt);\n whitelistedNonces[_chainId][_poolSalt] = _lastPoolNonceObserved + 1;\n _whitelistedPools.add(_poolSalt);\n emit PipelineWhitelisted(_chainId, _poolSalt, _lastPoolNonceObserved + 1);\n }\n\n function _whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_bridgeSenderAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n function _setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) internal {\n destinationDomainIds[_bridgeSenderAdapter][_chainId] = _destinationDomainId;\n emit DestinationDomainIdSet(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n function _setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) internal {\n receivers[_bridgeSenderAdapter][_destinationDomainId] = _dataReceiver;\n emit ReceiverSet(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n modifier validatePool(bytes32 _poolSalt) {\n if (!_whitelistedPools.contains(_poolSalt)) revert UnallowedPool();\n _;\n }\n\n modifier validatePipeline(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) {\n uint24 _whitelistedNonce = whitelistedNonces[_chainId][_poolSalt];\n if (_whitelistedNonce == 0) revert UnallowedPipeline();\n if (_whitelistedNonce > _poolNonce) revert WrongNonce();\n _;\n }\n}\n" - }, - "solidity/interfaces/IDataFeed.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IPipelineManagement} from './peripherals/IPipelineManagement.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IConnextSenderAdapter} from './bridges/IConnextSenderAdapter.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IDataFeed is IPipelineManagement {\n // STRUCTS\n\n struct PoolState {\n uint24 poolNonce; // Nonce of the last observation\n uint32 blockTimestamp; // Last observed timestamp\n int56 tickCumulative; // Pool's tickCumulative at last observed timestamp\n int24 arithmeticMeanTick; // Last calculated twap\n }\n\n // STATE VARIABLES\n\n /// @return _strategy Address of the contract allowed to trigger an oracle update\n /// @dev The strategy should define when and with which timestamps the pool should be read\n function strategy() external view returns (IDataFeedStrategy _strategy);\n\n /// @notice Tracks the last observed pool state by salt\n /// @param _poolSalt The id of both the oracle and the pool\n /// @return _lastPoolNonceObserved Nonce of the last observation\n /// @return _lastBlockTimestampObserved Last observed timestamp\n /// @return _lastTickCumulativeObserved Pool's tickCumulative at last observed timestamp\n /// @return _lastArithmeticMeanTickObserved Last calculated twap\n function lastPoolStateObserved(bytes32 _poolSalt)\n external\n view\n returns (\n uint24 _lastPoolNonceObserved,\n uint32 _lastBlockTimestampObserved,\n int56 _lastTickCumulativeObserved,\n int24 _lastArithmeticMeanTickObserved\n );\n\n // EVENTS\n\n /// @notice Emitted when a data batch is broadcast\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _dataReceiver Address of the targetted contract receiving the data\n /// @param _chainId Identifier number of the targetted chain\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n event DataBroadcast(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n uint32 _chainId,\n address _dataReceiver,\n IBridgeSenderAdapter _bridgeSenderAdapter\n );\n\n /// @notice Emitted when a data batch is observed\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n /// @param _observationsData Timestamp and tick data of the broadcast nonce\n event PoolObserved(bytes32 indexed _poolSalt, uint24 _poolNonce, IOracleSidechain.ObservationData[] _observationsData);\n\n /// @notice Emitted when the Strategy contract is set\n /// @param _strategy Address of the new strategy\n event StrategySet(IDataFeedStrategy _strategy);\n\n // ERRORS\n\n /// @notice Throws if set of secondsAgos is invalid to update the oracle\n error InvalidSecondsAgos();\n\n /// @notice Throws if an unknown dataset is being broadcast\n error UnknownHash();\n\n /// @notice Throws if a contract other than Strategy calls an update\n error OnlyStrategy();\n\n // FUNCTIONS\n\n /// @notice Broadcasts a validated set of datapoints to a bridge adapter\n /// @dev Permisionless, input parameters are validated to ensure being correct\n /// @param _bridgeSenderAdapter Address of the bridge adapter\n /// @param _chainId Identifier of the receiving chain\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _poolNonce Nonce identifier of the dataset\n /// @param _observationsData Array of tuples representing broadcast dataset\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Triggers an update of the oracle state\n /// @dev Permisioned, callable only by Strategy\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _secondsAgos Set of time periods to consult the pool with\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external;\n\n /// @notice Updates the Strategy address\n /// @dev Permisioned, callable only by Governor\n /// @param _strategy Address of the new Strategy\n function setStrategy(IDataFeedStrategy _strategy) external;\n}\n" - }, - "solidity/libraries/Create2Address.sol": { - "content": "//SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.8 <0.9.0;\n\n/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee\nlibrary Create2Address {\n /// @notice Deterministically computes the pool address given the factory, salt and initCodeHash\n /// @param _factory The Uniswap V3 factory contract address\n /// @param _salt The PoolKey encoded bytes\n /// @param _initCodeHash The Init Code Hash of the target\n /// @return _pool The contract address of the target pool/oracle\n function computeAddress(\n address _factory,\n bytes32 _salt,\n bytes32 _initCodeHash\n ) internal pure returns (address _pool) {\n _pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', _factory, _salt, _initCodeHash)))));\n }\n}\n" - }, - "solidity/contracts/peripherals/Governable.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public governor;\n\n /// @inheritdoc IGovernable\n address public pendingGovernor;\n\n constructor(address _governor) {\n if (_governor == address(0)) revert ZeroAddress();\n governor = _governor;\n }\n\n /// @inheritdoc IGovernable\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\n _setPendingGovernor(_pendingGovernor);\n }\n\n /// @inheritdoc IGovernable\n function acceptPendingGovernor() external onlyPendingGovernor {\n _acceptPendingGovernor();\n }\n\n function _setPendingGovernor(address _pendingGovernor) internal {\n if (_pendingGovernor == address(0)) revert ZeroAddress();\n pendingGovernor = _pendingGovernor;\n emit PendingGovernorSet(governor, pendingGovernor);\n }\n\n function _acceptPendingGovernor() internal {\n governor = pendingGovernor;\n pendingGovernor = address(0);\n emit PendingGovernorAccepted(governor);\n }\n\n modifier onlyGovernor() {\n if (msg.sender != governor) revert OnlyGovernor();\n _;\n }\n\n modifier onlyPendingGovernor() {\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\n _;\n }\n}\n" - }, - "solidity/interfaces/peripherals/IPipelineManagement.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './IGovernable.sol';\nimport {IBridgeSenderAdapter} from '../bridges/IBridgeSenderAdapter.sol';\n\ninterface IPipelineManagement is IGovernable {\n // STATE VARIABLES\n\n function whitelistedNonces(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _whitelistedNonce);\n\n function whitelistedAdapters(IBridgeSenderAdapter _bridgeSenderAdapter) external view returns (bool _isWhitelisted);\n\n function destinationDomainIds(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId) external view returns (uint32 _destinationDomainId);\n\n function receivers(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId) external view returns (address _dataReceiver);\n\n // EVENTS\n\n event PipelineWhitelisted(uint32 _chainId, bytes32 indexed _poolSalt, uint24 _whitelistedNonce);\n\n event AdapterWhitelisted(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted);\n\n event DestinationDomainIdSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId, uint32 _destinationDomainId);\n\n event ReceiverSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId, address _dataReceiver);\n\n // ERRORS\n\n error UnallowedPool();\n\n error UnallowedPipeline();\n\n error WrongNonce();\n\n error UnallowedAdapter();\n\n error DestinationDomainIdNotSet();\n\n error ReceiverNotSet();\n\n error LengthMismatch();\n\n // FUNCTIONS\n\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external;\n\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external;\n\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external;\n\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external;\n\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external;\n\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapter,\n uint32[] calldata _chainId,\n uint32[] calldata _destinationDomainId\n ) external;\n\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external;\n\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external;\n\n function whitelistedPools() external view returns (bytes32[] memory);\n\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n external\n view\n returns (uint32 _destinationDomainId, address _dataReceiver);\n}\n" - }, - "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 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 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 => 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 return _values(set._inner);\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 on 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" - }, - "solidity/interfaces/peripherals/IGovernable.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\ninterface IGovernable {\n // STATE VARIABLES\n\n /// @return _governor Address of the current governor\n function governor() external view returns (address _governor);\n\n /// @return _pendingGovernor Address of the current pending governor\n function pendingGovernor() external view returns (address _pendingGovernor);\n\n // EVENTS\n\n /// @notice Emitted when a new pending governor is set\n /// @param _governor Address of the current governor\n /// @param _pendingGovernor Address of the proposed next governor\n event PendingGovernorSet(address _governor, address _pendingGovernor);\n\n /// @notice Emitted when a new governor is set\n /// @param _newGovernor Address of the new governor\n event PendingGovernorAccepted(address _newGovernor);\n\n // ERRORS\n\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n\n /// @notice Throws if a non-governor user tries to call a OnlyGovernor function\n error OnlyGovernor();\n\n /// @notice Throws if a non-pending-governor user tries to call a OnlyPendingGovernor function\n error OnlyPendingGovernor();\n\n // FUNCTIONS\n\n /// @notice Allows a governor to propose a new governor\n /// @param _pendingGovernor Address of the proposed new governor\n function setPendingGovernor(address _pendingGovernor) external;\n\n /// @notice Allows a proposed governor to accept the governance\n function acceptPendingGovernor() external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeSenderAdapter {\n // FUNCTIONS\n\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable;\n\n // ERRORS\n\n error OnlyDataFeed();\n}\n" - }, - "solidity/interfaces/IOracleSidechain.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleFactory} from './IOracleFactory.sol';\n\ninterface IOracleSidechain {\n // STRUCTS\n\n struct ObservationData {\n uint32 blockTimestamp;\n int24 tick;\n }\n\n // STATE VARIABLES\n\n // TODO: complete natspec\n\n /// @return _oracleFactory The address of the OracleFactory\n function factory() external view returns (IOracleFactory _oracleFactory);\n\n /// @return _token0 The mainnet address of the Token0 of the oracle\n function token0() external view returns (address _token0);\n\n /// @return _token1 The mainnet address of the Token1 of the oracle\n function token1() external view returns (address _token1);\n\n /// @return _fee The fee identifier of the pool\n function fee() external view returns (uint24 _fee);\n\n /// @return _poolSalt The identifier of both the pool and the oracle\n function poolSalt() external view returns (bytes32 _poolSalt);\n\n /// @return _poolNonce Last recorded nonce of the pool history\n function poolNonce() external view returns (uint24 _poolNonce);\n\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\n /// @return _tick Used to maintain compatibility with Uniswap V3\n /// @return _observationIndex The index of the last oracle observation that was written,\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\n /// @return _unlocked Used to track if a pool information was already verified\n function slot0()\n external\n view\n returns (\n uint160 _sqrtPriceX96,\n int24 _tick,\n uint16 _observationIndex,\n uint16 _observationCardinality,\n uint16 _observationCardinalityNext,\n uint8 _feeProtocol,\n bool _unlocked\n );\n\n /// @notice Returns data about a specific observation index\n /// @param _index The element of the observations array to fetch\n /// @return _blockTimestamp The timestamp of the observation,\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return _initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 _index)\n external\n view\n returns (\n uint32 _blockTimestamp,\n int56 _tickCumulative,\n uint160 _secondsPerLiquidityCumulativeX128,\n bool _initialized\n );\n\n // EVENTS\n\n /// @notice Emitted when the pool information is verified\n /// @param _poolSalt Identifier of the pool and the oracle\n /// @param _token0 The contract address of either token0 or token1\n /// @param _token1 The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\n\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param _tick The log base 1.0001 of price of the pool after the swap\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\n\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\n\n // ERRORS\n\n error AI();\n error InvalidPool();\n error OnlyDataReceiver();\n error OnlyFactory();\n\n // FUNCTIONS\n\n /// @notice Permisionless method to verify token0, token1 and fee\n /// @dev Before verified, token0 and token1 views will return address(0)\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external;\n\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\n\n /// @notice Permisioned method to push a dataset to update\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolNonce Nonce of the observation broadcast\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\n\n /// @notice Permisioned method to increase the cardinalityNext value\n /// @param _observationCardinalityNext The new next length of the observations array\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\n}\n" - }, - "solidity/interfaces/IOracleFactory.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IDataReceiver} from './IDataReceiver.sol';\n\ninterface IOracleFactory is IGovernable {\n // STRUCTS\n\n struct OracleParameters {\n bytes32 poolSalt; // Identifier of the pool and oracle\n uint24 poolNonce; // Initial nonce of the deployed pool\n uint16 cardinality; // Initial cardinality of the deployed pool\n }\n\n // STATE VARIABLES\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /// @return _poolSalt The id of both the oracle and the pool\n /// @return _poolNonce The initial nonce of the pool data\n /// @return _cardinality The size of the observations memory storage\n function oracleParameters()\n external\n view\n returns (\n bytes32 _poolSalt,\n uint24 _poolNonce,\n uint16 _cardinality\n );\n\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function initialCardinality() external view returns (uint16 _initialCardinality);\n\n // EVENTS\n\n /// @notice Emitted when a new oracle is deployed\n /// @param _poolSalt The id of both the oracle and the pool\n /// @param _oracle The address of the deployed oracle\n /// @param _initialNonce The initial nonce of the pool data\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\n\n /// @notice Emitted when a new DataReceiver is set\n /// @param _dataReceiver The address of the new DataReceiver\n event DataReceiverSet(IDataReceiver _dataReceiver);\n\n /// @notice Emitted when a new initial oracle cardinality is set\n /// @param _initialCardinality The initial length of the observationCardinality array\n event InitialCardinalitySet(uint16 _initialCardinality);\n\n // ERRORS\n\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\n error OnlyDataReceiver();\n\n // FUNCTIONS\n\n /// @notice Deploys a new oracle given an inputted salt\n /// @dev Requires that the salt has not been deployed before\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\n /// @return _oracle The address of the newly deployed oracle\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\n\n /// @notice Allows governor to set a new allowed dataReceiver\n /// @dev Will disallow the previous dataReceiver\n /// @param _dataReceiver The address of the new allowed dataReceiver\n function setDataReceiver(IDataReceiver _dataReceiver) external;\n\n /// @notice Allows governor to set a new initial cardinality for new oracles\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function setInitialCardinality(uint16 _initialCardinality) external;\n\n /// @notice Overrides UniV3Factory getPool mapping\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _oracle The oracle address\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle);\n\n /// @notice Tracks the addresses of the oracle by poolSalt\n /// @param _poolSalt Identifier of both the pool and the oracle\n /// @return _oracle The address (if deployed) of the correspondant oracle\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\n\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _poolSalt Pool salt for inquired parameters\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (bytes32 _poolSalt);\n}\n" - }, - "solidity/interfaces/IDataReceiver.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IOracleFactory} from './IOracleFactory.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\n\ninterface IDataReceiver is IGovernable {\n // STATE VARIABLES\n\n /// @return _oracleFactory The address of the OracleFactory\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\n\n /// @notice Tracks already deployed oracles\n /// @param _poolSalt The identifier of the oracle\n /// @return _deployedOracle The address of the correspondant Oracle\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\n\n /// @notice Tracks the whitelisting of bridge adapters\n /// @param _adapter Address of the bridge adapter to consult\n /// @return _isAllowed Whether a bridge adapter is whitelisted\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n // EVENTS\n\n /// @notice Emitted when a broadcast observation is succesfully processed\n /// @param _poolSalt Identifier of the pool to fetch\n /// @return _poolNonce Nonce of the observation broadcast\n /// @return _observationsData Array of tuples containing the dataset\n /// @return _receiverAdapter Handler of the broadcast\n event ObservationsAdded(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] _observationsData,\n address _receiverAdapter\n );\n\n /// @notice Emitted when a new adapter whitelisting rule is set\n /// @param _adapter Address of the adapter\n /// @param _isAllowed New whitelisting status\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\n\n // ERRORS\n\n /// @notice Thrown when the broadcast nonce is incorrect\n error ObservationsNotWritable();\n\n /// @notice Thrown when a not-whitelisted adapter triggers an update\n error UnallowedAdapter();\n\n /// @notice Thrown when mismatching lists length\n error LengthMismatch();\n\n // FUNCTIONS\n\n /// @notice Allows whitelisted bridge adapters to push a broadcast\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _poolNonce Nonce of the observation broadcast\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external;\n\n /// @notice Allows governance to set an adapter whitelisted state\n /// @param _receiverAdapter Address of the adapter\n /// @param _isWhitelisted New whitelisting status\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\n\n /// @notice Allows governance to batch set adapters whitelisted state\n /// @param _receiverAdapters Array of addresses of the adapter\n /// @param _isWhitelisted Array of whitelisting status for each address\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IDataReceiver} from '../IDataReceiver.sol';\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeReceiverAdapter {\n // FUNCTIONS\n\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /* NOTE: callback methods should be here declared */\n\n // ERRORS\n\n error UnauthorizedCaller();\n}\n" - }, - "solidity/interfaces/IDataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\n\ninterface IDataFeedStrategy is IGovernable {\n // ENUMS\n\n enum TriggerReason {\n NONE,\n TIME,\n TWAP\n }\n\n // STRUCTS\n\n struct StrategySettings {\n uint32 periodDuration; // Resolution of the oracle, target twap length\n uint32 cooldown; // Time since last update to wait to time-trigger update\n uint24 twapThreshold; // Twap difference, in ticks, to twap-trigger update\n uint32 twapLength; // Twap length, in seconds, used for twap-trigger update\n }\n\n // STATE VARIABLES\n\n /// @return _dataFeed The address of the DataFeed contract\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _strategyCooldown Time in seconds since last update required to time-trigger an update\n function strategyCooldown() external view returns (uint32 _strategyCooldown);\n\n /// @return _periodDuration The targetted amount of seconds between pool consultations\n /// @dev Defines the resolution of the oracle, averaging data between consultations\n function periodDuration() external view returns (uint32 _periodDuration);\n\n /// @return _twapThreshold Twap difference, in ticks, to twap-trigger an update\n function twapThreshold() external view returns (uint24 _twapThreshold);\n\n /// @return _twapLength The time length, in seconds, used to calculate twap-trigger\n function twapLength() external view returns (uint32 _twapLength);\n\n // EVENTS\n\n /// @notice Emitted when a data fetch is triggered\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier number of the reason that triggered the fetch request\n event StrategicFetch(bytes32 indexed _poolSalt, TriggerReason _reason);\n\n /// @notice Emitted when the owner updates the job cooldown\n /// @param _strategyCooldown The new job cooldown\n event StrategyCooldownSet(uint32 _strategyCooldown);\n\n /// @notice Emitted when the owner updates the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n event TwapLengthSet(uint32 _twapLength);\n\n /// @notice Emitted when the owner updates the job twap threshold percentage\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n event TwapThresholdSet(uint24 _twapThreshold);\n\n /// @notice Emitted when the owner updates the job period length\n /// @param _periodDuration The new length of reading resolution periods\n event PeriodDurationSet(uint32 _periodDuration);\n\n // ERRORS\n\n /// @notice Thrown if the tx is not strategic\n error NotStrategic();\n\n /// @notice Thrown if setting breaks strategyCooldown >= twapLength >= periodDuration\n error WrongSetting();\n\n // FUNCTIONS\n\n /// @notice Permisionless, used to update the oracle state\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier of trigger reason (time/twap)\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external;\n\n /// @notice Permisioned, used to update the oracle state from a given timestamp\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _fromTimestamp Timestamp to start backfilling from\n function forceFetchObservations(bytes32 _poolSalt, uint32 _fromTimestamp) external;\n\n /// @notice Sets the job cooldown\n /// @param _strategyCooldown The job cooldown to be set\n function setStrategyCooldown(uint32 _strategyCooldown) external;\n\n /// @notice Sets the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n function setTwapLength(uint32 _twapLength) external;\n\n /// @notice Sets the job twap threshold percentage\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n function setTwapThreshold(uint24 _twapThreshold) external;\n\n /// @notice Sets the job period length\n /// @param _periodDuration The new length of reading resolution periods\n function setPeriodDuration(uint32 _periodDuration) external;\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the strategy can be executed\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason);\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the strategy can be executed\n /// @return _isStrategic Whether the tx is strategic or not\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) external view returns (bool _isStrategic);\n\n /// @notice Builds the secondsAgos array with periodDuration between each datapoint\n /// @param _fromTimestamp Timestamp from which to backfill the oracle with\n /// @return _secondsAgos Array of secondsAgo that backfills the history from fromTimestamp\n function calculateSecondsAgos(uint32 _fromTimestamp) external view returns (uint32[] memory _secondsAgos);\n}\n" - }, - "solidity/interfaces/bridges/IConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeSenderAdapter, IOracleSidechain} from './IBridgeSenderAdapter.sol';\nimport {IDataFeed} from '../IDataFeed.sol';\n\ninterface IConnextSenderAdapter is IBridgeSenderAdapter {\n // STATE VARIABLES\n\n function connext() external view returns (IConnext _connext);\n\n function dataFeed() external view returns (IDataFeed _dataFeed);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport {IUniswapV3PoolImmutables} from './pool/IUniswapV3PoolImmutables.sol';\nimport {IUniswapV3PoolState} from './pool/IUniswapV3PoolState.sol';\nimport {IUniswapV3PoolDerivedState} from './pool/IUniswapV3PoolDerivedState.sol';\nimport {IUniswapV3PoolActions} from './pool/IUniswapV3PoolActions.sol';\nimport {IUniswapV3PoolOwnerActions} from './pool/IUniswapV3PoolOwnerActions.sol';\nimport {IUniswapV3PoolErrors} from './pool/IUniswapV3PoolErrors.sol';\nimport {IUniswapV3PoolEvents} from './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolErrors,\n IUniswapV3PoolEvents\n{\n\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// @return tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// @return observationIndex The index of the last oracle observation that was written,\n /// @return observationCardinality The current maximum number of observations stored in the pool,\n /// @return observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n /// @return The liquidity at the current price of the pool\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper\n /// @return liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// @return feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// @return feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// @return tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// @return secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// @return secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// @return initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return liquidity The amount of liquidity in the position,\n /// @return feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// @return feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// @return tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// @return tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// @return tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolErrors.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Errors emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolErrors {\n error LOK();\n error TLU();\n error TLM();\n error TUM();\n error AI();\n error M0();\n error M1();\n error AS();\n error IIA();\n error L();\n error F0();\n error F1();\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {ExecuteArgs, TransferInfo, TokenId, DestinationTransferStatus} from \"../libraries/LibConnextStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {SwapUtils} from \"../libraries/SwapUtils.sol\";\n\nimport {IStableSwap} from \"./IStableSwap.sol\";\n\nimport {IDiamondCut} from \"./IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\ninterface IConnext is IDiamondLoupe, IDiamondCut {\n // TokenFacet\n function canonicalToAdopted(bytes32 _key) external view returns (address);\n\n function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\n\n function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\n\n function canonicalToRepresentation(bytes32 _key) external view returns (address);\n\n function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\n\n function representationToCanonical(address _adopted) external view returns (TokenId memory);\n\n function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\n\n function approvedAssets(bytes32 _key) external view returns (bool);\n\n function approvedAssets(TokenId calldata _canonical) external view returns (bool);\n\n function adoptedToLocalPools(bytes32 _key) external view returns (IStableSwap);\n\n function adoptedToLocalPools(TokenId calldata _canonical) external view returns (IStableSwap);\n\n function getTokenId(address _candidate) external view returns (TokenId memory);\n\n function setupAsset(\n TokenId calldata _canonical,\n uint8 _canonicalDecimals,\n string memory _representationName,\n string memory _representationSymbol,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function setupAssetWithDeployedRepresentation(\n TokenId calldata _canonical,\n address _representation,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\n\n function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\n\n function removeAssetId(\n bytes32 _key,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function removeAssetId(\n TokenId calldata _canonical,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function updateDetails(\n TokenId calldata _canonical,\n string memory _name,\n string memory _symbol\n ) external;\n\n // BaseConnextFacet\n\n // BridgeFacet\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\n\n function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\n\n function remote(uint32 _domain) external view returns (address);\n\n function domain() external view returns (uint256);\n\n function nonce() external view returns (uint256);\n\n function approvedSequencers(address _sequencer) external view returns (bool);\n\n function xAppConnectionManager() external view returns (address);\n\n function addConnextion(uint32 _domain, address _connext) external;\n\n function addSequencer(address _sequencer) external;\n\n function removeSequencer(address _sequencer) external;\n\n function xcall(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function xcallIntoLocal(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\n\n function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\n\n function bumpTransfer(bytes32 _transferId) external payable;\n\n function setXAppConnectionManager(address _xAppConnectionManager) external;\n\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n function enrollCustom(\n uint32 _domain,\n bytes32 _id,\n address _custom\n ) external;\n\n // InboxFacet\n\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external;\n\n // ProposedOwnableFacet\n\n function owner() external view returns (address);\n\n function routerWhitelistRemoved() external view returns (bool);\n\n function assetWhitelistRemoved() external view returns (bool);\n\n function proposed() external view returns (address);\n\n function proposedTimestamp() external view returns (uint256);\n\n function routerWhitelistTimestamp() external view returns (uint256);\n\n function assetWhitelistTimestamp() external view returns (uint256);\n\n function delay() external view returns (uint256);\n\n function proposeRouterWhitelistRemoval() external;\n\n function removeRouterWhitelist() external;\n\n function proposeAssetWhitelistRemoval() external;\n\n function removeAssetWhitelist() external;\n\n function renounced() external view returns (bool);\n\n function proposeNewOwner(address newlyProposed) external;\n\n function renounceOwnership() external;\n\n function acceptProposedOwner() external;\n\n function pause() external;\n\n function unpause() external;\n\n // RelayerFacet\n function approvedRelayers(address _relayer) external view returns (bool);\n\n function relayerFeeVault() external view returns (address);\n\n function setRelayerFeeVault(address _relayerFeeVault) external;\n\n function addRelayer(address _relayer) external;\n\n function removeRelayer(address _relayer) external;\n\n // RoutersFacet\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\n\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\n\n function getRouterApproval(address _router) external view returns (bool);\n\n function getRouterRecipient(address _router) external view returns (address);\n\n function getRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\n\n function maxRoutersPerTransfer() external view returns (uint256);\n\n function routerBalances(address _router, address _asset) external view returns (uint256);\n\n function getRouterApprovalForPortal(address _router) external view returns (bool);\n\n function setupRouter(\n address router,\n address owner,\n address recipient\n ) external;\n\n function removeRouter(address router) external;\n\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\n\n function setLiquidityFeeNumerator(uint256 _numerator) external;\n\n function approveRouterForPortal(address _router) external;\n\n function unapproveRouterForPortal(address _router) external;\n\n function setRouterRecipient(address router, address recipient) external;\n\n function proposeRouterOwner(address router, address proposed) external;\n\n function acceptProposedRouterOwner(address router) external;\n\n function addRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address _router\n ) external payable;\n\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\n\n function removeRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address payable _to,\n address _router\n ) external;\n\n function removeRouterLiquidity(\n uint256 _amount,\n address _local,\n address payable _to\n ) external;\n\n // PortalFacet\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\n\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\n\n function aavePool() external view returns (address);\n\n function aavePortalFee() external view returns (uint256);\n\n function setAavePool(address _aavePool) external;\n\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\n\n function repayAavePortal(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount,\n uint256 _maxIn\n ) external;\n\n function repayAavePortalFor(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount\n ) external;\n\n // StableSwapFacet\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\n\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\n\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\n\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\n\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\n\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\n\n function calculateSwap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapTokenAmount(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n bool deposit\n ) external view returns (uint256);\n\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) external view returns (uint256);\n\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\n\n function swap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n bytes32 canonicalId,\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n bytes32 canonicalId,\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function addSwapLiquidity(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidity(\n bytes32 canonicalId,\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidityImbalance(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n\n // SwapAdminFacet\n\n function initializeSwap(\n bytes32 _canonicalId,\n IERC20[] memory _pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 _a,\n uint256 _fee,\n uint256 _adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\n\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\n\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\n\n function rampA(\n bytes32 canonicalId,\n uint256 futureA,\n uint256 futureTime\n ) external;\n\n function stopRampA(bytes32 canonicalId) external;\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= 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 > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\nimport {IConnectorManager} from \"../../../messaging/interfaces/IConnectorManager.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n// ============= Enum =============\n\n/// @notice Enum representing address role\n// Returns uint\n// None - 0\n// Router - 1\n// Watcher - 2\n// Admin - 3\nenum Role {\n None,\n Router,\n Watcher,\n Admin\n}\n\n/**\n * @notice Enum representing status of destination transfer\n * @dev Status is only assigned on the destination domain, will always be \"none\" for the\n * origin domains\n * @return uint - Index of value in enum\n */\nenum DestinationTransferStatus {\n None, // 0\n Reconciled, // 1\n Executed, // 2\n Completed // 3 - executed + reconciled\n}\n\n// ============= Structs =============\n\nstruct TokenId {\n uint32 domain;\n bytes32 id;\n}\n\n/**\n * @notice These are the parameters that will remain constant between the\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\n * @property to - The account that receives funds, in the event of a crosschain call,\n * will receive funds if the call fails.\n *\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\n * @param canonicalDomain - The canonical domain of the asset you are bridging\n * @param to - The address you are sending funds (and potentially data) to\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\n * a user takes 1% slippage, this is expressed as 1_000)\n * @param originSender - The msg.sender of the xcall\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\n */\nstruct TransferInfo {\n uint32 originDomain;\n uint32 destinationDomain;\n uint32 canonicalDomain;\n address to;\n address delegate;\n bool receiveLocal;\n bytes callData;\n uint256 slippage;\n address originSender;\n uint256 bridgedAmt;\n uint256 normalizedIn;\n uint256 nonce;\n bytes32 canonicalId;\n}\n\n/**\n * @notice\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\n * @param routers - The routers who you are sending the funds on behalf of.\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\n * for the signed transfer ID.\n * @param sequencer - The sequencer who assigned the router path to this transfer.\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\n * for the path that was signed.\n */\nstruct ExecuteArgs {\n TransferInfo params;\n address[] routers;\n bytes[] routerSignatures;\n address sequencer;\n bytes sequencerSignature;\n}\n\n/**\n * @notice Contains RouterFacet related state\n * @param approvedRouters - Mapping of whitelisted router addresses\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\n * (if configured) or the router itself\n * @param routerOwners - Mapping of router owners\n * If set, can update the routerRecipient\n * @param proposedRouterOwners - Mapping of proposed router owners\n * Must wait timeout to set the\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\n * When accepting a proposed owner, must wait for delay to elapse\n */\nstruct RouterPermissionsManagerInfo {\n mapping(address => bool) approvedRouters;\n mapping(address => bool) approvedForPortalRouters;\n mapping(address => address) routerRecipients;\n mapping(address => address) routerOwners;\n mapping(address => address) proposedRouterOwners;\n mapping(address => uint256) proposedRouterTimestamp;\n}\n\nstruct AppStorage {\n //\n // 0\n bool initialized;\n //\n // Connext\n //\n // 1\n uint256 LIQUIDITY_FEE_NUMERATOR;\n /**\n * @notice The local address that is custodying relayer fees\n */\n // 2\n address relayerFeeVault;\n /**\n * @notice Nonce for the contract, used to keep unique transfer ids.\n * @dev Assigned at first interaction (xcall on origin domain).\n */\n // 3\n uint256 nonce;\n /**\n * @notice The domain this contract exists on.\n * @dev Must match the nomad domain, which is distinct from the \"chainId\".\n */\n // 4\n uint32 domain;\n /**\n * @notice Mapping holding the AMMs for swapping in and out of local assets.\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon).\n * This mapping is keyed on the hash of the canonical id + domain for local asset.\n */\n // 6\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\n /**\n * @notice Mapping of whitelisted assets on same domain as contract.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => bool) approvedAssets;\n /**\n * @notice Mapping of liquidity caps of whitelisted assets. If 0, no cap is enforced.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => uint256) caps;\n /**\n * @notice Mapping of adopted to canonical asset information.\n * @dev If the adopted asset is the native asset, the keyed address will\n * be the wrapped asset address.\n */\n // 8\n mapping(address => TokenId) adoptedToCanonical;\n /**\n * @notice Mapping of representation to canonical asset information.\n */\n // 9\n mapping(address => TokenId) representationToCanonical;\n /**\n * @notice Mapping of hash(canonicalId, canonicalDomain) to adopted asset on this domain.\n * @dev If the adopted asset is the native asset, the stored address will be the\n * wrapped asset address.\n */\n // 10\n mapping(bytes32 => address) canonicalToAdopted;\n /**\n * @notice Mapping of canonical to representation asset information.\n * @dev If the token is of local origin (meaning it was originanlly deployed on this chain),\n * this MUST map to address(0).\n */\n // 11\n mapping(bytes32 => address) canonicalToRepresentation;\n /**\n * @notice Mapping to track transfer status on destination domain\n */\n // 12\n mapping(bytes32 => DestinationTransferStatus) transferStatus;\n /**\n * @notice Mapping holding router address that provided fast liquidity.\n */\n // 13\n mapping(bytes32 => address[]) routedTransfers;\n /**\n * @notice Mapping of router to available balance of an asset.\n * @dev Routers should always store liquidity that they can expect to receive via the bridge on\n * this domain (the nomad local asset).\n */\n // 14\n mapping(address => mapping(address => uint256)) routerBalances;\n /**\n * @notice Mapping of approved relayers\n * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\n */\n // 15\n mapping(address => bool) approvedRelayers;\n /**\n * @notice The max amount of routers a payment can be routed through.\n */\n // 18\n uint256 maxRoutersPerTransfer;\n /**\n * @notice Stores a mapping of transfer id to slippage overrides.\n */\n // 20\n mapping(bytes32 => uint256) slippage;\n /**\n * @notice Stores a mapping of remote routers keyed on domains.\n * @dev Addresses are cast to bytes32.\n * This mapping is required because the Connext now contains the BridgeRouter and must implement\n * the remotes interface.\n */\n // 21\n mapping(uint32 => bytes32) remotes;\n //\n // ProposedOwnable\n //\n // 22\n address _proposed;\n // 23\n uint256 _proposedOwnershipTimestamp;\n // 24\n bool _routerWhitelistRemoved;\n // 25\n uint256 _routerWhitelistTimestamp;\n // 26\n bool _assetWhitelistRemoved;\n // 27\n uint256 _assetWhitelistTimestamp;\n /**\n * @notice Stores a mapping of address to Roles\n * @dev returns uint representing the enum Role value\n */\n // 28\n mapping(address => Role) roles;\n //\n // RouterFacet\n //\n // 29\n RouterPermissionsManagerInfo routerPermissionInfo;\n //\n // ReentrancyGuard\n //\n // 30\n uint256 _status;\n //\n // StableSwap\n //\n /**\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\n * Struct storing data responsible for automatic market maker functionalities. In order to\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\n */\n // 31\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\n /**\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\n */\n // 32\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\n /**\n * @notice Stores whether or not bribing, AMMs, have been paused.\n */\n // 33\n bool _paused;\n //\n // AavePortals\n //\n /**\n * @notice Address of Aave Pool contract.\n */\n // 34\n address aavePool;\n /**\n * @notice Fee percentage numerator for using Portal liquidity.\n * @dev Assumes the same basis points as the liquidity fee.\n */\n // 35\n uint256 aavePortalFeeNumerator;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 36\n mapping(bytes32 => uint256) portalDebt;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 37\n mapping(bytes32 => uint256) portalFeeDebt;\n /**\n * @notice Mapping of approved sequencers\n * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\n * for the fast liquidity route.\n */\n // 38\n mapping(address => bool) approvedSequencers;\n /**\n * @notice Remote connection manager for xapp.\n */\n // 39\n IConnectorManager xAppConnectionManager;\n}\n\nlibrary LibConnextStorage {\n function connextStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n // hash of proposed facets => acceptance time\n mapping(bytes32 => uint256) acceptanceTimes;\n // acceptance delay for upgrading facets\n uint256 acceptanceDelay;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function acceptanceDelay() internal view returns (uint256) {\n return diamondStorage().acceptanceDelay;\n }\n\n function acceptanceTime(bytes32 _key) internal view returns (uint256) {\n return diamondStorage().acceptanceTimes[_key];\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, \"LibDiamond: !contract owner\");\n }\n\n event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n function proposeDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 acceptance = block.timestamp + ds.acceptanceDelay;\n ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\n emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\n }\n\n event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n function rescindDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\n // period or befor the delay elpases\n diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = 0;\n emit DiamondCutRescinded(_diamondCut, _init, _calldata);\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n if (ds.facetAddresses.length != 0) {\n uint256 time = ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\n require(time != 0 && time <= block.timestamp, \"LibDiamond: delay not elapsed\");\n } // Otherwise, this is the first instance of deployment and it can be set automatically\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress != _facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, \"LibDiamondCut: New facet has no code\");\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n require(_calldata.length == 0, \"LibDiamondCut: _init is address(0) but_calldata is not empty\");\n } else {\n require(_calldata.length != 0, \"LibDiamondCut: _calldata is empty but _init is not address(0)\");\n if (_init != address(this)) {\n enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");\n }\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length != 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize != 0, _errorMessage);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IStableSwap {\n /*** EVENTS ***/\n\n // events replicated from SwapUtils to make the ABI easier for dumb\n // clients\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\n event AddLiquidity(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(uint256 newAdminFee);\n event NewSwapFee(uint256 newSwapFee);\n event NewWithdrawFee(uint256 newWithdrawFee);\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n function swap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function getA() external view returns (uint256);\n\n function getToken(uint8 index) external view returns (IERC20);\n\n function getTokenIndex(address tokenAddress) external view returns (uint8);\n\n function getTokenBalance(uint8 index) external view returns (uint256);\n\n function getVirtualPrice() external view returns (uint256);\n\n // min return calculation functions\n function calculateSwap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapOut(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) external view returns (uint256);\n\n function calculateSwapFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountIn\n ) external view returns (uint256);\n\n function calculateSwapOutFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountOut\n ) external view returns (uint256);\n\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\n\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\n external\n view\n returns (uint256 availableTokenAmount);\n\n // state modifying functions\n function initialize(\n IERC20[] memory pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 a,\n uint256 fee,\n uint256 adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function addLiquidity(\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidity(\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeLiquidityOneToken(\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidityImbalance(\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function proposeDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function rescindDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20, IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {LPToken} from \"../helpers/LPToken.sol\";\n\nimport {AmplificationUtils} from \"./AmplificationUtils.sol\";\nimport {MathUtils} from \"./MathUtils.sol\";\n\n/**\n * @title SwapUtils library\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\n * Admin functions should be protected within contracts using this library.\n */\nlibrary SwapUtils {\n using SafeERC20 for IERC20;\n using MathUtils for uint256;\n\n /*** EVENTS ***/\n\n event TokenSwap(\n bytes32 indexed key,\n address indexed buyer,\n uint256 tokensSold,\n uint256 tokensBought,\n uint128 soldId,\n uint128 boughtId\n );\n event AddLiquidity(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n bytes32 indexed key,\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\n event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\n\n struct Swap {\n // variables around the ramp management of A,\n // the amplification coefficient * n * (n - 1)\n // see https://www.curve.fi/stableswap-paper.pdf for details\n bytes32 key;\n uint256 initialA;\n uint256 futureA;\n uint256 initialATime;\n uint256 futureATime;\n // fee calculation\n uint256 swapFee;\n uint256 adminFee;\n LPToken lpToken;\n // contract references for all tokens being pooled\n IERC20[] pooledTokens;\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\n uint256[] tokenPrecisionMultipliers;\n // the pool balance of each token, in the token's precision\n // the contract's actual token balance might differ\n uint256[] balances;\n // the admin fee balance of each token, in the token's precision\n uint256[] adminFees;\n }\n\n // Struct storing variables used in calculations in the\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\n struct CalculateWithdrawOneTokenDYInfo {\n uint256 d0;\n uint256 d1;\n uint256 newY;\n uint256 feePerToken;\n uint256 preciseA;\n }\n\n // Struct storing variables used in calculations in the\n // {add,remove}Liquidity functions to avoid stack too deep errors\n struct ManageLiquidityInfo {\n uint256 d0;\n uint256 d1;\n uint256 d2;\n uint256 preciseA;\n LPToken lpToken;\n uint256 totalSupply;\n uint256[] balances;\n uint256[] multipliers;\n }\n\n // the precision all pools tokens will be converted to\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\n\n // the denominator used to calculate admin and LP fees. For example, an\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\n uint256 internal constant FEE_DENOMINATOR = 1e10;\n\n // Max swap fee is 1% or 100bps of each swap\n uint256 internal constant MAX_SWAP_FEE = 1e8;\n\n // Max adminFee is 100% of the swapFee\n // adminFee does not add additional fee on top of swapFee\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\n // users but only on the earnings of LPs\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\n\n // Constant value used as max loop limit\n uint256 internal constant MAX_LOOP_LIMIT = 256;\n\n /*** VIEW & PURE FUNCTIONS ***/\n\n function _getAPrecise(Swap storage self) private view returns (uint256) {\n return AmplificationUtils._getAPrecise(self);\n }\n\n /**\n * @notice Calculate the dy, the amount of selected token that user receives and\n * the fee of withdrawing in one token\n * @param tokenAmount the amount to withdraw in the pool's precision\n * @param tokenIndex which token will be withdrawn\n * @param self Swap struct to read from\n * @return the amount of token user will receive\n */\n function calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) internal view returns (uint256) {\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\n self,\n tokenAmount,\n tokenIndex,\n self.lpToken.totalSupply()\n );\n return availableTokenAmount;\n }\n\n function _calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 totalSupply\n ) private view returns (uint256, uint256) {\n uint256 dy;\n uint256 newY;\n uint256 currentY;\n\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\n\n // dy_0 (without fees)\n // dy, dy_0 - dy\n\n uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\n\n return (dy, dySwapFee);\n }\n\n /**\n * @notice Calculate the dy of withdrawing in one token\n * @param self Swap struct to read from\n * @param tokenIndex which token will be withdrawn\n * @param tokenAmount the amount to withdraw in the pools precision\n * @return the d and the new y after withdrawing one token\n */\n function calculateWithdrawOneTokenDY(\n Swap storage self,\n uint8 tokenIndex,\n uint256 tokenAmount,\n uint256 totalSupply\n )\n internal\n view\n returns (\n uint256,\n uint256,\n uint256\n )\n {\n // Get the current D, then solve the stableswap invariant\n // y_i for D - tokenAmount\n uint256[] memory xp = _xp(self);\n\n require(tokenIndex < xp.length, \"index out of range\");\n\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\n v.preciseA = _getAPrecise(self);\n v.d0 = getD(xp, v.preciseA);\n v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\n\n require(tokenAmount <= xp[tokenIndex], \"exceeds available\");\n\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\n\n uint256[] memory xpReduced = new uint256[](xp.length);\n\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\n for (uint256 i; i < xp.length; ) {\n uint256 xpi = xp[i];\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\n xpReduced[i] =\n xpi -\n ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\n FEE_DENOMINATOR);\n\n unchecked {\n ++i;\n }\n }\n\n uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\n dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\n\n return (dy, v.newY, xp[tokenIndex]);\n }\n\n /**\n * @notice Calculate the price of a token in the pool with given\n * precision-adjusted balances and a particular D.\n *\n * @dev This is accomplished via solving the invariant iteratively.\n * See the StableSwap paper and Curve.fi implementation for further details.\n *\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\n * x_1**2 + b*x_1 = c\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\n *\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\n * @param tokenIndex Index of token we are calculating for.\n * @param xp a precision-adjusted set of pool balances. Array should be\n * the same cardinality as the pool.\n * @param d the stableswap invariant\n * @return the price of the token, in the same precision as in xp\n */\n function getYD(\n uint256 a,\n uint8 tokenIndex,\n uint256[] memory xp,\n uint256 d\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndex < numTokens, \"Token not found\");\n\n uint256 c = d;\n uint256 s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < numTokens; ) {\n if (i != tokenIndex) {\n s += xp[i];\n c = (c * d) / (xp[i] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n }\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\n * as the pool.\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\n * See the StableSwap paper for details\n * @return the invariant, at the precision of the pool\n */\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n uint256 s;\n for (uint256 i; i < numTokens; ) {\n s += xp[i];\n\n unchecked {\n ++i;\n }\n }\n if (s == 0) {\n return 0;\n }\n\n uint256 prevD;\n uint256 d = s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n uint256 dP = d;\n for (uint256 j; j < numTokens; ) {\n dP = (dP * d) / (xp[j] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // dP = dP * D * D * D * ... overflow!\n\n unchecked {\n ++j;\n }\n }\n prevD = d;\n d =\n (((nA * s) / AmplificationUtils.A_PRECISION + dP * numTokens) * d) /\n ((((nA - AmplificationUtils.A_PRECISION) * d) / AmplificationUtils.A_PRECISION + (numTokens + 1) * dP));\n if (d.within1(prevD)) {\n return d;\n }\n\n unchecked {\n ++i;\n }\n }\n\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\n // function which does not rely on D.\n revert(\"D does not converge\");\n }\n\n /**\n * @notice Given a set of balances and precision multipliers, return the\n * precision-adjusted balances.\n *\n * @param balances an array of token balances, in their native precisions.\n * These should generally correspond with pooled tokens.\n *\n * @param precisionMultipliers an array of multipliers, corresponding to\n * the amounts in the balances array. When multiplied together they\n * should yield amounts at the pool's precision.\n *\n * @return an array of amounts \"scaled\" to the pool's precision\n */\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\n internal\n pure\n returns (uint256[] memory)\n {\n uint256 numTokens = balances.length;\n require(numTokens == precisionMultipliers.length, \"mismatch multipliers\");\n uint256[] memory xp = new uint256[](numTokens);\n for (uint256 i; i < numTokens; ) {\n xp[i] = balances[i] * precisionMultipliers[i];\n\n unchecked {\n ++i;\n }\n }\n return xp;\n }\n\n /**\n * @notice Return the precision-adjusted balances of all tokens in the pool\n * @param self Swap struct to read from\n * @return the pool balances \"scaled\" to the pool's precision, allowing\n * them to be more easily compared.\n */\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\n return _xp(self.balances, self.tokenPrecisionMultipliers);\n }\n\n /**\n * @notice Get the virtual price, to help calculate profit\n * @param self Swap struct to read from\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\n */\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\n uint256 d = getD(_xp(self), _getAPrecise(self));\n LPToken lpToken = self.lpToken;\n uint256 supply = lpToken.totalSupply();\n if (supply != 0) {\n return (d * (10**uint256(POOL_PRECISION_DECIMALS))) / supply;\n }\n return 0;\n }\n\n /**\n * @notice Calculate the new balances of the tokens given the indexes of the token\n * that is swapped from (FROM) and the token that is swapped to (TO).\n * This function is used as a helper function to calculate how much TO token\n * the user should receive on swap.\n *\n * @param preciseA precise form of amplification coefficient\n * @param tokenIndexFrom index of FROM token\n * @param tokenIndexTo index of TO token\n * @param x the new total amount of FROM token\n * @param xp balances of the tokens in the pool\n * @return the amount of TO token that should remain in the pool\n */\n function getY(\n uint256 preciseA,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 x,\n uint256[] memory xp\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \"token not found\");\n\n uint256 d = getD(xp, preciseA);\n uint256 c = d;\n uint256 s;\n uint256 nA = numTokens * preciseA;\n\n uint256 _x;\n for (uint256 i; i < numTokens; ) {\n if (i == tokenIndexFrom) {\n _x = x;\n } else if (i != tokenIndexTo) {\n _x = xp[i];\n } else {\n unchecked {\n ++i;\n }\n continue;\n }\n s += _x;\n c = (c * d) / (_x * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n\n // iterative approximation\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get\n */\n function calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) internal view returns (uint256 dy) {\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy.\n * @return dx the number of tokens the user have to transfer + fee\n */\n function calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) internal view returns (uint256 dx) {\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\n * @return dyFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256[] memory balances\n ) internal view returns (uint256 dy, uint256 dyFee) {\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\n dy = xp[tokenIndexTo] - y - 1;\n dyFee = (dy * self.swapFee) / FEE_DENOMINATOR;\n dy = (dy - dyFee) / multipliers[tokenIndexTo];\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\n * @return dxFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256[] memory balances\n ) internal view returns (uint256 dx, uint256 dxFee) {\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n\n uint256 a = _getAPrecise(self);\n uint256 d0 = getD(xp, a);\n\n xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\n dx = x - xp[tokenIndexFrom] + 1;\n dxFee = (dx * self.swapFee) / FEE_DENOMINATOR;\n dx = (dx + dxFee) / multipliers[tokenIndexFrom];\n }\n\n /**\n * @notice A simple method to calculate amount of each underlying\n * tokens that is returned upon burning given amount of\n * LP tokens\n *\n * @param amount the amount of LP tokens that would to be burned on\n * withdrawal\n * @return array of amounts of tokens user will receive\n */\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\n }\n\n function _calculateRemoveLiquidity(\n uint256[] memory balances,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (uint256[] memory) {\n require(amount <= totalSupply, \"exceed total supply\");\n\n uint256 numBalances = balances.length;\n uint256[] memory amounts = new uint256[](numBalances);\n\n for (uint256 i; i < numBalances; ) {\n amounts[i] = (balances[i] * amount) / totalSupply;\n\n unchecked {\n ++i;\n }\n }\n return amounts;\n }\n\n /**\n * @notice A simple method to calculate prices from deposits or\n * withdrawals, excluding fees but including slippage. This is\n * helpful as an input into the various \"min\" parameters on calls\n * to fight front-running\n *\n * @dev This shouldn't be used outside frontends for user estimates.\n *\n * @param self Swap struct to read from\n * @param amounts an array of token amounts to deposit or withdrawal,\n * corresponding to pooledTokens. The amount should be in each\n * pooled token's native precision. If a token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @param deposit whether this is a deposit or a withdrawal\n * @return if deposit was true, total amount of lp token that will be minted and if\n * deposit was false, total amount of lp token that will be burned\n */\n function calculateTokenAmount(\n Swap storage self,\n uint256[] calldata amounts,\n bool deposit\n ) internal view returns (uint256) {\n uint256 a = _getAPrecise(self);\n uint256[] memory balances = self.balances;\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n\n uint256 numBalances = balances.length;\n uint256 d0 = getD(_xp(balances, multipliers), a);\n for (uint256 i; i < numBalances; ) {\n if (deposit) {\n balances[i] = balances[i] + amounts[i];\n } else {\n balances[i] = balances[i] - amounts[i];\n }\n\n unchecked {\n ++i;\n }\n }\n uint256 d1 = getD(_xp(balances, multipliers), a);\n uint256 totalSupply = self.lpToken.totalSupply();\n\n if (deposit) {\n return ((d1 - d0) * totalSupply) / d0;\n } else {\n return ((d0 - d1) * totalSupply) / d0;\n }\n }\n\n /**\n * @notice return accumulated amount of admin fees of the token with given index\n * @param self Swap struct to read from\n * @param index Index of the pooled token\n * @return admin balance in the token's precision\n */\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\n require(index < self.pooledTokens.length, \"index out of range\");\n return self.adminFees[index];\n }\n\n /**\n * @notice internal helper function to calculate fee per token multiplier used in\n * swap fee calculations\n * @param swapFee swap fee for the tokens\n * @param numTokens number of tokens pooled\n */\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\n return (swapFee * numTokens) / ((numTokens - 1) * 4);\n }\n\n /*** STATE MODIFYING FUNCTIONS ***/\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"swap more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"no fee token support\");\n }\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dy the amount of tokens the user wants to buy\n * @param maxDx the max amount the user would like to send.\n * @return amount of token user have to transfer on swap\n */\n function swapOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \">pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"not support fee token\");\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice swap two tokens in the pool internally\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swapInternal(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n require(dx <= self.balances[tokenIndexFrom], \"more than pool balance\");\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice Should get exact amount out of AMM for asset put in\n */\n function swapInternalOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \"more than pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice Add liquidity to the pool\n * @param self Swap struct to read from and write to\n * @param amounts the amounts of each token to add, in their native precision\n * @param minToMint the minimum LP tokens adding this amount of liquidity\n * should mint, otherwise revert. Handy for front-running mitigation\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\n * @return amount of LP token user received\n */\n function addLiquidity(\n Swap storage self,\n uint256[] memory amounts,\n uint256 minToMint\n ) internal returns (uint256) {\n uint256 numTokens = self.pooledTokens.length;\n require(amounts.length == numTokens, \"mismatch pooled tokens\");\n\n // current state\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n if (v.totalSupply != 0) {\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n }\n\n uint256[] memory newBalances = new uint256[](numTokens);\n\n for (uint256 i; i < numTokens; ) {\n require(v.totalSupply != 0 || amounts[i] != 0, \"!supply all tokens\");\n\n // Transfer tokens first to see if a fee was charged on transfer\n if (amounts[i] != 0) {\n IERC20 token = self.pooledTokens[i];\n uint256 beforeBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), amounts[i]);\n\n // Update the amounts[] with actual transfer amount\n amounts[i] = token.balanceOf(address(this)) - beforeBalance;\n }\n\n newBalances[i] = v.balances[i] + amounts[i];\n\n unchecked {\n ++i;\n }\n }\n\n // invariant after change\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n require(v.d1 > v.d0, \"D should increase\");\n\n // updated to reflect fees and calculate the user's LP tokens\n v.d2 = v.d1;\n uint256[] memory fees = new uint256[](numTokens);\n\n if (v.totalSupply != 0) {\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n for (uint256 i; i < numTokens; ) {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / FEE_DENOMINATOR;\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = newBalances[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n newBalances[i] = newBalances[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n } else {\n // the initial depositor doesn't pay fees\n self.balances = newBalances;\n }\n\n uint256 toMint;\n if (v.totalSupply == 0) {\n toMint = v.d1;\n } else {\n toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\n }\n\n require(toMint >= minToMint, \"mint < min\");\n\n // mint the user's LP tokens\n v.lpToken.mint(msg.sender, toMint);\n\n emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\n\n return toMint;\n }\n\n /**\n * @notice Burn LP tokens to remove liquidity from the pool.\n * @dev Liquidity can always be removed, even when the pool is paused.\n * @param self Swap struct to read from and write to\n * @param amount the amount of LP tokens to burn\n * @param minAmounts the minimum amounts of each token in the pool\n * acceptable for this burn. Useful as a front-running mitigation\n * @return amounts of tokens the user received\n */\n function removeLiquidity(\n Swap storage self,\n uint256 amount,\n uint256[] calldata minAmounts\n ) internal returns (uint256[] memory) {\n LPToken lpToken = self.lpToken;\n require(amount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(minAmounts.length == numTokens, \"mismatch poolTokens\");\n\n uint256[] memory balances = self.balances;\n uint256 totalSupply = lpToken.totalSupply();\n\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\n\n uint256 numAmounts = amounts.length;\n for (uint256 i; i < numAmounts; ) {\n require(amounts[i] >= minAmounts[i], \"amounts[i] < minAmounts[i]\");\n self.balances[i] = balances[i] - amounts[i];\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n lpToken.burnFrom(msg.sender, amount);\n\n emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\n\n return amounts;\n }\n\n /**\n * @notice Remove liquidity from the pool all in one token.\n * @param self Swap struct to read from and write to\n * @param tokenAmount the amount of the lp tokens to burn\n * @param tokenIndex the index of the token you want to receive\n * @param minAmount the minimum amount to withdraw, otherwise revert\n * @return amount chosen token that user received\n */\n function removeLiquidityOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount\n ) internal returns (uint256) {\n LPToken lpToken = self.lpToken;\n\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(tokenIndex < numTokens, \"not found\");\n\n uint256 totalSupply = lpToken.totalSupply();\n\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\n\n require(dy >= minAmount, \"dy < minAmount\");\n\n uint256 adminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR;\n self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\n if (adminFee != 0) {\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\n }\n lpToken.burnFrom(msg.sender, tokenAmount);\n self.pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\n\n emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\n\n return dy;\n }\n\n /**\n * @notice Remove liquidity from the pool, weighted differently than the\n * pool's current balances.\n *\n * @param self Swap struct to read from and write to\n * @param amounts how much of each token to withdraw\n * @param maxBurnAmount the max LP token provider is willing to pay to\n * remove liquidity. Useful as a front-running mitigation.\n * @return actual amount of LP tokens burned in the withdrawal\n */\n function removeLiquidityImbalance(\n Swap storage self,\n uint256[] memory amounts,\n uint256 maxBurnAmount\n ) internal returns (uint256) {\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n\n uint256 numTokens = self.pooledTokens.length;\n uint256 numAmounts = amounts.length;\n require(numAmounts == numTokens, \"mismatch pool tokens\");\n\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \">LP.balanceOf\");\n\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n uint256[] memory fees = new uint256[](numTokens);\n {\n uint256[] memory balances1 = new uint256[](numTokens);\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n for (uint256 i; i < numTokens; ) {\n require(v.balances[i] >= amounts[i], \"withdraw more than available\");\n\n unchecked {\n balances1[i] = v.balances[i] - amounts[i];\n ++i;\n }\n }\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\n\n for (uint256 i; i < numTokens; ) {\n {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n uint256 difference = idealBalance.difference(balances1[i]);\n fees[i] = (feePerToken * difference) / FEE_DENOMINATOR;\n }\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = balances1[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n balances1[i] = balances1[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\n }\n uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\n require(tokenAmount != 0, \"!zero amount\");\n tokenAmount = tokenAmount + 1;\n\n require(tokenAmount <= maxBurnAmount, \"tokenAmount > maxBurnAmount\");\n\n v.lpToken.burnFrom(msg.sender, tokenAmount);\n\n for (uint256 i; i < numTokens; ) {\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\n\n return tokenAmount;\n }\n\n /**\n * @notice withdraw all admin fees to a given address\n * @param self Swap struct to withdraw fees from\n * @param to Address to send the fees to\n */\n function withdrawAdminFees(Swap storage self, address to) internal {\n uint256 numTokens = self.pooledTokens.length;\n for (uint256 i; i < numTokens; ) {\n IERC20 token = self.pooledTokens[i];\n uint256 balance = self.adminFees[i];\n if (balance != 0) {\n self.adminFees[i] = 0;\n token.safeTransfer(to, balance);\n }\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Sets the admin fee\n * @dev adminFee cannot be higher than 100% of the swap fee\n * @param self Swap struct to update\n * @param newAdminFee new admin fee to be applied on future transactions\n */\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\n require(newAdminFee <= MAX_ADMIN_FEE, \"too high\");\n self.adminFee = newAdminFee;\n\n emit NewAdminFee(self.key, newAdminFee);\n }\n\n /**\n * @notice update the swap fee\n * @dev fee cannot be higher than 1% of each swap\n * @param self Swap struct to update\n * @param newSwapFee new swap fee to be applied on future transactions\n */\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\n require(newSwapFee <= MAX_SWAP_FEE, \"too high\");\n self.swapFee = newSwapFee;\n\n emit NewSwapFee(self.key, newSwapFee);\n }\n\n /**\n * @notice Check if this stableswap pool exists and is valid (i.e. has been\n * initialized and tokens have been added).\n * @return bool true if this stableswap pool is valid, false if not.\n */\n function exists(Swap storage self) internal view returns (bool) {\n return self.pooledTokens.length != 0;\n }\n}\n" - }, - "@openzeppelin/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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/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" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\nimport {IOutbox} from \"./IOutbox.sol\";\n\n/**\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\n * allows an admin to call `setXAppConnectionManager` to update the underlying\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\n *\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\n * will interface with.\n */\ninterface IConnectorManager {\n /**\n * @notice Get the local inbox contract from the xAppConnectionManager\n * @return The local inbox contract\n * @dev The local inbox contract is a SpokeConnector with AMBs, and a\n * Home contract with nomad\n */\n function home() external view returns (IOutbox);\n\n /**\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\n * @return True if _potentialReplica is an enrolled Replica\n */\n function isReplica(address _potentialReplica) external view returns (bool);\n\n /**\n * @notice Get the local domain from the xAppConnectionManager\n * @return The local domain\n */\n function localDomain() external view returns (uint32);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n/**\n * @title AmplificationUtils library\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\n * This library assumes the struct is fully validated.\n */\nlibrary AmplificationUtils {\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n // Constant values used in ramping A calculations\n uint256 public constant A_PRECISION = 100;\n uint256 public constant MAX_A = 10**6;\n uint256 private constant MAX_A_CHANGE = 2;\n uint256 private constant MIN_RAMP_TIME = 14 days;\n\n /**\n * @notice Return A, the amplification coefficient * n * (n - 1)\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter\n */\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self) / A_PRECISION;\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self);\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n uint256 t1 = self.futureATime; // time when ramp is finished\n uint256 a1 = self.futureA; // final A value when ramp is finished\n\n if (block.timestamp < t1) {\n uint256 t0 = self.initialATime; // time when ramp is started\n uint256 a0 = self.initialA; // initial A value when ramp is started\n if (a1 > a0) {\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\n return a0 + ((a1 - a0) * (block.timestamp - t0)) / (t1 - t0);\n } else {\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\n return a0 - ((a0 - a1) * (block.timestamp - t0)) / (t1 - t0);\n }\n } else {\n return a1;\n }\n }\n\n /**\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\n * Checks if the change is too rapid, and commits the new A value only when it falls under\n * the limit range.\n * @param self Swap struct to update\n * @param futureA_ the new A to ramp towards\n * @param futureTime_ timestamp when the new A should be reached\n */\n function rampA(\n SwapUtils.Swap storage self,\n uint256 futureA_,\n uint256 futureTime_\n ) internal {\n require(block.timestamp >= self.initialATime + 1 days, \"Wait 1 day before starting ramp\");\n require(futureTime_ >= block.timestamp + MIN_RAMP_TIME, \"Insufficient ramp time\");\n require(futureA_ != 0 && futureA_ < MAX_A, \"futureA_ must be > 0 and < MAX_A\");\n\n uint256 initialAPrecise = _getAPrecise(self);\n uint256 futureAPrecise = futureA_ * A_PRECISION;\n\n if (futureAPrecise < initialAPrecise) {\n require(futureAPrecise * MAX_A_CHANGE >= initialAPrecise, \"futureA_ is too small\");\n } else {\n require(futureAPrecise <= initialAPrecise * MAX_A_CHANGE, \"futureA_ is too large\");\n }\n\n self.initialA = initialAPrecise;\n self.futureA = futureAPrecise;\n self.initialATime = block.timestamp;\n self.futureATime = futureTime_;\n\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\n }\n\n /**\n * @notice Stops ramping A immediately. Once this function is called, rampA()\n * cannot be called for another 24 hours\n * @param self Swap struct to update\n */\n function stopRampA(SwapUtils.Swap storage self) internal {\n require(self.futureATime > block.timestamp, \"Ramp is already stopped\");\n\n uint256 currentA = _getAPrecise(self);\n self.initialA = currentA;\n self.futureA = currentA;\n self.initialATime = block.timestamp;\n self.futureATime = block.timestamp;\n\n emit StopRampA(currentA, block.timestamp);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title Liquidity Provider Token\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\n * It is used to represent user's shares when providing liquidity to swap contracts.\n * @dev Only Swap contracts should initialize and own LPToken contracts.\n */\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\n // ============ Upgrade Gap ============\n\n uint256[49] private __GAP; // gap for upgrade safety\n\n // ============ Storage ============\n\n /**\n * @notice Used to enforce proper token dilution\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\n * See audit recommendations here:\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\n * and uniswap v2 implementation here:\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\n */\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\n\n // ============ Initializer ============\n\n /**\n * @notice Initializes this LPToken contract with the given name and symbol\n * @dev The caller of this function will become the owner. A Swap contract should call this\n * in its initializer function.\n * @param name name of this token\n * @param symbol symbol of this token\n */\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\n __Context_init_unchained();\n __ERC20_init_unchained(name, symbol);\n __Ownable_init_unchained();\n return true;\n }\n\n // ============ External functions ============\n\n /**\n * @notice Mints the given amount of LPToken to the recipient.\n * @dev only owner can call this mint function\n * @param recipient address of account to receive the tokens\n * @param amount amount of tokens to mint\n */\n function mint(address recipient, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot mint 0\");\n if (totalSupply() == 0) {\n // NOTE: using the _mint function directly will error because it is going\n // to the 0 address. fix by using the address(1) here instead\n _mint(address(1), MINIMUM_LIQUIDITY);\n }\n _mint(recipient, amount);\n }\n\n /**\n * @notice Burns the given amount of LPToken from provided account\n * @dev only owner can call this burn function\n * @param account address of account from which to burn token\n * @param amount amount of tokens to mint\n */\n function burnFrom(address account, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot burn 0\");\n _burn(account, amount);\n }\n\n // ============ Internal functions ============\n\n /**\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\n * This assumes the owner is set to a Swap contract's address.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20Upgradeable) {\n super._beforeTokenTransfer(from, to, amount);\n require(to != address(this), \"LPToken: cannot send to itself\");\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\n/**\n * @title MathUtils library\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\n * differences between two uint256.\n */\nlibrary MathUtils {\n /**\n * @notice Compares a and b and returns true if the difference between a and b\n * is less than 1 or equal to each other.\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return True if the difference between a and b is less than 1 or equal,\n * otherwise return false\n */\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\n return (difference(a, b) <= 1);\n }\n\n /**\n * @notice Calculates absolute difference between a and b\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return Difference between a and b\n */\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a > b) {\n return a - b;\n }\n return b - a;\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.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 IERC20Upgradeable {\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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\n/**\n * @notice Interface for all contracts sending messages originating on their\n * current domain.\n *\n * @dev These are the Home.sol interface methods used by the `Router`\n * and exposed via `home()` on the `XAppConnectionClient`\n */\ninterface IOutbox {\n /**\n * @notice Emitted when a new message is added to an outbound message merkle root\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination << 32) & nonce)\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\n * @param committedRoot the latest notarized root submitted in the last signed Update\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes32 committedRoot,\n bytes message\n );\n\n /**\n * @notice Dispatch the message it to the destination domain & recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n * @return bytes32 The leaf added to the tree\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n bytes memory _messageBody\n ) external returns (bytes32);\n}\n" - }, - "solidity/for-test/DataReceiverForTest.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {DataReceiver} from '../contracts/DataReceiver.sol';\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\ncontract DataReceiverForTest is DataReceiver {\n constructor(address _governor, IOracleFactory _oracleFactory) DataReceiver(_governor, _oracleFactory) {}\n\n function internalAddObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "solidity/contracts/DataReceiver.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\n\n/// @title The DataReceiver contract\n/// @notice Handles reception of broadcast data and delivers it to correspondant oracle\ncontract DataReceiver is IDataReceiver, Governable {\n /// @inheritdoc IDataReceiver\n IOracleFactory public immutable oracleFactory;\n\n /// @inheritdoc IDataReceiver\n mapping(bytes32 => IOracleSidechain) public deployedOracles;\n\n /// @inheritdoc IDataReceiver\n mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters;\n\n /// @inheritdoc IDataReceiver\n bytes32 public constant ORACLE_INIT_CODE_HASH = 0x81a14d5bbd761f94f91b3251dcb81827627068b092edb305c98f3799dcf10da2;\n\n constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) {\n oracleFactory = _oracleFactory;\n }\n\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external onlyWhitelistedAdapters {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n // Read, store or deploy oracle given poolSalt\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.getPool(_poolSalt);\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.deployOracle(_poolSalt, _poolNonce);\n }\n deployedOracles[_poolSalt] = _oracle;\n }\n // Try to write observations data into oracle\n if (_oracle.write(_observationsData, _poolNonce)) {\n emit ObservationsAdded(_poolSalt, _poolNonce, _observationsData, msg.sender);\n } else {\n revert ObservationsNotWritable();\n }\n }\n\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_receiverAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IDataReceiver\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _receiverAdapterLength = _receiverAdapters.length;\n if (_receiverAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _receiverAdapterLength; ++_i) {\n _whitelistAdapter(_receiverAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n function _whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_receiverAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_receiverAdapter, _isWhitelisted);\n }\n\n modifier onlyWhitelistedAdapters() {\n if (!whitelistedAdapters[IBridgeReceiverAdapter(msg.sender)]) revert UnallowedAdapter();\n _;\n }\n}\n" - }, - "solidity/contracts/OracleSidechain.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\n\n/// @title The SidechainOracle contract\n/// @notice Computes and stores on-chain price data from Mainnet\ncontract OracleSidechain is IOracleSidechain {\n using Oracle for Oracle.Observation[65535];\n\n /// @inheritdoc IOracleSidechain\n IOracleFactory public immutable factory;\n\n struct Slot0 {\n // the current price\n uint160 sqrtPriceX96;\n // the current tick\n int24 tick;\n // the most-recently updated index of the observations array\n uint16 observationIndex;\n // the current maximum number of observations that are being stored\n uint16 observationCardinality;\n // the next maximum number of observations to store, triggered in observations.write\n uint16 observationCardinalityNext;\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\n // represented as an integer denominator (1/x)%\n uint8 feeProtocol;\n // whether the pool is locked\n bool unlocked;\n }\n /// @inheritdoc IOracleSidechain\n Slot0 public slot0;\n\n /// @inheritdoc IOracleSidechain\n Oracle.Observation[65535] public observations;\n\n /// @inheritdoc IOracleSidechain\n bytes32 public immutable poolSalt;\n\n uint24 public poolNonce;\n /// @inheritdoc IOracleSidechain\n address public token0;\n /// @inheritdoc IOracleSidechain\n address public token1;\n /// @inheritdoc IOracleSidechain\n uint24 public fee;\n\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\n function _getBlockTimestamp() internal view virtual returns (uint32) {\n return uint32(block.timestamp); // truncation is desired\n }\n\n constructor() {\n factory = IOracleFactory(msg.sender);\n uint16 _cardinality;\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\n\n slot0 = Slot0({\n sqrtPriceX96: 0,\n tick: 0,\n observationIndex: _cardinality - 1,\n observationCardinality: _cardinality,\n observationCardinalityNext: _cardinality,\n feeProtocol: 0,\n unlocked: true\n });\n }\n\n /// @inheritdoc IOracleSidechain\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external {\n if (!slot0.unlocked) revert AI();\n\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\n\n token0 = _token0;\n token1 = _token1;\n fee = _fee;\n slot0.unlocked = false;\n\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\n }\n\n /// @inheritdoc IOracleSidechain\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\n {\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\n }\n\n /// @inheritdoc IOracleSidechain\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\n if (_poolNonce != poolNonce++) return false;\n\n uint256 _observationsDataLength = _observationsData.length;\n for (uint256 _i; _i < _observationsDataLength; ) {\n _write(_observationsData[_i]);\n unchecked {\n ++_i;\n }\n }\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\n\n // emits UniV3 Swap event topic with minimal data\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\n return true;\n }\n\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\n if (_observationCardinalityNext <= _observationCardinalityNextOld) return;\n slot0.observationCardinalityNext = _observationCardinalityNext;\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\n }\n\n function _write(ObservationData memory _observationData) private {\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\n slot0.observationIndex,\n _observationData.blockTimestamp,\n slot0.tick,\n 0,\n slot0.observationCardinality,\n slot0.observationCardinalityNext\n );\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\n slot0.tick = _observationData.tick;\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\n _;\n }\n\n modifier onlyFactory() {\n if (msg.sender != address(factory)) revert OnlyFactory();\n _;\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/TickMath.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n error T();\n error R();\n\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n unchecked {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n if (absTick > uint256(int256(MAX_TICK))) revert T();\n\n uint256 ratio = absTick & 0x1 != 0\n ? 0xfffcb933bd6fad37aa2d162d1a594001\n : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\n /// ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n unchecked {\n // second inequality must be < because the price can never reach the price at the max tick\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/Oracle.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/// @title Oracle\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\n/// @dev Instances of stored oracle data, \"observations\", are collected in the oracle array\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\n/// Observations are overwritten when the full length of the oracle array is populated.\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\nlibrary Oracle {\n error I();\n error OLD();\n\n struct Observation {\n // the block timestamp of the observation\n uint32 blockTimestamp;\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\n int56 tickCumulative;\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\n uint160 secondsPerLiquidityCumulativeX128;\n // whether or not the observation is initialized\n bool initialized;\n }\n\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\n /// @param last The specified observation to be transformed\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @return Observation The newly populated observation\n function transform(\n Observation memory last,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity\n ) private pure returns (Observation memory) {\n unchecked {\n uint32 delta = blockTimestamp - last.blockTimestamp;\n return\n Observation({\n blockTimestamp: blockTimestamp,\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\n initialized: true\n });\n }\n }\n\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\n /// @param self The stored oracle array\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\n /// @return cardinality The number of populated elements in the oracle array\n /// @return cardinalityNext The new length of the oracle array, independent of population\n function initialize(Observation[65535] storage self, uint32 time)\n internal\n returns (uint16 cardinality, uint16 cardinalityNext)\n {\n self[0] = Observation({\n blockTimestamp: time,\n tickCumulative: 0,\n secondsPerLiquidityCumulativeX128: 0,\n initialized: true\n });\n return (1, 1);\n }\n\n /// @notice Writes an oracle observation to the array\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\n /// @param self The stored oracle array\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @param cardinality The number of populated elements in the oracle array\n /// @param cardinalityNext The new length of the oracle array, independent of population\n /// @return indexUpdated The new index of the most recently written element in the oracle array\n /// @return cardinalityUpdated The new cardinality of the oracle array\n function write(\n Observation[65535] storage self,\n uint16 index,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity,\n uint16 cardinality,\n uint16 cardinalityNext\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\n unchecked {\n Observation memory last = self[index];\n\n // early return if we've already written an observation this block\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\n\n // if the conditions are right, we can bump the cardinality\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\n cardinalityUpdated = cardinalityNext;\n } else {\n cardinalityUpdated = cardinality;\n }\n\n indexUpdated = (index + 1) % cardinalityUpdated;\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\n }\n }\n\n /// @notice Prepares the oracle array to store up to `next` observations\n /// @param self The stored oracle array\n /// @param current The current next cardinality of the oracle array\n /// @param next The proposed next cardinality which will be populated in the oracle array\n /// @return next The next cardinality which will be populated in the oracle array\n function grow(\n Observation[65535] storage self,\n uint16 current,\n uint16 next\n ) internal returns (uint16) {\n unchecked {\n if (current <= 0) revert I();\n // no-op if the passed next value isn't greater than the current next value\n if (next <= current) return current;\n // store in each slot to prevent fresh SSTOREs in swaps\n // this data will not be used because the initialized boolean is still false\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\n return next;\n }\n }\n\n /// @notice comparator for 32-bit timestamps\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\n /// @param time A timestamp truncated to 32 bits\n /// @param a A comparison timestamp from which to determine the relative position of `time`\n /// @param b From which to determine the relative position of `time`\n /// @return Whether `a` is chronologically <= `b`\n function lte(\n uint32 time,\n uint32 a,\n uint32 b\n ) private pure returns (bool) {\n unchecked {\n // if there hasn't been overflow, no need to adjust\n if (a <= time && b <= time) return a <= b;\n\n uint256 aAdjusted = a > time ? a : a + 2**32;\n uint256 bAdjusted = b > time ? b : b + 2**32;\n\n return aAdjusted <= bAdjusted;\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\n /// The result may be the same observation, or adjacent observations.\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation recorded before, or at, the target\n /// @return atOrAfter The observation recorded at, or after, the target\n function binarySearch(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n uint16 index,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n uint256 l = (index + 1) % cardinality; // oldest observation\n uint256 r = l + cardinality - 1; // newest observation\n uint256 i;\n while (true) {\n i = (l + r) / 2;\n\n beforeOrAt = self[i % cardinality];\n\n // we've landed on an uninitialized tick, keep searching higher (more recently)\n if (!beforeOrAt.initialized) {\n l = i + 1;\n continue;\n }\n\n atOrAfter = self[(i + 1) % cardinality];\n\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\n\n // check if we've found the answer!\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\n\n if (!targetAtOrAfter) r = i - 1;\n else l = i + 1;\n }\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\n /// @dev Assumes there is at least 1 initialized observation.\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param tick The active tick at the time of the returned or simulated observation\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The total pool liquidity at the time of the call\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\n function getSurroundingObservations(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n // optimistically set before to the newest observation\n beforeOrAt = self[index];\n\n // if the target is chronologically at or after the newest observation, we can early return\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\n if (beforeOrAt.blockTimestamp == target) {\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\n return (beforeOrAt, atOrAfter);\n } else {\n // otherwise, we need to transform\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\n }\n }\n\n // now, set before to the oldest observation\n beforeOrAt = self[(index + 1) % cardinality];\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\n\n // ensure that the target is chronologically at or after the oldest observation\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\n\n // if we've reached this point, we have to binary search\n return binarySearch(self, time, target, index, cardinality);\n }\n }\n\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\n /// at exactly the timestamp between the two observations.\n /// @param self The stored oracle array\n /// @param time The current block timestamp\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\n function observeSingle(\n Observation[65535] storage self,\n uint32 time,\n uint32 secondsAgo,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\n unchecked {\n if (secondsAgo == 0) {\n Observation memory last = self[index];\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\n }\n\n uint32 target = time - secondsAgo;\n\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\n self,\n time,\n target,\n tick,\n index,\n liquidity,\n cardinality\n );\n\n if (target == beforeOrAt.blockTimestamp) {\n // we're at the left boundary\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\n } else if (target == atOrAfter.blockTimestamp) {\n // we're at the right boundary\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\n } else {\n // we're in the middle\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\n return (\n beforeOrAt.tickCumulative +\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\n int56(uint56(targetDelta)),\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\n uint160(\n (uint256(\n atOrAfter.secondsPerLiquidityCumulativeX128 -\n beforeOrAt.secondsPerLiquidityCumulativeX128\n ) * targetDelta) / observationTimeDelta\n )\n );\n }\n }\n }\n\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\n /// @dev Reverts if `secondsAgos` > oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\n function observe(\n Observation[65535] storage self,\n uint32 time,\n uint32[] memory secondsAgos,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\n unchecked {\n if (cardinality <= 0) revert I();\n\n tickCumulatives = new int56[](secondsAgos.length);\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\n for (uint256 i = 0; i < secondsAgos.length; i++) {\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\n self,\n time,\n secondsAgos[i],\n tick,\n index,\n liquidity,\n cardinality\n );\n }\n }\n }\n}\n" - }, - "solidity/interfaces/bridges/IConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from './IBridgeReceiverAdapter.sol';\n\ninterface IConnextReceiverAdapter is IBridgeReceiverAdapter {\n // STATE VARIABLES\n\n function connext() external view returns (IConnext _connext);\n\n function source() external view returns (address _originContract);\n\n function originDomain() external view returns (uint32 _originDomain);\n}\n" - }, - "solidity/contracts/bridges/ConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {LibConnextStorage, TransferInfo} from '@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol';\nimport {IConnext, IConnextSenderAdapter, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../../interfaces/bridges/IConnextSenderAdapter.sol';\n\ncontract ConnextSenderAdapter is IConnextSenderAdapter {\n /// @inheritdoc IConnextSenderAdapter\n IConnext public immutable connext;\n\n /// @inheritdoc IConnextSenderAdapter\n IDataFeed public immutable dataFeed;\n\n constructor(IConnext _connext, IDataFeed _dataFeed) {\n connext = _connext;\n dataFeed = _dataFeed;\n }\n\n /// @inheritdoc IBridgeSenderAdapter\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce // TODO: review input parameters packing KMC-\n ) external payable onlyDataFeed {\n bytes memory _callData = abi.encode(_observationsData, _poolSalt, _poolNonce);\n\n connext.xcall({\n _destination: _destinationDomainId, // unique identifier for destination domain\n _to: _to, // recipient of funds, where calldata will be executed\n _asset: address(0), // asset being transferred\n _delegate: address(0), // permissioned address to recover in edgecases on destination domain\n _amount: 0, // amount being transferred\n _slippage: 0, // slippage in bps\n _callData: _callData // to be executed on _to on the destination domain\n });\n }\n\n modifier onlyDataFeed() {\n if (msg.sender != address(dataFeed)) revert OnlyDataFeed();\n _;\n }\n}\n" - }, - "solidity/interfaces/IStrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IKeep3rJob} from './peripherals/IKeep3rJob.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IStrategyJob is IKeep3rJob {\n // STATE VARIABLES\n\n /// @return _dataFeedStrategy The address of the current DataFeedStrategy\n function dataFeedStrategy() external view returns (IDataFeedStrategy _dataFeedStrategy);\n\n /// @return _dataFeed The address of the DataFeed\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _defaultBridgeSenderAdapter The address of the job bridge sender adapter\n function defaultBridgeSenderAdapter() external view returns (IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n /// @param _chainId The identifier of the chain\n /// @param _poolSalt The identifier of both the pool and oracle\n /// @return _lastPoolNonceBridged Last nonce of the oracle observed\n function lastPoolNonceBridged(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _lastPoolNonceBridged);\n\n // EVENTS\n\n /// @notice Emitted when a new default bridge sender adapter is set\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n event DefaultBridgeSenderAdapterSet(IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n // ERRORS\n\n /// @notice Thrown when the job is not workable\n error NotWorkable();\n\n // FUNCTIONS\n\n /// @notice Calls to send observations in the DataFeed contract\n /// @param _chainId The Ethereum chain identification\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Calls to fetch observations and update the oracle state in the DataFeed contract\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The identifier of the reason to trigger an update\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external;\n\n /// @notice Allows governor to set a new default bridge sender adapter\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external;\n\n /// @notice Returns if the job can be worked\n /// @param _chainId The destination chain ID\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n /// @return _isWorkable Whether the job is workable or not\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external view returns (bool _isWorkable);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the job can be worked\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the job can be worked\n /// @return _isWorkable Whether the job is workable or not\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external view returns (bool _isWorkable);\n}\n" - }, - "solidity/interfaces/peripherals/IKeep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './IGovernable.sol';\nimport {IKeep3r} from '@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol';\n\ninterface IKeep3rJob is IGovernable {\n // STATE VARIABLES\n\n /// @return _keep3r Address of the Keep3r contract\n function keep3r() external view returns (IKeep3r _keep3r);\n\n // EVENTS\n\n /// @notice Emitted when a new Keep3r contract is set\n /// @param _keep3r Address of the new Keep3r contract\n event Keep3rSet(IKeep3r _keep3r);\n\n // ERRORS\n\n /// @notice Throws when a keeper fails the validation\n error KeeperNotValid();\n\n // FUNCTIONS\n\n /// @notice Allows governor to set a new Keep3r contract\n /// @param _keep3r Address of the new Keep3r contract\n function setKeep3r(IKeep3r _keep3r) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rAccountance.sol';\nimport './peripherals/IKeep3rRoles.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rAccountance, IKeep3rRoles, IKeep3rParameters {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rRoles.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rKeepers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable, IKeep3rKeeperFundable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rAccountance.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rParameters.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\n\ninterface IKeep3rParameters is IBaseErrors {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rJobs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobOwnership, IKeep3rJobDisputable, IKeep3rJobMigration, IKeep3rJobManager, IKeep3rJobWorkable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IBaseErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" - }, - "solidity/contracts/OracleFactory.sol": { - "content": "//TODO: change license\n//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IOracleFactory, IOracleSidechain, IDataReceiver} from '../interfaces/IOracleFactory.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The OracleFactory contract\n/// @notice Handles the deployment of new OracleSidechains\ncontract OracleFactory is IOracleFactory, Governable {\n /// @inheritdoc IOracleFactory\n IDataReceiver public dataReceiver;\n\n /// @inheritdoc IOracleFactory\n OracleParameters public oracleParameters;\n\n /// @inheritdoc IOracleFactory\n uint16 public initialCardinality = 144;\n\n /// @inheritdoc IOracleFactory\n bytes32 public constant ORACLE_INIT_CODE_HASH = keccak256(type(OracleSidechain).creationCode);\n\n constructor(address _governor, IDataReceiver _dataReceiver) Governable(_governor) {\n dataReceiver = _dataReceiver;\n }\n\n /// @inheritdoc IOracleFactory\n function deployOracle(bytes32 _poolSalt, uint24 _initialNonce) external onlyDataReceiver returns (IOracleSidechain _oracle) {\n oracleParameters = OracleParameters({poolSalt: _poolSalt, poolNonce: _initialNonce, cardinality: initialCardinality});\n _oracle = new OracleSidechain{salt: _poolSalt}();\n\n delete oracleParameters;\n emit OracleDeployed(_poolSalt, address(_oracle), _initialNonce);\n }\n\n /// @inheritdoc IOracleFactory\n function setDataReceiver(IDataReceiver _dataReceiver) external onlyGovernor {\n dataReceiver = _dataReceiver;\n emit DataReceiverSet(_dataReceiver);\n }\n\n /// @inheritdoc IOracleFactory\n function setInitialCardinality(uint16 _initialCardinality) external onlyGovernor {\n initialCardinality = _initialCardinality;\n emit InitialCardinalitySet(_initialCardinality);\n }\n\n function increaseOracleCardinality(bytes32 _poolSalt, uint16 _observationCardinalityNext) external onlyGovernor {\n IOracleSidechain _oracle = getPool(_poolSalt);\n _oracle.increaseObservationCardinalityNext(_observationCardinalityNext);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle) {\n bytes32 _poolSalt = getPoolSalt(_tokenA, _tokenB, _fee);\n _oracle = getPool(_poolSalt);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(bytes32 _poolSalt) public view returns (IOracleSidechain _oracle) {\n _oracle = IOracleSidechain(Create2Address.computeAddress(address(this), _poolSalt, ORACLE_INIT_CODE_HASH));\n if (address(_oracle).code.length == 0) return IOracleSidechain(address(0));\n }\n\n /// @inheritdoc IOracleFactory\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) public pure returns (bytes32 _poolSalt) {\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n _poolSalt = keccak256(abi.encode(_token0, _token1, _fee));\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(dataReceiver)) revert OnlyDataReceiver();\n _;\n }\n}\n" - }, - "solidity/for-test/DummyAdapterForTest.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\nimport {IDataReceiver} from '../interfaces/IDataReceiver.sol';\n\ncontract DummyAdapterForTest {\n // TODO: factorize interfaces so that this adapter can use same as sender/receiver\n event SentData(IDataReceiver, IOracleSidechain.ObservationData[]);\n event Create2Hash(bytes32);\n\n bool public ignoreTxs;\n\n constructor() {\n /// @dev Emitted to validate correct calculation of ORACLE_INIT_CODE_HASH\n emit Create2Hash(keccak256(type(OracleSidechain).creationCode));\n }\n\n function bridgeObservations(\n IDataReceiver _to,\n uint32,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable {\n if (!ignoreTxs) {\n _to.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n emit SentData(_to, _observationsData);\n }\n\n function setIgnoreTxs(bool _ignoreTxs) external {\n ignoreTxs = _ignoreTxs;\n }\n}\n" - }, - "solidity/contracts/DataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {IDataFeedStrategy, IUniswapV3Pool, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeedStrategy.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The DataFeed Strategy contract\n/// @notice Handles when and how a history of a pool should be updated\ncontract DataFeedStrategy is IDataFeedStrategy, Governable {\n /// @inheritdoc IDataFeedStrategy\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public periodDuration;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public strategyCooldown;\n\n /// @inheritdoc IDataFeedStrategy\n uint24 public twapThreshold;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public twapLength;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(\n address _governor,\n IDataFeed _dataFeed,\n StrategySettings memory _params\n ) Governable(_governor) {\n dataFeed = _dataFeed;\n _setStrategyCooldown(_params.cooldown);\n _setTwapLength(_params.twapLength);\n _setTwapThreshold(_params.twapThreshold);\n _setPeriodDuration(_params.periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n if (!_isStrategic(_poolSalt, _lastPoolStateObserved, _reason)) revert NotStrategic();\n uint32[] memory _secondsAgos = calculateSecondsAgos(_lastPoolStateObserved.blockTimestamp);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n emit StrategicFetch(_poolSalt, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n /// @dev Allows governor to choose a timestamp from which to send data (overcome !OLD error)\n function forceFetchObservations(bytes32 _poolSalt, uint32 _fromTimestamp) external onlyGovernor {\n uint32[] memory _secondsAgos = calculateSecondsAgos(_fromTimestamp);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setStrategyCooldown(uint32 _strategyCooldown) external onlyGovernor {\n _setStrategyCooldown(_strategyCooldown);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapLength(uint32 _twapLength) external onlyGovernor {\n _setTwapLength(_twapLength);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapThreshold(uint24 _twapThreshold) external onlyGovernor {\n _setTwapThreshold(_twapThreshold);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setPeriodDuration(uint32 _periodDuration) external onlyGovernor {\n _setPeriodDuration(_periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason) {\n if (isStrategic(_poolSalt, TriggerReason.TIME)) return TriggerReason.TIME;\n if (isStrategic(_poolSalt, TriggerReason.TWAP)) return TriggerReason.TWAP;\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) public view returns (bool _strategic) {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n return _isStrategic(_poolSalt, _lastPoolStateObserved, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function calculateSecondsAgos(uint32 _fromTimestamp) public view returns (uint32[] memory _secondsAgos) {\n if (_fromTimestamp == 0) return _initializeSecondsAgos();\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _timeSinceLastObservation = _secondsNow - _fromTimestamp;\n uint32 _periodDuration = periodDuration;\n uint32 _periods = _timeSinceLastObservation / _periodDuration;\n uint32 _remainder = _timeSinceLastObservation % _periodDuration;\n uint32 _i;\n\n if (_remainder != 0) {\n _secondsAgos = new uint32[](++_periods);\n _timeSinceLastObservation -= _remainder;\n _secondsAgos[_i++] = _timeSinceLastObservation;\n } else {\n _secondsAgos = new uint32[](_periods);\n }\n\n while (_timeSinceLastObservation > 0) {\n _timeSinceLastObservation -= _periodDuration;\n _secondsAgos[_i++] = _timeSinceLastObservation;\n }\n }\n\n function _isStrategic(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n TriggerReason _reason\n ) internal view returns (bool _strategic) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n if (_reason == TriggerReason.TIME) {\n return _secondsNow >= _lastPoolStateObserved.blockTimestamp + strategyCooldown;\n } else if (_reason == TriggerReason.TWAP) {\n return _twapIsOutOfThresholds(_poolSalt, _lastPoolStateObserved, _secondsNow);\n }\n }\n\n function _twapIsOutOfThresholds(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n uint32 _secondsNow\n ) internal view returns (bool _isOutOfThresholds) {\n uint32 _twapLength = twapLength;\n\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[0] = _twapLength;\n _secondsAgos[1] = 0;\n\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _poolTickCumulatives, ) = _pool.observe(_secondsAgos);\n\n int24 _poolArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _poolTickCumulatives[1], _twapLength);\n\n uint32 _oracleDelta = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n int56 _oracleTickCumulative = _lastPoolStateObserved.tickCumulative + int56(_lastPoolStateObserved.arithmeticMeanTick) * int32(_oracleDelta);\n\n int24 _oracleArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _oracleTickCumulative, _twapLength);\n\n return\n _poolArithmeticMeanTick > _oracleArithmeticMeanTick + int24(twapThreshold) ||\n _poolArithmeticMeanTick < _oracleArithmeticMeanTick - int24(twapThreshold);\n }\n\n function _computeTwap(\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n uint32 _delta\n ) internal pure returns (int24 _arithmeticMeanTick) {\n int56 _tickCumulativesDelta = _tickCumulative2 - _tickCumulative1;\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n }\n\n function _initializeSecondsAgos() internal view returns (uint32[] memory _secondsAgos) {\n // TODO: define initialization of _secondsAgos\n _secondsAgos = new uint32[](2);\n _secondsAgos[0] = periodDuration;\n _secondsAgos[1] = 0; // as if _fromTimestamp = _secondsNow - (periodDuration + 1)\n }\n\n function _setStrategyCooldown(uint32 _strategyCooldown) private {\n if (_strategyCooldown < twapLength) revert WrongSetting();\n\n strategyCooldown = _strategyCooldown;\n emit StrategyCooldownSet(_strategyCooldown);\n }\n\n function _setTwapLength(uint32 _twapLength) private {\n if ((_twapLength > strategyCooldown) || (_twapLength < periodDuration)) revert WrongSetting();\n\n twapLength = _twapLength;\n emit TwapLengthSet(_twapLength);\n }\n\n function _setTwapThreshold(uint24 _twapThreshold) private {\n twapThreshold = _twapThreshold;\n emit TwapThresholdSet(_twapThreshold);\n }\n\n function _setPeriodDuration(uint32 _periodDuration) private {\n if (_periodDuration > twapLength) revert WrongSetting();\n\n periodDuration = _periodDuration;\n emit PeriodDurationSet(_periodDuration);\n }\n}\n" - }, - "solidity/contracts/peripherals/Keep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './Governable.sol';\nimport {IKeep3rJob, IKeep3r} from '../../interfaces/peripherals/IKeep3rJob.sol';\n\nabstract contract Keep3rJob is IKeep3rJob, Governable {\n /// @inheritdoc IKeep3rJob\n IKeep3r public keep3r = IKeep3r(0xeb02addCfD8B773A5FFA6B9d1FE99c566f8c44CC);\n\n /// @inheritdoc IKeep3rJob\n function setKeep3r(IKeep3r _keep3r) public onlyGovernor {\n _setKeep3r(_keep3r);\n }\n\n function _setKeep3r(IKeep3r _keep3r) internal {\n keep3r = _keep3r;\n emit Keep3rSet(_keep3r);\n }\n\n function _isValidKeeper(address _keeper) internal virtual {\n if (!keep3r.isKeeper(_keeper)) revert KeeperNotValid();\n }\n\n modifier upkeep() {\n _isValidKeeper(msg.sender);\n _;\n keep3r.worked(msg.sender);\n }\n}\n" - }, - "solidity/for-test/Keep3rJobForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from '../contracts/peripherals/Keep3rJob.sol';\n\ncontract Keep3rJobForTest is Keep3rJob {\n constructor(address _governor) Governable(_governor) {}\n\n function internalIsValidKeeper(address _keeper) external {\n _isValidKeeper(_keeper);\n }\n}\n" - }, - "solidity/contracts/StrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from './peripherals/Keep3rJob.sol';\nimport {IStrategyJob, IDataFeedStrategy, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IStrategyJob.sol';\n\n/// @title The StrategyJob contract\n/// @notice Adds a reward layer for triggering fetch and bridge transactions\ncontract StrategyJob is IStrategyJob, Keep3rJob {\n /// @inheritdoc IStrategyJob\n IDataFeedStrategy public immutable dataFeedStrategy;\n\n /// @inheritdoc IStrategyJob\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IStrategyJob\n IBridgeSenderAdapter public defaultBridgeSenderAdapter;\n\n /// @inheritdoc IStrategyJob\n mapping(uint32 => mapping(bytes32 => uint24)) public lastPoolNonceBridged;\n\n constructor(\n address _governor,\n IDataFeedStrategy _dataFeedStrategy,\n IDataFeed _dataFeed,\n IBridgeSenderAdapter _defaultBridgeSenderAdapter\n ) Governable(_governor) {\n dataFeedStrategy = _dataFeedStrategy;\n dataFeed = _dataFeed;\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external upkeep {\n // TODO: change criteria for workable (if there's a new nonce, bridge)\n if (!_workable(_chainId, _poolSalt, _poolNonce)) revert NotWorkable();\n lastPoolNonceBridged[_chainId][_poolSalt] = _poolNonce;\n dataFeed.sendObservations(defaultBridgeSenderAdapter, _chainId, _poolSalt, _poolNonce, _observationsData);\n }\n\n /// @inheritdoc IStrategyJob\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external upkeep {\n dataFeedStrategy.strategicFetchObservations(_poolSalt, _reason);\n }\n\n /// @inheritdoc IStrategyJob\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external onlyGovernor {\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) public view returns (bool _isWorkable) {\n uint24 _whitelistedNonce = dataFeed.whitelistedNonces(_chainId, _poolSalt);\n if (_whitelistedNonce != 0 && _whitelistedNonce <= _poolNonce) return _workable(_chainId, _poolSalt, _poolNonce);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) public view returns (bool _isWorkable) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt, _reason);\n }\n\n function _workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal view returns (bool _isWorkable) {\n uint24 _lastPoolNonceBridged = lastPoolNonceBridged[_chainId][_poolSalt];\n if (_lastPoolNonceBridged == 0) {\n (uint24 _lastPoolNonceObserved, , , ) = dataFeed.lastPoolStateObserved(_poolSalt);\n return _poolNonce == _lastPoolNonceObserved;\n } else {\n return _poolNonce == ++_lastPoolNonceBridged;\n }\n }\n\n function _setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) private {\n defaultBridgeSenderAdapter = _defaultBridgeSenderAdapter;\n emit DefaultBridgeSenderAdapterSet(_defaultBridgeSenderAdapter);\n }\n}\n" - }, - "solidity/contracts/bridges/ConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {BridgeReceiverAdapter} from './BridgeReceiverAdapter.sol';\nimport {IConnext, IConnextReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IConnextReceiverAdapter.sol';\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextReceiverAdapter is BridgeReceiverAdapter, IXReceiver, IConnextReceiverAdapter {\n // The connectHandler contract on this domain\n IConnext public immutable connext;\n // The origin domain ID\n uint32 public immutable originDomain;\n // The DAO that's expected as the xcaller\n address public immutable source;\n\n constructor(\n IDataReceiver _dataReceiver,\n address _source,\n uint32 _originDomain,\n IConnext _connext\n ) BridgeReceiverAdapter(_dataReceiver) {\n source = _source;\n originDomain = _originDomain;\n connext = _connext;\n }\n\n function xReceive(\n bytes32, // _transferId\n uint256, // _amount\n address, // _asset\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external onlyExecutor(_originSender, _origin) returns (bytes memory) {\n (IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, uint24 _poolNonce) = abi.decode(\n _callData,\n (IOracleSidechain.ObservationData[], bytes32, uint24)\n );\n\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n return bytes(abi.encode(''));\n }\n\n modifier onlyExecutor(address _originSender, uint32 _originDomain) {\n if (msg.sender != address(connext) || _originSender != source || _originDomain != originDomain) revert UnauthorizedCaller();\n _;\n }\n}\n" - }, - "solidity/contracts/bridges/BridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IBridgeReceiverAdapter.sol';\n\nabstract contract BridgeReceiverAdapter is IBridgeReceiverAdapter {\n /// @inheritdoc IBridgeReceiverAdapter\n IDataReceiver public immutable dataReceiver;\n\n constructor(IDataReceiver _dataReceiver) {\n dataReceiver = _dataReceiver;\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n dataReceiver.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface IXReceiver {\n function xReceive(\n bytes32 _transferId,\n uint256 _amount,\n address _asset,\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external returns (bytes memory);\n}\n" - }, - "solidity/for-test/ConnextHandlerForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextHandlerForTest {\n uint32 public origin;\n\n constructor() {\n // TODO: set in constructor\n origin = 1111;\n }\n\n function xcall(\n uint32, // _destination, unique identifier for destination domain\n address _to, // recipient of funds, where calldata will be executed\n address, // _asset, asset being transferred\n address, // _delegate, permissioned address to recover in edgecases on destination domain\n uint256, // _amount, amount being transferred\n uint256, // _slippage, slippage in bps\n bytes calldata _callData // to be executed on _to on the destination domain\n ) external payable returns (bytes32) {\n IXReceiver(_to).xReceive({_transferId: 0, _amount: 0, _asset: address(0), _originSender: msg.sender, _origin: origin, _callData: _callData});\n\n return bytes32(abi.encode('random'));\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file diff --git a/deployments/ethereum/solcInputs/eef40425e50b109f1821184fab9444c8.json b/deployments/ethereum/solcInputs/eef40425e50b109f1821184fab9444c8.json deleted file mode 100644 index 13fa902..0000000 --- a/deployments/ethereum/solcInputs/eef40425e50b109f1821184fab9444c8.json +++ /dev/null @@ -1,278 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "solidity/contracts/DataFeed.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {PipelineManagement, Governable} from './peripherals/PipelineManagement.sol';\nimport {IDataFeed, IDataFeedStrategy, IUniswapV3Pool, IConnextSenderAdapter, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeed.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The DataFeed interface\n/// @notice Queries UniV3Pools, stores history proofs on chain, handles data broadcast\ncontract DataFeed is IDataFeed, PipelineManagement {\n /// @inheritdoc IDataFeed\n IDataFeedStrategy public strategy;\n\n /// @inheritdoc IDataFeed\n mapping(bytes32 => PoolState) public lastPoolStateObserved;\n\n mapping(bytes32 => bool) internal _observedKeccak;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(address _governor, IDataFeedStrategy _strategy) Governable(_governor) {\n _setStrategy(_strategy);\n }\n\n /// @inheritdoc IDataFeed\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external validatePipeline(_chainId, _poolSalt, _poolNonce) {\n (uint32 _destinationDomainId, address _dataReceiver) = validateSenderAdapter(_bridgeSenderAdapter, _chainId);\n\n {\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _poolNonce, _observationsData));\n if (!_observedKeccak[_resultingKeccak]) revert UnknownHash();\n }\n\n _bridgeSenderAdapter.bridgeObservations(_dataReceiver, _destinationDomainId, _observationsData, _poolSalt, _poolNonce);\n emit DataBroadcast(_poolSalt, _poolNonce, _chainId, _dataReceiver, _bridgeSenderAdapter);\n }\n\n /// @inheritdoc IDataFeed\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external onlyStrategy validatePool(_poolSalt) {\n IOracleSidechain.ObservationData[] memory _observationsData;\n PoolState memory _lastPoolStateObserved = lastPoolStateObserved[_poolSalt];\n\n {\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _tickCumulatives, ) = _pool.observe(_secondsAgos);\n\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _secondsAgo;\n int56 _tickCumulative;\n int24 _arithmeticMeanTick;\n uint256 _secondsAgosLength = _secondsAgos.length;\n uint256 _i;\n\n // If first fetched observation\n if (_lastPoolStateObserved.blockTimestamp == 0) {\n if (_secondsAgosLength == 1) revert InvalidSecondsAgos();\n // Initializes timestamp and cumulative with first item\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength - 1);\n _secondsAgo = _secondsAgos[0];\n _tickCumulative = _tickCumulatives[0];\n // Skips first loop iteration\n // Cannot not calculate twap (there is no last tickCumulative)\n unchecked {\n ++_i;\n }\n } else {\n // Initializes timestamp and cumulative with cache\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength);\n _secondsAgo = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n _tickCumulative = _lastPoolStateObserved.tickCumulative;\n }\n\n uint32 _delta;\n int56 _tickCumulativesDelta;\n uint256 _observationsDataIndex;\n\n for (; _i < _secondsAgosLength; ) {\n // Twap is calculated using the last recorded tickCumulative and time\n _tickCumulativesDelta = _tickCumulatives[_i] - _tickCumulative;\n _delta = _secondsAgo - _secondsAgos[_i];\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n\n // Stores blockTimestamp and tick in observations array\n _observationsData[_observationsDataIndex++] = IOracleSidechain.ObservationData({\n blockTimestamp: _secondsNow - _secondsAgo,\n tick: _arithmeticMeanTick\n });\n\n // Updates state for next iteration calculation\n _secondsAgo = _secondsAgos[_i];\n _tickCumulative = _tickCumulatives[_i];\n\n unchecked {\n ++_i;\n }\n }\n\n _lastPoolStateObserved = PoolState({\n poolNonce: _lastPoolStateObserved.poolNonce + 1,\n blockTimestamp: _secondsNow - _secondsAgo,\n tickCumulative: _tickCumulative,\n arithmeticMeanTick: _arithmeticMeanTick\n });\n }\n\n // Stores last pool state in the contract cache\n lastPoolStateObserved[_poolSalt] = _lastPoolStateObserved;\n\n // Whitelists keccak256 to be broadcast to other chains\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData));\n _observedKeccak[_resultingKeccak] = true;\n\n // Emits event with data to be read off-chain and used as broadcast input parameters\n emit PoolObserved(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData);\n }\n\n /// @inheritdoc IDataFeed\n function setStrategy(IDataFeedStrategy _strategy) external onlyGovernor {\n _setStrategy(_strategy);\n }\n\n function _setStrategy(IDataFeedStrategy _strategy) private {\n strategy = _strategy;\n emit StrategySet(_strategy);\n }\n\n modifier onlyStrategy() {\n if (msg.sender != address(strategy)) revert OnlyStrategy();\n _;\n }\n}\n" - }, - "solidity/contracts/peripherals/PipelineManagement.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './Governable.sol';\nimport {IPipelineManagement, IBridgeSenderAdapter} from '../../interfaces/peripherals/IPipelineManagement.sol';\nimport {IDataFeed} from '../../interfaces/IDataFeed.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\n\nabstract contract PipelineManagement is IPipelineManagement, Governable {\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n EnumerableSet.Bytes32Set private _whitelistedPools;\n\n /// @inheritdoc IPipelineManagement\n mapping(uint32 => mapping(bytes32 => uint24)) public whitelistedNonces;\n\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => bool) public whitelistedAdapters;\n\n // adapter => chainId => destinationDomain\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => uint32)) public destinationDomainIds;\n\n // adapter => destinationDomainId => dataReceiver\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => address)) public receivers;\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external onlyGovernor {\n _whitelistPipeline(_chainId, _poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external onlyGovernor {\n uint256 _chainIdsLength = _chainIds.length;\n if (_chainIdsLength != _poolSalts.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _chainIdsLength; ++_i) {\n _whitelistPipeline(_chainIds[_i], _poolSalts[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _whitelistAdapter(_bridgeSenderAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external onlyGovernor {\n _setDestinationDomainId(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _chainIds,\n uint32[] calldata _destinationDomainIds\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _chainIds.length || _bridgeSenderAdapterLength != _destinationDomainIds.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setDestinationDomainId(_bridgeSenderAdapters[_i], _chainIds[_i], _destinationDomainIds[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external onlyGovernor {\n _setReceiver(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _destinationDomainIds.length || _bridgeSenderAdapterLength != _dataReceivers.length)\n revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setReceiver(_bridgeSenderAdapters[_i], _destinationDomainIds[_i], _dataReceivers[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistedPools() external view returns (bytes32[] memory) {\n return _whitelistedPools.values();\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return _whitelistedPools.contains(_poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return whitelistedNonces[_chainId][_poolSalt] != 0;\n }\n\n /// @inheritdoc IPipelineManagement\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n public\n view\n returns (uint32 _destinationDomainId, address _dataReceiver)\n {\n if (!whitelistedAdapters[_bridgeSenderAdapter]) revert UnallowedAdapter();\n\n _destinationDomainId = destinationDomainIds[_bridgeSenderAdapter][_chainId];\n if (_destinationDomainId == 0) revert DestinationDomainIdNotSet();\n\n _dataReceiver = receivers[_bridgeSenderAdapter][_destinationDomainId];\n if (_dataReceiver == address(0)) revert ReceiverNotSet();\n }\n\n function _whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) internal {\n (uint24 _lastPoolNonceObserved, , , ) = IDataFeed(address(this)).lastPoolStateObserved(_poolSalt);\n whitelistedNonces[_chainId][_poolSalt] = _lastPoolNonceObserved + 1;\n _whitelistedPools.add(_poolSalt);\n emit PipelineWhitelisted(_chainId, _poolSalt, _lastPoolNonceObserved + 1);\n }\n\n function _whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_bridgeSenderAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n function _setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) internal {\n destinationDomainIds[_bridgeSenderAdapter][_chainId] = _destinationDomainId;\n emit DestinationDomainIdSet(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n function _setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) internal {\n receivers[_bridgeSenderAdapter][_destinationDomainId] = _dataReceiver;\n emit ReceiverSet(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n modifier validatePool(bytes32 _poolSalt) {\n if (!_whitelistedPools.contains(_poolSalt)) revert UnallowedPool();\n _;\n }\n\n modifier validatePipeline(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) {\n uint24 _whitelistedNonce = whitelistedNonces[_chainId][_poolSalt];\n if (_whitelistedNonce == 0) revert UnallowedPipeline();\n if (_whitelistedNonce > _poolNonce) revert WrongNonce();\n _;\n }\n}\n" - }, - "solidity/interfaces/IDataFeed.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IPipelineManagement} from './peripherals/IPipelineManagement.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IConnextSenderAdapter} from './bridges/IConnextSenderAdapter.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IDataFeed is IPipelineManagement {\n // STRUCTS\n\n struct PoolState {\n uint24 poolNonce; // Nonce of the last observation\n uint32 blockTimestamp; // Last observed timestamp\n int56 tickCumulative; // Pool's tickCumulative at last observed timestamp\n int24 arithmeticMeanTick; // Last calculated twap\n }\n\n // STATE VARIABLES\n\n /// @return _strategy Address of the contract allowed to trigger an oracle update\n /// @dev The strategy should define when and with which timestamps the pool should be read\n function strategy() external view returns (IDataFeedStrategy _strategy);\n\n /// @notice Tracks the last observed pool state by salt\n /// @param _poolSalt The id of both the oracle and the pool\n /// @return _lastPoolNonceObserved Nonce of the last observation\n /// @return _lastBlockTimestampObserved Last observed timestamp\n /// @return _lastTickCumulativeObserved Pool's tickCumulative at last observed timestamp\n /// @return _lastArithmeticMeanTickObserved Last calculated twap\n function lastPoolStateObserved(bytes32 _poolSalt)\n external\n view\n returns (\n uint24 _lastPoolNonceObserved,\n uint32 _lastBlockTimestampObserved,\n int56 _lastTickCumulativeObserved,\n int24 _lastArithmeticMeanTickObserved\n );\n\n // EVENTS\n\n /// @notice Emitted when a data batch is broadcast\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _dataReceiver Address of the targetted contract receiving the data\n /// @param _chainId Identifier number of the targetted chain\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n event DataBroadcast(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n uint32 _chainId,\n address _dataReceiver,\n IBridgeSenderAdapter _bridgeSenderAdapter\n );\n\n /// @notice Emitted when a data batch is observed\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n /// @param _observationsData Timestamp and tick data of the broadcast nonce\n event PoolObserved(bytes32 indexed _poolSalt, uint24 _poolNonce, IOracleSidechain.ObservationData[] _observationsData);\n\n /// @notice Emitted when the Strategy contract is set\n /// @param _strategy Address of the new strategy\n event StrategySet(IDataFeedStrategy _strategy);\n\n // ERRORS\n\n /// @notice Throws if set of secondsAgos is invalid to update the oracle\n error InvalidSecondsAgos();\n\n /// @notice Throws if an unknown dataset is being broadcast\n error UnknownHash();\n\n /// @notice Throws if a contract other than Strategy calls an update\n error OnlyStrategy();\n\n // FUNCTIONS\n\n /// @notice Broadcasts a validated set of datapoints to a bridge adapter\n /// @dev Permisionless, input parameters are validated to ensure being correct\n /// @param _bridgeSenderAdapter Address of the bridge adapter\n /// @param _chainId Identifier of the receiving chain\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _poolNonce Nonce identifier of the dataset\n /// @param _observationsData Array of tuples representing broadcast dataset\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Triggers an update of the oracle state\n /// @dev Permisioned, callable only by Strategy\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _secondsAgos Set of time periods to consult the pool with\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external;\n\n /// @notice Updates the Strategy address\n /// @dev Permisioned, callable only by Governor\n /// @param _strategy Address of the new Strategy\n function setStrategy(IDataFeedStrategy _strategy) external;\n}\n" - }, - "solidity/libraries/Create2Address.sol": { - "content": "//SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.8 <0.9.0;\n\n/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee\nlibrary Create2Address {\n /// @notice Deterministically computes the pool address given the factory, salt and initCodeHash\n /// @param _factory The Uniswap V3 factory contract address\n /// @param _salt The PoolKey encoded bytes\n /// @param _initCodeHash The Init Code Hash of the target\n /// @return _pool The contract address of the target pool/oracle\n function computeAddress(\n address _factory,\n bytes32 _salt,\n bytes32 _initCodeHash\n ) internal pure returns (address _pool) {\n _pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', _factory, _salt, _initCodeHash)))));\n }\n}\n" - }, - "solidity/contracts/peripherals/Governable.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public governor;\n\n /// @inheritdoc IGovernable\n address public pendingGovernor;\n\n constructor(address _governor) {\n if (_governor == address(0)) revert ZeroAddress();\n governor = _governor;\n }\n\n /// @inheritdoc IGovernable\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\n _setPendingGovernor(_pendingGovernor);\n }\n\n /// @inheritdoc IGovernable\n function acceptPendingGovernor() external onlyPendingGovernor {\n _acceptPendingGovernor();\n }\n\n function _setPendingGovernor(address _pendingGovernor) internal {\n if (_pendingGovernor == address(0)) revert ZeroAddress();\n pendingGovernor = _pendingGovernor;\n emit PendingGovernorSet(governor, pendingGovernor);\n }\n\n function _acceptPendingGovernor() internal {\n governor = pendingGovernor;\n pendingGovernor = address(0);\n emit PendingGovernorAccepted(governor);\n }\n\n modifier onlyGovernor() {\n if (msg.sender != governor) revert OnlyGovernor();\n _;\n }\n\n modifier onlyPendingGovernor() {\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\n _;\n }\n}\n" - }, - "solidity/interfaces/peripherals/IPipelineManagement.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './IGovernable.sol';\nimport {IBridgeSenderAdapter} from '../bridges/IBridgeSenderAdapter.sol';\n\ninterface IPipelineManagement is IGovernable {\n // STATE VARIABLES\n\n function whitelistedNonces(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _whitelistedNonce);\n\n function whitelistedAdapters(IBridgeSenderAdapter _bridgeSenderAdapter) external view returns (bool _isWhitelisted);\n\n function destinationDomainIds(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId) external view returns (uint32 _destinationDomainId);\n\n function receivers(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId) external view returns (address _dataReceiver);\n\n // EVENTS\n\n event PipelineWhitelisted(uint32 _chainId, bytes32 indexed _poolSalt, uint24 _whitelistedNonce);\n\n event AdapterWhitelisted(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted);\n\n event DestinationDomainIdSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId, uint32 _destinationDomainId);\n\n event ReceiverSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId, address _dataReceiver);\n\n // ERRORS\n\n error UnallowedPool();\n\n error UnallowedPipeline();\n\n error WrongNonce();\n\n error UnallowedAdapter();\n\n error DestinationDomainIdNotSet();\n\n error ReceiverNotSet();\n\n error LengthMismatch();\n\n // FUNCTIONS\n\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external;\n\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external;\n\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external;\n\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external;\n\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external;\n\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapter,\n uint32[] calldata _chainId,\n uint32[] calldata _destinationDomainId\n ) external;\n\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external;\n\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external;\n\n function whitelistedPools() external view returns (bytes32[] memory);\n\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n external\n view\n returns (uint32 _destinationDomainId, address _dataReceiver);\n}\n" - }, - "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 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 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 => 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 return _values(set._inner);\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 on 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" - }, - "solidity/interfaces/peripherals/IGovernable.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\ninterface IGovernable {\n // STATE VARIABLES\n\n /// @return _governor Address of the current governor\n function governor() external view returns (address _governor);\n\n /// @return _pendingGovernor Address of the current pending governor\n function pendingGovernor() external view returns (address _pendingGovernor);\n\n // EVENTS\n\n /// @notice Emitted when a new pending governor is set\n /// @param _governor Address of the current governor\n /// @param _pendingGovernor Address of the proposed next governor\n event PendingGovernorSet(address _governor, address _pendingGovernor);\n\n /// @notice Emitted when a new governor is set\n /// @param _newGovernor Address of the new governor\n event PendingGovernorAccepted(address _newGovernor);\n\n // ERRORS\n\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n\n /// @notice Throws if a non-governor user tries to call a OnlyGovernor function\n error OnlyGovernor();\n\n /// @notice Throws if a non-pending-governor user tries to call a OnlyPendingGovernor function\n error OnlyPendingGovernor();\n\n // FUNCTIONS\n\n /// @notice Allows a governor to propose a new governor\n /// @param _pendingGovernor Address of the proposed new governor\n function setPendingGovernor(address _pendingGovernor) external;\n\n /// @notice Allows a proposed governor to accept the governance\n function acceptPendingGovernor() external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeSenderAdapter {\n // FUNCTIONS\n\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable;\n\n // ERRORS\n\n error OnlyDataFeed();\n}\n" - }, - "solidity/interfaces/IOracleSidechain.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleFactory} from './IOracleFactory.sol';\n\ninterface IOracleSidechain {\n // STRUCTS\n\n struct ObservationData {\n uint32 blockTimestamp;\n int24 tick;\n }\n\n // STATE VARIABLES\n\n // TODO: complete natspec\n\n /// @return _oracleFactory The address of the OracleFactory\n function factory() external view returns (IOracleFactory _oracleFactory);\n\n /// @return _token0 The mainnet address of the Token0 of the oracle\n function token0() external view returns (address _token0);\n\n /// @return _token1 The mainnet address of the Token1 of the oracle\n function token1() external view returns (address _token1);\n\n /// @return _fee The fee identifier of the pool\n function fee() external view returns (uint24 _fee);\n\n /// @return _poolSalt The identifier of both the pool and the oracle\n function poolSalt() external view returns (bytes32 _poolSalt);\n\n /// @return _poolNonce Last recorded nonce of the pool history\n function poolNonce() external view returns (uint24 _poolNonce);\n\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\n /// @return _tick Used to maintain compatibility with Uniswap V3\n /// @return _observationIndex The index of the last oracle observation that was written,\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\n /// @return _unlocked Used to track if a pool information was already verified\n function slot0()\n external\n view\n returns (\n uint160 _sqrtPriceX96,\n int24 _tick,\n uint16 _observationIndex,\n uint16 _observationCardinality,\n uint16 _observationCardinalityNext,\n uint8 _feeProtocol,\n bool _unlocked\n );\n\n /// @notice Returns data about a specific observation index\n /// @param _index The element of the observations array to fetch\n /// @return _blockTimestamp The timestamp of the observation,\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return _initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 _index)\n external\n view\n returns (\n uint32 _blockTimestamp,\n int56 _tickCumulative,\n uint160 _secondsPerLiquidityCumulativeX128,\n bool _initialized\n );\n\n // EVENTS\n\n /// @notice Emitted when the pool information is verified\n /// @param _poolSalt Identifier of the pool and the oracle\n /// @param _token0 The contract address of either token0 or token1\n /// @param _token1 The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\n\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param _tick The log base 1.0001 of price of the pool after the swap\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\n\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\n\n // ERRORS\n\n error AI();\n error InvalidPool();\n error OnlyDataReceiver();\n error OnlyFactory();\n\n // FUNCTIONS\n\n /// @notice Permisionless method to verify token0, token1 and fee\n /// @dev Before verified, token0 and token1 views will return address(0)\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external;\n\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\n\n /// @notice Permisioned method to push a dataset to update\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolNonce Nonce of the observation broadcast\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\n\n /// @notice Permisioned method to increase the cardinalityNext value\n /// @param _observationCardinalityNext The new next length of the observations array\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\n}\n" - }, - "solidity/interfaces/IOracleFactory.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IDataReceiver} from './IDataReceiver.sol';\n\ninterface IOracleFactory is IGovernable {\n // STRUCTS\n\n struct OracleParameters {\n bytes32 poolSalt; // Identifier of the pool and oracle\n uint24 poolNonce; // Initial nonce of the deployed pool\n uint16 cardinality; // Initial cardinality of the deployed pool\n }\n\n // STATE VARIABLES\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /// @return _poolSalt The id of both the oracle and the pool\n /// @return _poolNonce The initial nonce of the pool data\n /// @return _cardinality The size of the observations memory storage\n function oracleParameters()\n external\n view\n returns (\n bytes32 _poolSalt,\n uint24 _poolNonce,\n uint16 _cardinality\n );\n\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function initialCardinality() external view returns (uint16 _initialCardinality);\n\n // EVENTS\n\n /// @notice Emitted when a new oracle is deployed\n /// @param _poolSalt The id of both the oracle and the pool\n /// @param _oracle The address of the deployed oracle\n /// @param _initialNonce The initial nonce of the pool data\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\n\n /// @notice Emitted when a new DataReceiver is set\n /// @param _dataReceiver The address of the new DataReceiver\n event DataReceiverSet(IDataReceiver _dataReceiver);\n\n /// @notice Emitted when a new initial oracle cardinality is set\n /// @param _initialCardinality The initial length of the observationCardinality array\n event InitialCardinalitySet(uint16 _initialCardinality);\n\n // ERRORS\n\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\n error OnlyDataReceiver();\n\n // FUNCTIONS\n\n /// @notice Deploys a new oracle given an inputted salt\n /// @dev Requires that the salt has not been deployed before\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\n /// @return _oracle The address of the newly deployed oracle\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\n\n /// @notice Allows governor to set a new allowed dataReceiver\n /// @dev Will disallow the previous dataReceiver\n /// @param _dataReceiver The address of the new allowed dataReceiver\n function setDataReceiver(IDataReceiver _dataReceiver) external;\n\n /// @notice Allows governor to set a new initial cardinality for new oracles\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function setInitialCardinality(uint16 _initialCardinality) external;\n\n /// @notice Overrides UniV3Factory getPool mapping\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _oracle The oracle address\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle);\n\n /// @notice Tracks the addresses of the oracle by poolSalt\n /// @param _poolSalt Identifier of both the pool and the oracle\n /// @return _oracle The address (if deployed) of the correspondant oracle\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\n\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _poolSalt Pool salt for inquired parameters\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (bytes32 _poolSalt);\n}\n" - }, - "solidity/interfaces/IDataReceiver.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IOracleFactory} from './IOracleFactory.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\n\ninterface IDataReceiver is IGovernable {\n // STATE VARIABLES\n\n /// @return _oracleFactory The address of the OracleFactory\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\n\n /// @notice Tracks already deployed oracles\n /// @param _poolSalt The identifier of the oracle\n /// @return _deployedOracle The address of the correspondant Oracle\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\n\n /// @notice Tracks the whitelisting of bridge adapters\n /// @param _adapter Address of the bridge adapter to consult\n /// @return _isAllowed Whether a bridge adapter is whitelisted\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n // EVENTS\n\n /// @notice Emitted when a broadcast observation is succesfully processed\n /// @param _poolSalt Identifier of the pool to fetch\n /// @return _poolNonce Nonce of the observation broadcast\n /// @return _observationsData Array of tuples containing the dataset\n /// @return _receiverAdapter Handler of the broadcast\n event ObservationsAdded(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] _observationsData,\n address _receiverAdapter\n );\n\n /// @notice Emitted when a new adapter whitelisting rule is set\n /// @param _adapter Address of the adapter\n /// @param _isAllowed New whitelisting status\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\n\n // ERRORS\n\n /// @notice Thrown when the broadcast nonce is incorrect\n error ObservationsNotWritable();\n\n /// @notice Thrown when a not-whitelisted adapter triggers an update\n error UnallowedAdapter();\n\n /// @notice Thrown when mismatching lists length\n error LengthMismatch();\n\n // FUNCTIONS\n\n /// @notice Allows whitelisted bridge adapters to push a broadcast\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _poolNonce Nonce of the observation broadcast\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external;\n\n /// @notice Allows governance to set an adapter whitelisted state\n /// @param _receiverAdapter Address of the adapter\n /// @param _isWhitelisted New whitelisting status\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\n\n /// @notice Allows governance to batch set adapters whitelisted state\n /// @param _receiverAdapters Array of addresses of the adapter\n /// @param _isWhitelisted Array of whitelisting status for each address\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IDataReceiver} from '../IDataReceiver.sol';\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeReceiverAdapter {\n // FUNCTIONS\n\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /* NOTE: callback methods should be here declared */\n\n // ERRORS\n\n error UnauthorizedCaller();\n}\n" - }, - "solidity/interfaces/IDataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\n\ninterface IDataFeedStrategy is IGovernable {\n // ENUMS\n\n enum TriggerReason {\n NONE,\n TIME,\n TWAP\n }\n\n // STRUCTS\n\n struct StrategySettings {\n uint32 periodDuration; // Resolution of the oracle, target twap length\n uint32 cooldown; // Time since last update to wait to time-trigger update\n uint24 twapThreshold; // Twap difference, in ticks, to twap-trigger update\n uint32 twapLength; // Twap length, in seconds, used for twap-trigger update\n }\n\n // STATE VARIABLES\n\n /// @return _dataFeed The address of the DataFeed contract\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _strategyCooldown Time in seconds since last update required to time-trigger an update\n function strategyCooldown() external view returns (uint32 _strategyCooldown);\n\n /// @return _periodDuration The targetted amount of seconds between pool consultations\n /// @dev Defines the resolution of the oracle, averaging data between consultations\n function periodDuration() external view returns (uint32 _periodDuration);\n\n /// @return _twapThreshold Twap difference, in ticks, to twap-trigger an update\n function twapThreshold() external view returns (uint24 _twapThreshold);\n\n /// @return _twapLength The time length, in seconds, used to calculate twap-trigger\n function twapLength() external view returns (uint32 _twapLength);\n\n // EVENTS\n\n /// @notice Emitted when a data fetch is triggered\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier number of the reason that triggered the fetch request\n event StrategicFetch(bytes32 indexed _poolSalt, TriggerReason _reason);\n\n /// @notice Emitted when the owner updates the job cooldown\n /// @param _strategyCooldown The new job cooldown\n event StrategyCooldownSet(uint32 _strategyCooldown);\n\n /// @notice Emitted when the owner updates the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n event TwapLengthSet(uint32 _twapLength);\n\n /// @notice Emitted when the owner updates the job twap threshold percentage\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n event TwapThresholdSet(uint24 _twapThreshold);\n\n /// @notice Emitted when the owner updates the job period length\n /// @param _periodDuration The new length of reading resolution periods\n event PeriodDurationSet(uint32 _periodDuration);\n\n // ERRORS\n\n /// @notice Thrown if the tx is not strategic\n error NotStrategic();\n\n /// @notice Thrown if setting breaks strategyCooldown >= twapLength >= periodDuration\n error WrongSetting();\n\n // FUNCTIONS\n\n /// @notice Permisionless, used to update the oracle state\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier of trigger reason (time/twap)\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external;\n\n /// @notice Permisioned, used to update the oracle state from a given timestamp\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _fromTimestamp Timestamp to start backfilling from\n function forceFetchObservations(bytes32 _poolSalt, uint32 _fromTimestamp) external;\n\n /// @notice Sets the job cooldown\n /// @param _strategyCooldown The job cooldown to be set\n function setStrategyCooldown(uint32 _strategyCooldown) external;\n\n /// @notice Sets the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n function setTwapLength(uint32 _twapLength) external;\n\n /// @notice Sets the job twap threshold percentage\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n function setTwapThreshold(uint24 _twapThreshold) external;\n\n /// @notice Sets the job period length\n /// @param _periodDuration The new length of reading resolution periods\n function setPeriodDuration(uint32 _periodDuration) external;\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the strategy can be executed\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason);\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the strategy can be executed\n /// @return _isStrategic Whether the tx is strategic or not\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) external view returns (bool _isStrategic);\n\n /// @notice Builds the secondsAgos array with periodDuration between each datapoint\n /// @param _fromTimestamp Timestamp from which to backfill the oracle with\n /// @return _secondsAgos Array of secondsAgo that backfills the history from fromTimestamp\n function calculateSecondsAgos(uint32 _fromTimestamp) external view returns (uint32[] memory _secondsAgos);\n}\n" - }, - "solidity/interfaces/bridges/IConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeSenderAdapter, IOracleSidechain} from './IBridgeSenderAdapter.sol';\nimport {IDataFeed} from '../IDataFeed.sol';\n\ninterface IConnextSenderAdapter is IBridgeSenderAdapter {\n // STATE VARIABLES\n\n function connext() external view returns (IConnext _connext);\n\n function dataFeed() external view returns (IDataFeed _dataFeed);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport {IUniswapV3PoolImmutables} from './pool/IUniswapV3PoolImmutables.sol';\nimport {IUniswapV3PoolState} from './pool/IUniswapV3PoolState.sol';\nimport {IUniswapV3PoolDerivedState} from './pool/IUniswapV3PoolDerivedState.sol';\nimport {IUniswapV3PoolActions} from './pool/IUniswapV3PoolActions.sol';\nimport {IUniswapV3PoolOwnerActions} from './pool/IUniswapV3PoolOwnerActions.sol';\nimport {IUniswapV3PoolErrors} from './pool/IUniswapV3PoolErrors.sol';\nimport {IUniswapV3PoolEvents} from './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolErrors,\n IUniswapV3PoolEvents\n{\n\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// @return tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// @return observationIndex The index of the last oracle observation that was written,\n /// @return observationCardinality The current maximum number of observations stored in the pool,\n /// @return observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n /// @return The liquidity at the current price of the pool\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper\n /// @return liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// @return feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// @return feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// @return tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// @return secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// @return secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// @return initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return liquidity The amount of liquidity in the position,\n /// @return feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// @return feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// @return tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// @return tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// @return tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolErrors.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Errors emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolErrors {\n error LOK();\n error TLU();\n error TLM();\n error TUM();\n error AI();\n error M0();\n error M1();\n error AS();\n error IIA();\n error L();\n error F0();\n error F1();\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {ExecuteArgs, TransferInfo, TokenId, DestinationTransferStatus} from \"../libraries/LibConnextStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {SwapUtils} from \"../libraries/SwapUtils.sol\";\n\nimport {IStableSwap} from \"./IStableSwap.sol\";\n\nimport {IDiamondCut} from \"./IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\ninterface IConnext is IDiamondLoupe, IDiamondCut {\n // TokenFacet\n function canonicalToAdopted(bytes32 _key) external view returns (address);\n\n function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\n\n function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\n\n function canonicalToRepresentation(bytes32 _key) external view returns (address);\n\n function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\n\n function representationToCanonical(address _adopted) external view returns (TokenId memory);\n\n function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\n\n function approvedAssets(bytes32 _key) external view returns (bool);\n\n function approvedAssets(TokenId calldata _canonical) external view returns (bool);\n\n function adoptedToLocalPools(bytes32 _key) external view returns (IStableSwap);\n\n function adoptedToLocalPools(TokenId calldata _canonical) external view returns (IStableSwap);\n\n function getTokenId(address _candidate) external view returns (TokenId memory);\n\n function setupAsset(\n TokenId calldata _canonical,\n uint8 _canonicalDecimals,\n string memory _representationName,\n string memory _representationSymbol,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function setupAssetWithDeployedRepresentation(\n TokenId calldata _canonical,\n address _representation,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\n\n function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\n\n function removeAssetId(\n bytes32 _key,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function removeAssetId(\n TokenId calldata _canonical,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function updateDetails(\n TokenId calldata _canonical,\n string memory _name,\n string memory _symbol\n ) external;\n\n // BaseConnextFacet\n\n // BridgeFacet\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\n\n function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\n\n function remote(uint32 _domain) external view returns (address);\n\n function domain() external view returns (uint256);\n\n function nonce() external view returns (uint256);\n\n function approvedSequencers(address _sequencer) external view returns (bool);\n\n function xAppConnectionManager() external view returns (address);\n\n function addConnextion(uint32 _domain, address _connext) external;\n\n function addSequencer(address _sequencer) external;\n\n function removeSequencer(address _sequencer) external;\n\n function xcall(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function xcallIntoLocal(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\n\n function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\n\n function bumpTransfer(bytes32 _transferId) external payable;\n\n function setXAppConnectionManager(address _xAppConnectionManager) external;\n\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n function enrollCustom(\n uint32 _domain,\n bytes32 _id,\n address _custom\n ) external;\n\n // InboxFacet\n\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external;\n\n // ProposedOwnableFacet\n\n function owner() external view returns (address);\n\n function routerWhitelistRemoved() external view returns (bool);\n\n function assetWhitelistRemoved() external view returns (bool);\n\n function proposed() external view returns (address);\n\n function proposedTimestamp() external view returns (uint256);\n\n function routerWhitelistTimestamp() external view returns (uint256);\n\n function assetWhitelistTimestamp() external view returns (uint256);\n\n function delay() external view returns (uint256);\n\n function proposeRouterWhitelistRemoval() external;\n\n function removeRouterWhitelist() external;\n\n function proposeAssetWhitelistRemoval() external;\n\n function removeAssetWhitelist() external;\n\n function renounced() external view returns (bool);\n\n function proposeNewOwner(address newlyProposed) external;\n\n function renounceOwnership() external;\n\n function acceptProposedOwner() external;\n\n function pause() external;\n\n function unpause() external;\n\n // RelayerFacet\n function approvedRelayers(address _relayer) external view returns (bool);\n\n function relayerFeeVault() external view returns (address);\n\n function setRelayerFeeVault(address _relayerFeeVault) external;\n\n function addRelayer(address _relayer) external;\n\n function removeRelayer(address _relayer) external;\n\n // RoutersFacet\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\n\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\n\n function getRouterApproval(address _router) external view returns (bool);\n\n function getRouterRecipient(address _router) external view returns (address);\n\n function getRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\n\n function maxRoutersPerTransfer() external view returns (uint256);\n\n function routerBalances(address _router, address _asset) external view returns (uint256);\n\n function getRouterApprovalForPortal(address _router) external view returns (bool);\n\n function setupRouter(\n address router,\n address owner,\n address recipient\n ) external;\n\n function removeRouter(address router) external;\n\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\n\n function setLiquidityFeeNumerator(uint256 _numerator) external;\n\n function approveRouterForPortal(address _router) external;\n\n function unapproveRouterForPortal(address _router) external;\n\n function setRouterRecipient(address router, address recipient) external;\n\n function proposeRouterOwner(address router, address proposed) external;\n\n function acceptProposedRouterOwner(address router) external;\n\n function addRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address _router\n ) external payable;\n\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\n\n function removeRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address payable _to,\n address _router\n ) external;\n\n function removeRouterLiquidity(\n uint256 _amount,\n address _local,\n address payable _to\n ) external;\n\n // PortalFacet\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\n\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\n\n function aavePool() external view returns (address);\n\n function aavePortalFee() external view returns (uint256);\n\n function setAavePool(address _aavePool) external;\n\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\n\n function repayAavePortal(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount,\n uint256 _maxIn\n ) external;\n\n function repayAavePortalFor(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount\n ) external;\n\n // StableSwapFacet\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\n\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\n\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\n\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\n\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\n\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\n\n function calculateSwap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapTokenAmount(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n bool deposit\n ) external view returns (uint256);\n\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) external view returns (uint256);\n\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\n\n function swap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n bytes32 canonicalId,\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n bytes32 canonicalId,\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function addSwapLiquidity(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidity(\n bytes32 canonicalId,\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidityImbalance(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n\n // SwapAdminFacet\n\n function initializeSwap(\n bytes32 _canonicalId,\n IERC20[] memory _pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 _a,\n uint256 _fee,\n uint256 _adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\n\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\n\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\n\n function rampA(\n bytes32 canonicalId,\n uint256 futureA,\n uint256 futureTime\n ) external;\n\n function stopRampA(bytes32 canonicalId) external;\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\nimport {IConnectorManager} from \"../../../messaging/interfaces/IConnectorManager.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n// ============= Enum =============\n\n/// @notice Enum representing address role\n// Returns uint\n// None - 0\n// Router - 1\n// Watcher - 2\n// Admin - 3\nenum Role {\n None,\n Router,\n Watcher,\n Admin\n}\n\n/**\n * @notice Enum representing status of destination transfer\n * @dev Status is only assigned on the destination domain, will always be \"none\" for the\n * origin domains\n * @return uint - Index of value in enum\n */\nenum DestinationTransferStatus {\n None, // 0\n Reconciled, // 1\n Executed, // 2\n Completed // 3 - executed + reconciled\n}\n\n// ============= Structs =============\n\nstruct TokenId {\n uint32 domain;\n bytes32 id;\n}\n\n/**\n * @notice These are the parameters that will remain constant between the\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\n * @property to - The account that receives funds, in the event of a crosschain call,\n * will receive funds if the call fails.\n *\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\n * @param canonicalDomain - The canonical domain of the asset you are bridging\n * @param to - The address you are sending funds (and potentially data) to\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\n * a user takes 1% slippage, this is expressed as 1_000)\n * @param originSender - The msg.sender of the xcall\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\n */\nstruct TransferInfo {\n uint32 originDomain;\n uint32 destinationDomain;\n uint32 canonicalDomain;\n address to;\n address delegate;\n bool receiveLocal;\n bytes callData;\n uint256 slippage;\n address originSender;\n uint256 bridgedAmt;\n uint256 normalizedIn;\n uint256 nonce;\n bytes32 canonicalId;\n}\n\n/**\n * @notice\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\n * @param routers - The routers who you are sending the funds on behalf of.\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\n * for the signed transfer ID.\n * @param sequencer - The sequencer who assigned the router path to this transfer.\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\n * for the path that was signed.\n */\nstruct ExecuteArgs {\n TransferInfo params;\n address[] routers;\n bytes[] routerSignatures;\n address sequencer;\n bytes sequencerSignature;\n}\n\n/**\n * @notice Contains RouterFacet related state\n * @param approvedRouters - Mapping of whitelisted router addresses\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\n * (if configured) or the router itself\n * @param routerOwners - Mapping of router owners\n * If set, can update the routerRecipient\n * @param proposedRouterOwners - Mapping of proposed router owners\n * Must wait timeout to set the\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\n * When accepting a proposed owner, must wait for delay to elapse\n */\nstruct RouterPermissionsManagerInfo {\n mapping(address => bool) approvedRouters;\n mapping(address => bool) approvedForPortalRouters;\n mapping(address => address) routerRecipients;\n mapping(address => address) routerOwners;\n mapping(address => address) proposedRouterOwners;\n mapping(address => uint256) proposedRouterTimestamp;\n}\n\nstruct AppStorage {\n //\n // 0\n bool initialized;\n //\n // Connext\n //\n // 1\n uint256 LIQUIDITY_FEE_NUMERATOR;\n /**\n * @notice The local address that is custodying relayer fees\n */\n // 2\n address relayerFeeVault;\n /**\n * @notice Nonce for the contract, used to keep unique transfer ids.\n * @dev Assigned at first interaction (xcall on origin domain).\n */\n // 3\n uint256 nonce;\n /**\n * @notice The domain this contract exists on.\n * @dev Must match the nomad domain, which is distinct from the \"chainId\".\n */\n // 4\n uint32 domain;\n /**\n * @notice Mapping holding the AMMs for swapping in and out of local assets.\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon).\n * This mapping is keyed on the hash of the canonical id + domain for local asset.\n */\n // 6\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\n /**\n * @notice Mapping of whitelisted assets on same domain as contract.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => bool) approvedAssets;\n /**\n * @notice Mapping of liquidity caps of whitelisted assets. If 0, no cap is enforced.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => uint256) caps;\n /**\n * @notice Mapping of adopted to canonical asset information.\n * @dev If the adopted asset is the native asset, the keyed address will\n * be the wrapped asset address.\n */\n // 8\n mapping(address => TokenId) adoptedToCanonical;\n /**\n * @notice Mapping of representation to canonical asset information.\n */\n // 9\n mapping(address => TokenId) representationToCanonical;\n /**\n * @notice Mapping of hash(canonicalId, canonicalDomain) to adopted asset on this domain.\n * @dev If the adopted asset is the native asset, the stored address will be the\n * wrapped asset address.\n */\n // 10\n mapping(bytes32 => address) canonicalToAdopted;\n /**\n * @notice Mapping of canonical to representation asset information.\n * @dev If the token is of local origin (meaning it was originanlly deployed on this chain),\n * this MUST map to address(0).\n */\n // 11\n mapping(bytes32 => address) canonicalToRepresentation;\n /**\n * @notice Mapping to track transfer status on destination domain\n */\n // 12\n mapping(bytes32 => DestinationTransferStatus) transferStatus;\n /**\n * @notice Mapping holding router address that provided fast liquidity.\n */\n // 13\n mapping(bytes32 => address[]) routedTransfers;\n /**\n * @notice Mapping of router to available balance of an asset.\n * @dev Routers should always store liquidity that they can expect to receive via the bridge on\n * this domain (the nomad local asset).\n */\n // 14\n mapping(address => mapping(address => uint256)) routerBalances;\n /**\n * @notice Mapping of approved relayers\n * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\n */\n // 15\n mapping(address => bool) approvedRelayers;\n /**\n * @notice The max amount of routers a payment can be routed through.\n */\n // 18\n uint256 maxRoutersPerTransfer;\n /**\n * @notice Stores a mapping of transfer id to slippage overrides.\n */\n // 20\n mapping(bytes32 => uint256) slippage;\n /**\n * @notice Stores a mapping of remote routers keyed on domains.\n * @dev Addresses are cast to bytes32.\n * This mapping is required because the Connext now contains the BridgeRouter and must implement\n * the remotes interface.\n */\n // 21\n mapping(uint32 => bytes32) remotes;\n //\n // ProposedOwnable\n //\n // 22\n address _proposed;\n // 23\n uint256 _proposedOwnershipTimestamp;\n // 24\n bool _routerWhitelistRemoved;\n // 25\n uint256 _routerWhitelistTimestamp;\n // 26\n bool _assetWhitelistRemoved;\n // 27\n uint256 _assetWhitelistTimestamp;\n /**\n * @notice Stores a mapping of address to Roles\n * @dev returns uint representing the enum Role value\n */\n // 28\n mapping(address => Role) roles;\n //\n // RouterFacet\n //\n // 29\n RouterPermissionsManagerInfo routerPermissionInfo;\n //\n // ReentrancyGuard\n //\n // 30\n uint256 _status;\n //\n // StableSwap\n //\n /**\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\n * Struct storing data responsible for automatic market maker functionalities. In order to\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\n */\n // 31\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\n /**\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\n */\n // 32\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\n /**\n * @notice Stores whether or not bribing, AMMs, have been paused.\n */\n // 33\n bool _paused;\n //\n // AavePortals\n //\n /**\n * @notice Address of Aave Pool contract.\n */\n // 34\n address aavePool;\n /**\n * @notice Fee percentage numerator for using Portal liquidity.\n * @dev Assumes the same basis points as the liquidity fee.\n */\n // 35\n uint256 aavePortalFeeNumerator;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 36\n mapping(bytes32 => uint256) portalDebt;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 37\n mapping(bytes32 => uint256) portalFeeDebt;\n /**\n * @notice Mapping of approved sequencers\n * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\n * for the fast liquidity route.\n */\n // 38\n mapping(address => bool) approvedSequencers;\n /**\n * @notice Remote connection manager for xapp.\n */\n // 39\n IConnectorManager xAppConnectionManager;\n}\n\nlibrary LibConnextStorage {\n function connextStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= 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 > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n // hash of proposed facets => acceptance time\n mapping(bytes32 => uint256) acceptanceTimes;\n // acceptance delay for upgrading facets\n uint256 acceptanceDelay;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function acceptanceDelay() internal view returns (uint256) {\n return diamondStorage().acceptanceDelay;\n }\n\n function acceptanceTime(bytes32 _key) internal view returns (uint256) {\n return diamondStorage().acceptanceTimes[_key];\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, \"LibDiamond: !contract owner\");\n }\n\n event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n function proposeDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 acceptance = block.timestamp + ds.acceptanceDelay;\n ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\n emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\n }\n\n event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n function rescindDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\n // period or befor the delay elpases\n diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = 0;\n emit DiamondCutRescinded(_diamondCut, _init, _calldata);\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n if (ds.facetAddresses.length != 0) {\n uint256 time = ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\n require(time != 0 && time <= block.timestamp, \"LibDiamond: delay not elapsed\");\n } // Otherwise, this is the first instance of deployment and it can be set automatically\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress != _facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, \"LibDiamondCut: New facet has no code\");\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n require(_calldata.length == 0, \"LibDiamondCut: _init is address(0) but_calldata is not empty\");\n } else {\n require(_calldata.length != 0, \"LibDiamondCut: _calldata is empty but _init is not address(0)\");\n if (_init != address(this)) {\n enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");\n }\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length != 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize != 0, _errorMessage);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20, IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {LPToken} from \"../helpers/LPToken.sol\";\n\nimport {AmplificationUtils} from \"./AmplificationUtils.sol\";\nimport {MathUtils} from \"./MathUtils.sol\";\n\n/**\n * @title SwapUtils library\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\n * Admin functions should be protected within contracts using this library.\n */\nlibrary SwapUtils {\n using SafeERC20 for IERC20;\n using MathUtils for uint256;\n\n /*** EVENTS ***/\n\n event TokenSwap(\n bytes32 indexed key,\n address indexed buyer,\n uint256 tokensSold,\n uint256 tokensBought,\n uint128 soldId,\n uint128 boughtId\n );\n event AddLiquidity(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n bytes32 indexed key,\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\n event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\n\n struct Swap {\n // variables around the ramp management of A,\n // the amplification coefficient * n * (n - 1)\n // see https://www.curve.fi/stableswap-paper.pdf for details\n bytes32 key;\n uint256 initialA;\n uint256 futureA;\n uint256 initialATime;\n uint256 futureATime;\n // fee calculation\n uint256 swapFee;\n uint256 adminFee;\n LPToken lpToken;\n // contract references for all tokens being pooled\n IERC20[] pooledTokens;\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\n uint256[] tokenPrecisionMultipliers;\n // the pool balance of each token, in the token's precision\n // the contract's actual token balance might differ\n uint256[] balances;\n // the admin fee balance of each token, in the token's precision\n uint256[] adminFees;\n }\n\n // Struct storing variables used in calculations in the\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\n struct CalculateWithdrawOneTokenDYInfo {\n uint256 d0;\n uint256 d1;\n uint256 newY;\n uint256 feePerToken;\n uint256 preciseA;\n }\n\n // Struct storing variables used in calculations in the\n // {add,remove}Liquidity functions to avoid stack too deep errors\n struct ManageLiquidityInfo {\n uint256 d0;\n uint256 d1;\n uint256 d2;\n uint256 preciseA;\n LPToken lpToken;\n uint256 totalSupply;\n uint256[] balances;\n uint256[] multipliers;\n }\n\n // the precision all pools tokens will be converted to\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\n\n // the denominator used to calculate admin and LP fees. For example, an\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\n uint256 internal constant FEE_DENOMINATOR = 1e10;\n\n // Max swap fee is 1% or 100bps of each swap\n uint256 internal constant MAX_SWAP_FEE = 1e8;\n\n // Max adminFee is 100% of the swapFee\n // adminFee does not add additional fee on top of swapFee\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\n // users but only on the earnings of LPs\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\n\n // Constant value used as max loop limit\n uint256 internal constant MAX_LOOP_LIMIT = 256;\n\n /*** VIEW & PURE FUNCTIONS ***/\n\n function _getAPrecise(Swap storage self) private view returns (uint256) {\n return AmplificationUtils._getAPrecise(self);\n }\n\n /**\n * @notice Calculate the dy, the amount of selected token that user receives and\n * the fee of withdrawing in one token\n * @param tokenAmount the amount to withdraw in the pool's precision\n * @param tokenIndex which token will be withdrawn\n * @param self Swap struct to read from\n * @return the amount of token user will receive\n */\n function calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) internal view returns (uint256) {\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\n self,\n tokenAmount,\n tokenIndex,\n self.lpToken.totalSupply()\n );\n return availableTokenAmount;\n }\n\n function _calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 totalSupply\n ) private view returns (uint256, uint256) {\n uint256 dy;\n uint256 newY;\n uint256 currentY;\n\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\n\n // dy_0 (without fees)\n // dy, dy_0 - dy\n\n uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\n\n return (dy, dySwapFee);\n }\n\n /**\n * @notice Calculate the dy of withdrawing in one token\n * @param self Swap struct to read from\n * @param tokenIndex which token will be withdrawn\n * @param tokenAmount the amount to withdraw in the pools precision\n * @return the d and the new y after withdrawing one token\n */\n function calculateWithdrawOneTokenDY(\n Swap storage self,\n uint8 tokenIndex,\n uint256 tokenAmount,\n uint256 totalSupply\n )\n internal\n view\n returns (\n uint256,\n uint256,\n uint256\n )\n {\n // Get the current D, then solve the stableswap invariant\n // y_i for D - tokenAmount\n uint256[] memory xp = _xp(self);\n\n require(tokenIndex < xp.length, \"index out of range\");\n\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\n v.preciseA = _getAPrecise(self);\n v.d0 = getD(xp, v.preciseA);\n v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\n\n require(tokenAmount <= xp[tokenIndex], \"exceeds available\");\n\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\n\n uint256[] memory xpReduced = new uint256[](xp.length);\n\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\n for (uint256 i; i < xp.length; ) {\n uint256 xpi = xp[i];\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\n xpReduced[i] =\n xpi -\n ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\n FEE_DENOMINATOR);\n\n unchecked {\n ++i;\n }\n }\n\n uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\n dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\n\n return (dy, v.newY, xp[tokenIndex]);\n }\n\n /**\n * @notice Calculate the price of a token in the pool with given\n * precision-adjusted balances and a particular D.\n *\n * @dev This is accomplished via solving the invariant iteratively.\n * See the StableSwap paper and Curve.fi implementation for further details.\n *\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\n * x_1**2 + b*x_1 = c\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\n *\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\n * @param tokenIndex Index of token we are calculating for.\n * @param xp a precision-adjusted set of pool balances. Array should be\n * the same cardinality as the pool.\n * @param d the stableswap invariant\n * @return the price of the token, in the same precision as in xp\n */\n function getYD(\n uint256 a,\n uint8 tokenIndex,\n uint256[] memory xp,\n uint256 d\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndex < numTokens, \"Token not found\");\n\n uint256 c = d;\n uint256 s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < numTokens; ) {\n if (i != tokenIndex) {\n s += xp[i];\n c = (c * d) / (xp[i] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n }\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\n * as the pool.\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\n * See the StableSwap paper for details\n * @return the invariant, at the precision of the pool\n */\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n uint256 s;\n for (uint256 i; i < numTokens; ) {\n s += xp[i];\n\n unchecked {\n ++i;\n }\n }\n if (s == 0) {\n return 0;\n }\n\n uint256 prevD;\n uint256 d = s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n uint256 dP = d;\n for (uint256 j; j < numTokens; ) {\n dP = (dP * d) / (xp[j] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // dP = dP * D * D * D * ... overflow!\n\n unchecked {\n ++j;\n }\n }\n prevD = d;\n d =\n (((nA * s) / AmplificationUtils.A_PRECISION + dP * numTokens) * d) /\n ((((nA - AmplificationUtils.A_PRECISION) * d) / AmplificationUtils.A_PRECISION + (numTokens + 1) * dP));\n if (d.within1(prevD)) {\n return d;\n }\n\n unchecked {\n ++i;\n }\n }\n\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\n // function which does not rely on D.\n revert(\"D does not converge\");\n }\n\n /**\n * @notice Given a set of balances and precision multipliers, return the\n * precision-adjusted balances.\n *\n * @param balances an array of token balances, in their native precisions.\n * These should generally correspond with pooled tokens.\n *\n * @param precisionMultipliers an array of multipliers, corresponding to\n * the amounts in the balances array. When multiplied together they\n * should yield amounts at the pool's precision.\n *\n * @return an array of amounts \"scaled\" to the pool's precision\n */\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\n internal\n pure\n returns (uint256[] memory)\n {\n uint256 numTokens = balances.length;\n require(numTokens == precisionMultipliers.length, \"mismatch multipliers\");\n uint256[] memory xp = new uint256[](numTokens);\n for (uint256 i; i < numTokens; ) {\n xp[i] = balances[i] * precisionMultipliers[i];\n\n unchecked {\n ++i;\n }\n }\n return xp;\n }\n\n /**\n * @notice Return the precision-adjusted balances of all tokens in the pool\n * @param self Swap struct to read from\n * @return the pool balances \"scaled\" to the pool's precision, allowing\n * them to be more easily compared.\n */\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\n return _xp(self.balances, self.tokenPrecisionMultipliers);\n }\n\n /**\n * @notice Get the virtual price, to help calculate profit\n * @param self Swap struct to read from\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\n */\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\n uint256 d = getD(_xp(self), _getAPrecise(self));\n LPToken lpToken = self.lpToken;\n uint256 supply = lpToken.totalSupply();\n if (supply != 0) {\n return (d * (10**uint256(POOL_PRECISION_DECIMALS))) / supply;\n }\n return 0;\n }\n\n /**\n * @notice Calculate the new balances of the tokens given the indexes of the token\n * that is swapped from (FROM) and the token that is swapped to (TO).\n * This function is used as a helper function to calculate how much TO token\n * the user should receive on swap.\n *\n * @param preciseA precise form of amplification coefficient\n * @param tokenIndexFrom index of FROM token\n * @param tokenIndexTo index of TO token\n * @param x the new total amount of FROM token\n * @param xp balances of the tokens in the pool\n * @return the amount of TO token that should remain in the pool\n */\n function getY(\n uint256 preciseA,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 x,\n uint256[] memory xp\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \"token not found\");\n\n uint256 d = getD(xp, preciseA);\n uint256 c = d;\n uint256 s;\n uint256 nA = numTokens * preciseA;\n\n uint256 _x;\n for (uint256 i; i < numTokens; ) {\n if (i == tokenIndexFrom) {\n _x = x;\n } else if (i != tokenIndexTo) {\n _x = xp[i];\n } else {\n unchecked {\n ++i;\n }\n continue;\n }\n s += _x;\n c = (c * d) / (_x * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n\n // iterative approximation\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get\n */\n function calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) internal view returns (uint256 dy) {\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy.\n * @return dx the number of tokens the user have to transfer + fee\n */\n function calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) internal view returns (uint256 dx) {\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\n * @return dyFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256[] memory balances\n ) internal view returns (uint256 dy, uint256 dyFee) {\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\n dy = xp[tokenIndexTo] - y - 1;\n dyFee = (dy * self.swapFee) / FEE_DENOMINATOR;\n dy = (dy - dyFee) / multipliers[tokenIndexTo];\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\n * @return dxFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256[] memory balances\n ) internal view returns (uint256 dx, uint256 dxFee) {\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n\n uint256 a = _getAPrecise(self);\n uint256 d0 = getD(xp, a);\n\n xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\n dx = x - xp[tokenIndexFrom] + 1;\n dxFee = (dx * self.swapFee) / FEE_DENOMINATOR;\n dx = (dx + dxFee) / multipliers[tokenIndexFrom];\n }\n\n /**\n * @notice A simple method to calculate amount of each underlying\n * tokens that is returned upon burning given amount of\n * LP tokens\n *\n * @param amount the amount of LP tokens that would to be burned on\n * withdrawal\n * @return array of amounts of tokens user will receive\n */\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\n }\n\n function _calculateRemoveLiquidity(\n uint256[] memory balances,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (uint256[] memory) {\n require(amount <= totalSupply, \"exceed total supply\");\n\n uint256 numBalances = balances.length;\n uint256[] memory amounts = new uint256[](numBalances);\n\n for (uint256 i; i < numBalances; ) {\n amounts[i] = (balances[i] * amount) / totalSupply;\n\n unchecked {\n ++i;\n }\n }\n return amounts;\n }\n\n /**\n * @notice A simple method to calculate prices from deposits or\n * withdrawals, excluding fees but including slippage. This is\n * helpful as an input into the various \"min\" parameters on calls\n * to fight front-running\n *\n * @dev This shouldn't be used outside frontends for user estimates.\n *\n * @param self Swap struct to read from\n * @param amounts an array of token amounts to deposit or withdrawal,\n * corresponding to pooledTokens. The amount should be in each\n * pooled token's native precision. If a token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @param deposit whether this is a deposit or a withdrawal\n * @return if deposit was true, total amount of lp token that will be minted and if\n * deposit was false, total amount of lp token that will be burned\n */\n function calculateTokenAmount(\n Swap storage self,\n uint256[] calldata amounts,\n bool deposit\n ) internal view returns (uint256) {\n uint256 a = _getAPrecise(self);\n uint256[] memory balances = self.balances;\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n\n uint256 numBalances = balances.length;\n uint256 d0 = getD(_xp(balances, multipliers), a);\n for (uint256 i; i < numBalances; ) {\n if (deposit) {\n balances[i] = balances[i] + amounts[i];\n } else {\n balances[i] = balances[i] - amounts[i];\n }\n\n unchecked {\n ++i;\n }\n }\n uint256 d1 = getD(_xp(balances, multipliers), a);\n uint256 totalSupply = self.lpToken.totalSupply();\n\n if (deposit) {\n return ((d1 - d0) * totalSupply) / d0;\n } else {\n return ((d0 - d1) * totalSupply) / d0;\n }\n }\n\n /**\n * @notice return accumulated amount of admin fees of the token with given index\n * @param self Swap struct to read from\n * @param index Index of the pooled token\n * @return admin balance in the token's precision\n */\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\n require(index < self.pooledTokens.length, \"index out of range\");\n return self.adminFees[index];\n }\n\n /**\n * @notice internal helper function to calculate fee per token multiplier used in\n * swap fee calculations\n * @param swapFee swap fee for the tokens\n * @param numTokens number of tokens pooled\n */\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\n return (swapFee * numTokens) / ((numTokens - 1) * 4);\n }\n\n /*** STATE MODIFYING FUNCTIONS ***/\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"swap more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"no fee token support\");\n }\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dy the amount of tokens the user wants to buy\n * @param maxDx the max amount the user would like to send.\n * @return amount of token user have to transfer on swap\n */\n function swapOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \">pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"not support fee token\");\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice swap two tokens in the pool internally\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swapInternal(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n require(dx <= self.balances[tokenIndexFrom], \"more than pool balance\");\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice Should get exact amount out of AMM for asset put in\n */\n function swapInternalOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \"more than pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice Add liquidity to the pool\n * @param self Swap struct to read from and write to\n * @param amounts the amounts of each token to add, in their native precision\n * @param minToMint the minimum LP tokens adding this amount of liquidity\n * should mint, otherwise revert. Handy for front-running mitigation\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\n * @return amount of LP token user received\n */\n function addLiquidity(\n Swap storage self,\n uint256[] memory amounts,\n uint256 minToMint\n ) internal returns (uint256) {\n uint256 numTokens = self.pooledTokens.length;\n require(amounts.length == numTokens, \"mismatch pooled tokens\");\n\n // current state\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n if (v.totalSupply != 0) {\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n }\n\n uint256[] memory newBalances = new uint256[](numTokens);\n\n for (uint256 i; i < numTokens; ) {\n require(v.totalSupply != 0 || amounts[i] != 0, \"!supply all tokens\");\n\n // Transfer tokens first to see if a fee was charged on transfer\n if (amounts[i] != 0) {\n IERC20 token = self.pooledTokens[i];\n uint256 beforeBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), amounts[i]);\n\n // Update the amounts[] with actual transfer amount\n amounts[i] = token.balanceOf(address(this)) - beforeBalance;\n }\n\n newBalances[i] = v.balances[i] + amounts[i];\n\n unchecked {\n ++i;\n }\n }\n\n // invariant after change\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n require(v.d1 > v.d0, \"D should increase\");\n\n // updated to reflect fees and calculate the user's LP tokens\n v.d2 = v.d1;\n uint256[] memory fees = new uint256[](numTokens);\n\n if (v.totalSupply != 0) {\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n for (uint256 i; i < numTokens; ) {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / FEE_DENOMINATOR;\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = newBalances[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n newBalances[i] = newBalances[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n } else {\n // the initial depositor doesn't pay fees\n self.balances = newBalances;\n }\n\n uint256 toMint;\n if (v.totalSupply == 0) {\n toMint = v.d1;\n } else {\n toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\n }\n\n require(toMint >= minToMint, \"mint < min\");\n\n // mint the user's LP tokens\n v.lpToken.mint(msg.sender, toMint);\n\n emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\n\n return toMint;\n }\n\n /**\n * @notice Burn LP tokens to remove liquidity from the pool.\n * @dev Liquidity can always be removed, even when the pool is paused.\n * @param self Swap struct to read from and write to\n * @param amount the amount of LP tokens to burn\n * @param minAmounts the minimum amounts of each token in the pool\n * acceptable for this burn. Useful as a front-running mitigation\n * @return amounts of tokens the user received\n */\n function removeLiquidity(\n Swap storage self,\n uint256 amount,\n uint256[] calldata minAmounts\n ) internal returns (uint256[] memory) {\n LPToken lpToken = self.lpToken;\n require(amount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(minAmounts.length == numTokens, \"mismatch poolTokens\");\n\n uint256[] memory balances = self.balances;\n uint256 totalSupply = lpToken.totalSupply();\n\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\n\n uint256 numAmounts = amounts.length;\n for (uint256 i; i < numAmounts; ) {\n require(amounts[i] >= minAmounts[i], \"amounts[i] < minAmounts[i]\");\n self.balances[i] = balances[i] - amounts[i];\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n lpToken.burnFrom(msg.sender, amount);\n\n emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\n\n return amounts;\n }\n\n /**\n * @notice Remove liquidity from the pool all in one token.\n * @param self Swap struct to read from and write to\n * @param tokenAmount the amount of the lp tokens to burn\n * @param tokenIndex the index of the token you want to receive\n * @param minAmount the minimum amount to withdraw, otherwise revert\n * @return amount chosen token that user received\n */\n function removeLiquidityOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount\n ) internal returns (uint256) {\n LPToken lpToken = self.lpToken;\n\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(tokenIndex < numTokens, \"not found\");\n\n uint256 totalSupply = lpToken.totalSupply();\n\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\n\n require(dy >= minAmount, \"dy < minAmount\");\n\n uint256 adminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR;\n self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\n if (adminFee != 0) {\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\n }\n lpToken.burnFrom(msg.sender, tokenAmount);\n self.pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\n\n emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\n\n return dy;\n }\n\n /**\n * @notice Remove liquidity from the pool, weighted differently than the\n * pool's current balances.\n *\n * @param self Swap struct to read from and write to\n * @param amounts how much of each token to withdraw\n * @param maxBurnAmount the max LP token provider is willing to pay to\n * remove liquidity. Useful as a front-running mitigation.\n * @return actual amount of LP tokens burned in the withdrawal\n */\n function removeLiquidityImbalance(\n Swap storage self,\n uint256[] memory amounts,\n uint256 maxBurnAmount\n ) internal returns (uint256) {\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n\n uint256 numTokens = self.pooledTokens.length;\n uint256 numAmounts = amounts.length;\n require(numAmounts == numTokens, \"mismatch pool tokens\");\n\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \">LP.balanceOf\");\n\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n uint256[] memory fees = new uint256[](numTokens);\n {\n uint256[] memory balances1 = new uint256[](numTokens);\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n for (uint256 i; i < numTokens; ) {\n require(v.balances[i] >= amounts[i], \"withdraw more than available\");\n\n unchecked {\n balances1[i] = v.balances[i] - amounts[i];\n ++i;\n }\n }\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\n\n for (uint256 i; i < numTokens; ) {\n {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n uint256 difference = idealBalance.difference(balances1[i]);\n fees[i] = (feePerToken * difference) / FEE_DENOMINATOR;\n }\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = balances1[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n balances1[i] = balances1[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\n }\n uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\n require(tokenAmount != 0, \"!zero amount\");\n tokenAmount = tokenAmount + 1;\n\n require(tokenAmount <= maxBurnAmount, \"tokenAmount > maxBurnAmount\");\n\n v.lpToken.burnFrom(msg.sender, tokenAmount);\n\n for (uint256 i; i < numTokens; ) {\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\n\n return tokenAmount;\n }\n\n /**\n * @notice withdraw all admin fees to a given address\n * @param self Swap struct to withdraw fees from\n * @param to Address to send the fees to\n */\n function withdrawAdminFees(Swap storage self, address to) internal {\n uint256 numTokens = self.pooledTokens.length;\n for (uint256 i; i < numTokens; ) {\n IERC20 token = self.pooledTokens[i];\n uint256 balance = self.adminFees[i];\n if (balance != 0) {\n self.adminFees[i] = 0;\n token.safeTransfer(to, balance);\n }\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Sets the admin fee\n * @dev adminFee cannot be higher than 100% of the swap fee\n * @param self Swap struct to update\n * @param newAdminFee new admin fee to be applied on future transactions\n */\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\n require(newAdminFee <= MAX_ADMIN_FEE, \"too high\");\n self.adminFee = newAdminFee;\n\n emit NewAdminFee(self.key, newAdminFee);\n }\n\n /**\n * @notice update the swap fee\n * @dev fee cannot be higher than 1% of each swap\n * @param self Swap struct to update\n * @param newSwapFee new swap fee to be applied on future transactions\n */\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\n require(newSwapFee <= MAX_SWAP_FEE, \"too high\");\n self.swapFee = newSwapFee;\n\n emit NewSwapFee(self.key, newSwapFee);\n }\n\n /**\n * @notice Check if this stableswap pool exists and is valid (i.e. has been\n * initialized and tokens have been added).\n * @return bool true if this stableswap pool is valid, false if not.\n */\n function exists(Swap storage self) internal view returns (bool) {\n return self.pooledTokens.length != 0;\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IStableSwap {\n /*** EVENTS ***/\n\n // events replicated from SwapUtils to make the ABI easier for dumb\n // clients\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\n event AddLiquidity(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(uint256 newAdminFee);\n event NewSwapFee(uint256 newSwapFee);\n event NewWithdrawFee(uint256 newWithdrawFee);\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n function swap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function getA() external view returns (uint256);\n\n function getToken(uint8 index) external view returns (IERC20);\n\n function getTokenIndex(address tokenAddress) external view returns (uint8);\n\n function getTokenBalance(uint8 index) external view returns (uint256);\n\n function getVirtualPrice() external view returns (uint256);\n\n // min return calculation functions\n function calculateSwap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapOut(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) external view returns (uint256);\n\n function calculateSwapFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountIn\n ) external view returns (uint256);\n\n function calculateSwapOutFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountOut\n ) external view returns (uint256);\n\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\n\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\n external\n view\n returns (uint256 availableTokenAmount);\n\n // state modifying functions\n function initialize(\n IERC20[] memory pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 a,\n uint256 fee,\n uint256 adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function addLiquidity(\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidity(\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeLiquidityOneToken(\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidityImbalance(\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function proposeDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function rescindDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\nimport {IOutbox} from \"./IOutbox.sol\";\n\n/**\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\n * allows an admin to call `setXAppConnectionManager` to update the underlying\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\n *\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\n * will interface with.\n */\ninterface IConnectorManager {\n /**\n * @notice Get the local inbox contract from the xAppConnectionManager\n * @return The local inbox contract\n * @dev The local inbox contract is a SpokeConnector with AMBs, and a\n * Home contract with nomad\n */\n function home() external view returns (IOutbox);\n\n /**\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\n * @return True if _potentialReplica is an enrolled Replica\n */\n function isReplica(address _potentialReplica) external view returns (bool);\n\n /**\n * @notice Get the local domain from the xAppConnectionManager\n * @return The local domain\n */\n function localDomain() external view returns (uint32);\n}\n" - }, - "@openzeppelin/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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\n/**\n * @notice Interface for all contracts sending messages originating on their\n * current domain.\n *\n * @dev These are the Home.sol interface methods used by the `Router`\n * and exposed via `home()` on the `XAppConnectionClient`\n */\ninterface IOutbox {\n /**\n * @notice Emitted when a new message is added to an outbound message merkle root\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination << 32) & nonce)\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\n * @param committedRoot the latest notarized root submitted in the last signed Update\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes32 committedRoot,\n bytes message\n );\n\n /**\n * @notice Dispatch the message it to the destination domain & recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n * @return bytes32 The leaf added to the tree\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n bytes memory _messageBody\n ) external returns (bytes32);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\n/**\n * @title MathUtils library\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\n * differences between two uint256.\n */\nlibrary MathUtils {\n /**\n * @notice Compares a and b and returns true if the difference between a and b\n * is less than 1 or equal to each other.\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return True if the difference between a and b is less than 1 or equal,\n * otherwise return false\n */\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\n return (difference(a, b) <= 1);\n }\n\n /**\n * @notice Calculates absolute difference between a and b\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return Difference between a and b\n */\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a > b) {\n return a - b;\n }\n return b - a;\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title Liquidity Provider Token\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\n * It is used to represent user's shares when providing liquidity to swap contracts.\n * @dev Only Swap contracts should initialize and own LPToken contracts.\n */\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\n // ============ Upgrade Gap ============\n\n uint256[49] private __GAP; // gap for upgrade safety\n\n // ============ Storage ============\n\n /**\n * @notice Used to enforce proper token dilution\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\n * See audit recommendations here:\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\n * and uniswap v2 implementation here:\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\n */\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\n\n // ============ Initializer ============\n\n /**\n * @notice Initializes this LPToken contract with the given name and symbol\n * @dev The caller of this function will become the owner. A Swap contract should call this\n * in its initializer function.\n * @param name name of this token\n * @param symbol symbol of this token\n */\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\n __Context_init_unchained();\n __ERC20_init_unchained(name, symbol);\n __Ownable_init_unchained();\n return true;\n }\n\n // ============ External functions ============\n\n /**\n * @notice Mints the given amount of LPToken to the recipient.\n * @dev only owner can call this mint function\n * @param recipient address of account to receive the tokens\n * @param amount amount of tokens to mint\n */\n function mint(address recipient, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot mint 0\");\n if (totalSupply() == 0) {\n // NOTE: using the _mint function directly will error because it is going\n // to the 0 address. fix by using the address(1) here instead\n _mint(address(1), MINIMUM_LIQUIDITY);\n }\n _mint(recipient, amount);\n }\n\n /**\n * @notice Burns the given amount of LPToken from provided account\n * @dev only owner can call this burn function\n * @param account address of account from which to burn token\n * @param amount amount of tokens to mint\n */\n function burnFrom(address account, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot burn 0\");\n _burn(account, amount);\n }\n\n // ============ Internal functions ============\n\n /**\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\n * This assumes the owner is set to a Swap contract's address.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20Upgradeable) {\n super._beforeTokenTransfer(from, to, amount);\n require(to != address(this), \"LPToken: cannot send to itself\");\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n/**\n * @title AmplificationUtils library\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\n * This library assumes the struct is fully validated.\n */\nlibrary AmplificationUtils {\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n // Constant values used in ramping A calculations\n uint256 public constant A_PRECISION = 100;\n uint256 public constant MAX_A = 10**6;\n uint256 private constant MAX_A_CHANGE = 2;\n uint256 private constant MIN_RAMP_TIME = 14 days;\n\n /**\n * @notice Return A, the amplification coefficient * n * (n - 1)\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter\n */\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self) / A_PRECISION;\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self);\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n uint256 t1 = self.futureATime; // time when ramp is finished\n uint256 a1 = self.futureA; // final A value when ramp is finished\n\n if (block.timestamp < t1) {\n uint256 t0 = self.initialATime; // time when ramp is started\n uint256 a0 = self.initialA; // initial A value when ramp is started\n if (a1 > a0) {\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\n return a0 + ((a1 - a0) * (block.timestamp - t0)) / (t1 - t0);\n } else {\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\n return a0 - ((a0 - a1) * (block.timestamp - t0)) / (t1 - t0);\n }\n } else {\n return a1;\n }\n }\n\n /**\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\n * Checks if the change is too rapid, and commits the new A value only when it falls under\n * the limit range.\n * @param self Swap struct to update\n * @param futureA_ the new A to ramp towards\n * @param futureTime_ timestamp when the new A should be reached\n */\n function rampA(\n SwapUtils.Swap storage self,\n uint256 futureA_,\n uint256 futureTime_\n ) internal {\n require(block.timestamp >= self.initialATime + 1 days, \"Wait 1 day before starting ramp\");\n require(futureTime_ >= block.timestamp + MIN_RAMP_TIME, \"Insufficient ramp time\");\n require(futureA_ != 0 && futureA_ < MAX_A, \"futureA_ must be > 0 and < MAX_A\");\n\n uint256 initialAPrecise = _getAPrecise(self);\n uint256 futureAPrecise = futureA_ * A_PRECISION;\n\n if (futureAPrecise < initialAPrecise) {\n require(futureAPrecise * MAX_A_CHANGE >= initialAPrecise, \"futureA_ is too small\");\n } else {\n require(futureAPrecise <= initialAPrecise * MAX_A_CHANGE, \"futureA_ is too large\");\n }\n\n self.initialA = initialAPrecise;\n self.futureA = futureAPrecise;\n self.initialATime = block.timestamp;\n self.futureATime = futureTime_;\n\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\n }\n\n /**\n * @notice Stops ramping A immediately. Once this function is called, rampA()\n * cannot be called for another 24 hours\n * @param self Swap struct to update\n */\n function stopRampA(SwapUtils.Swap storage self) internal {\n require(self.futureATime > block.timestamp, \"Ramp is already stopped\");\n\n uint256 currentA = _getAPrecise(self);\n self.initialA = currentA;\n self.futureA = currentA;\n self.initialATime = block.timestamp;\n self.futureATime = block.timestamp;\n\n emit StopRampA(currentA, block.timestamp);\n }\n}\n" - }, - "@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/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" - }, - "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.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 IERC20Upgradeable {\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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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" - }, - "solidity/for-test/DataReceiverForTest.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {DataReceiver} from '../contracts/DataReceiver.sol';\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\ncontract DataReceiverForTest is DataReceiver {\n constructor(address _governor, IOracleFactory _oracleFactory) DataReceiver(_governor, _oracleFactory) {}\n\n function internalAddObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "solidity/contracts/DataReceiver.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\n\n/// @title The DataReceiver contract\n/// @notice Handles reception of broadcast data and delivers it to correspondant oracle\ncontract DataReceiver is IDataReceiver, Governable {\n /// @inheritdoc IDataReceiver\n IOracleFactory public immutable oracleFactory;\n\n /// @inheritdoc IDataReceiver\n mapping(bytes32 => IOracleSidechain) public deployedOracles;\n\n /// @inheritdoc IDataReceiver\n mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters;\n\n /// @inheritdoc IDataReceiver\n bytes32 public constant ORACLE_INIT_CODE_HASH = 0x81a14d5bbd761f94f91b3251dcb81827627068b092edb305c98f3799dcf10da2;\n\n constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) {\n oracleFactory = _oracleFactory;\n }\n\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external onlyWhitelistedAdapters {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n // Read, store or deploy oracle given poolSalt\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.getPool(_poolSalt);\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.deployOracle(_poolSalt, _poolNonce);\n }\n deployedOracles[_poolSalt] = _oracle;\n }\n // Try to write observations data into oracle\n if (_oracle.write(_observationsData, _poolNonce)) {\n emit ObservationsAdded(_poolSalt, _poolNonce, _observationsData, msg.sender);\n } else {\n revert ObservationsNotWritable();\n }\n }\n\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_receiverAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IDataReceiver\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _receiverAdapterLength = _receiverAdapters.length;\n if (_receiverAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _receiverAdapterLength; ++_i) {\n _whitelistAdapter(_receiverAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n function _whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_receiverAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_receiverAdapter, _isWhitelisted);\n }\n\n modifier onlyWhitelistedAdapters() {\n if (!whitelistedAdapters[IBridgeReceiverAdapter(msg.sender)]) revert UnallowedAdapter();\n _;\n }\n}\n" - }, - "solidity/contracts/OracleSidechain.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\n\n/// @title The SidechainOracle contract\n/// @notice Computes and stores on-chain price data from Mainnet\ncontract OracleSidechain is IOracleSidechain {\n using Oracle for Oracle.Observation[65535];\n\n /// @inheritdoc IOracleSidechain\n IOracleFactory public immutable factory;\n\n struct Slot0 {\n // the current price\n uint160 sqrtPriceX96;\n // the current tick\n int24 tick;\n // the most-recently updated index of the observations array\n uint16 observationIndex;\n // the current maximum number of observations that are being stored\n uint16 observationCardinality;\n // the next maximum number of observations to store, triggered in observations.write\n uint16 observationCardinalityNext;\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\n // represented as an integer denominator (1/x)%\n uint8 feeProtocol;\n // whether the pool is locked\n bool unlocked;\n }\n /// @inheritdoc IOracleSidechain\n Slot0 public slot0;\n\n /// @inheritdoc IOracleSidechain\n Oracle.Observation[65535] public observations;\n\n /// @inheritdoc IOracleSidechain\n bytes32 public immutable poolSalt;\n\n uint24 public poolNonce;\n /// @inheritdoc IOracleSidechain\n address public token0;\n /// @inheritdoc IOracleSidechain\n address public token1;\n /// @inheritdoc IOracleSidechain\n uint24 public fee;\n\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\n function _getBlockTimestamp() internal view virtual returns (uint32) {\n return uint32(block.timestamp); // truncation is desired\n }\n\n constructor() {\n factory = IOracleFactory(msg.sender);\n uint16 _cardinality;\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\n\n slot0 = Slot0({\n sqrtPriceX96: 0,\n tick: 0,\n observationIndex: _cardinality - 1,\n observationCardinality: _cardinality,\n observationCardinalityNext: _cardinality,\n feeProtocol: 0,\n unlocked: true\n });\n }\n\n /// @inheritdoc IOracleSidechain\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external {\n if (!slot0.unlocked) revert AI();\n\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\n\n token0 = _token0;\n token1 = _token1;\n fee = _fee;\n slot0.unlocked = false;\n\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\n }\n\n /// @inheritdoc IOracleSidechain\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\n {\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\n }\n\n /// @inheritdoc IOracleSidechain\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\n if (_poolNonce != poolNonce++) return false;\n\n uint256 _observationsDataLength = _observationsData.length;\n for (uint256 _i; _i < _observationsDataLength; ) {\n _write(_observationsData[_i]);\n unchecked {\n ++_i;\n }\n }\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\n\n // emits UniV3 Swap event topic with minimal data\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\n return true;\n }\n\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\n if (_observationCardinalityNext <= _observationCardinalityNextOld) return;\n slot0.observationCardinalityNext = _observationCardinalityNext;\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\n }\n\n function _write(ObservationData memory _observationData) private {\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\n slot0.observationIndex,\n _observationData.blockTimestamp,\n slot0.tick,\n 0,\n slot0.observationCardinality,\n slot0.observationCardinalityNext\n );\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\n slot0.tick = _observationData.tick;\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\n _;\n }\n\n modifier onlyFactory() {\n if (msg.sender != address(factory)) revert OnlyFactory();\n _;\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/TickMath.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n error T();\n error R();\n\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n unchecked {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n if (absTick > uint256(int256(MAX_TICK))) revert T();\n\n uint256 ratio = absTick & 0x1 != 0\n ? 0xfffcb933bd6fad37aa2d162d1a594001\n : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\n /// ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n unchecked {\n // second inequality must be < because the price can never reach the price at the max tick\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/Oracle.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/// @title Oracle\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\n/// @dev Instances of stored oracle data, \"observations\", are collected in the oracle array\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\n/// Observations are overwritten when the full length of the oracle array is populated.\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\nlibrary Oracle {\n error I();\n error OLD();\n\n struct Observation {\n // the block timestamp of the observation\n uint32 blockTimestamp;\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\n int56 tickCumulative;\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\n uint160 secondsPerLiquidityCumulativeX128;\n // whether or not the observation is initialized\n bool initialized;\n }\n\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\n /// @param last The specified observation to be transformed\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @return Observation The newly populated observation\n function transform(\n Observation memory last,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity\n ) private pure returns (Observation memory) {\n unchecked {\n uint32 delta = blockTimestamp - last.blockTimestamp;\n return\n Observation({\n blockTimestamp: blockTimestamp,\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\n initialized: true\n });\n }\n }\n\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\n /// @param self The stored oracle array\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\n /// @return cardinality The number of populated elements in the oracle array\n /// @return cardinalityNext The new length of the oracle array, independent of population\n function initialize(Observation[65535] storage self, uint32 time)\n internal\n returns (uint16 cardinality, uint16 cardinalityNext)\n {\n self[0] = Observation({\n blockTimestamp: time,\n tickCumulative: 0,\n secondsPerLiquidityCumulativeX128: 0,\n initialized: true\n });\n return (1, 1);\n }\n\n /// @notice Writes an oracle observation to the array\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\n /// @param self The stored oracle array\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @param cardinality The number of populated elements in the oracle array\n /// @param cardinalityNext The new length of the oracle array, independent of population\n /// @return indexUpdated The new index of the most recently written element in the oracle array\n /// @return cardinalityUpdated The new cardinality of the oracle array\n function write(\n Observation[65535] storage self,\n uint16 index,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity,\n uint16 cardinality,\n uint16 cardinalityNext\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\n unchecked {\n Observation memory last = self[index];\n\n // early return if we've already written an observation this block\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\n\n // if the conditions are right, we can bump the cardinality\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\n cardinalityUpdated = cardinalityNext;\n } else {\n cardinalityUpdated = cardinality;\n }\n\n indexUpdated = (index + 1) % cardinalityUpdated;\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\n }\n }\n\n /// @notice Prepares the oracle array to store up to `next` observations\n /// @param self The stored oracle array\n /// @param current The current next cardinality of the oracle array\n /// @param next The proposed next cardinality which will be populated in the oracle array\n /// @return next The next cardinality which will be populated in the oracle array\n function grow(\n Observation[65535] storage self,\n uint16 current,\n uint16 next\n ) internal returns (uint16) {\n unchecked {\n if (current <= 0) revert I();\n // no-op if the passed next value isn't greater than the current next value\n if (next <= current) return current;\n // store in each slot to prevent fresh SSTOREs in swaps\n // this data will not be used because the initialized boolean is still false\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\n return next;\n }\n }\n\n /// @notice comparator for 32-bit timestamps\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\n /// @param time A timestamp truncated to 32 bits\n /// @param a A comparison timestamp from which to determine the relative position of `time`\n /// @param b From which to determine the relative position of `time`\n /// @return Whether `a` is chronologically <= `b`\n function lte(\n uint32 time,\n uint32 a,\n uint32 b\n ) private pure returns (bool) {\n unchecked {\n // if there hasn't been overflow, no need to adjust\n if (a <= time && b <= time) return a <= b;\n\n uint256 aAdjusted = a > time ? a : a + 2**32;\n uint256 bAdjusted = b > time ? b : b + 2**32;\n\n return aAdjusted <= bAdjusted;\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\n /// The result may be the same observation, or adjacent observations.\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation recorded before, or at, the target\n /// @return atOrAfter The observation recorded at, or after, the target\n function binarySearch(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n uint16 index,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n uint256 l = (index + 1) % cardinality; // oldest observation\n uint256 r = l + cardinality - 1; // newest observation\n uint256 i;\n while (true) {\n i = (l + r) / 2;\n\n beforeOrAt = self[i % cardinality];\n\n // we've landed on an uninitialized tick, keep searching higher (more recently)\n if (!beforeOrAt.initialized) {\n l = i + 1;\n continue;\n }\n\n atOrAfter = self[(i + 1) % cardinality];\n\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\n\n // check if we've found the answer!\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\n\n if (!targetAtOrAfter) r = i - 1;\n else l = i + 1;\n }\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\n /// @dev Assumes there is at least 1 initialized observation.\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param tick The active tick at the time of the returned or simulated observation\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The total pool liquidity at the time of the call\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\n function getSurroundingObservations(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n // optimistically set before to the newest observation\n beforeOrAt = self[index];\n\n // if the target is chronologically at or after the newest observation, we can early return\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\n if (beforeOrAt.blockTimestamp == target) {\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\n return (beforeOrAt, atOrAfter);\n } else {\n // otherwise, we need to transform\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\n }\n }\n\n // now, set before to the oldest observation\n beforeOrAt = self[(index + 1) % cardinality];\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\n\n // ensure that the target is chronologically at or after the oldest observation\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\n\n // if we've reached this point, we have to binary search\n return binarySearch(self, time, target, index, cardinality);\n }\n }\n\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\n /// at exactly the timestamp between the two observations.\n /// @param self The stored oracle array\n /// @param time The current block timestamp\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\n function observeSingle(\n Observation[65535] storage self,\n uint32 time,\n uint32 secondsAgo,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\n unchecked {\n if (secondsAgo == 0) {\n Observation memory last = self[index];\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\n }\n\n uint32 target = time - secondsAgo;\n\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\n self,\n time,\n target,\n tick,\n index,\n liquidity,\n cardinality\n );\n\n if (target == beforeOrAt.blockTimestamp) {\n // we're at the left boundary\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\n } else if (target == atOrAfter.blockTimestamp) {\n // we're at the right boundary\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\n } else {\n // we're in the middle\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\n return (\n beforeOrAt.tickCumulative +\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\n int56(uint56(targetDelta)),\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\n uint160(\n (uint256(\n atOrAfter.secondsPerLiquidityCumulativeX128 -\n beforeOrAt.secondsPerLiquidityCumulativeX128\n ) * targetDelta) / observationTimeDelta\n )\n );\n }\n }\n }\n\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\n /// @dev Reverts if `secondsAgos` > oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\n function observe(\n Observation[65535] storage self,\n uint32 time,\n uint32[] memory secondsAgos,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\n unchecked {\n if (cardinality <= 0) revert I();\n\n tickCumulatives = new int56[](secondsAgos.length);\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\n for (uint256 i = 0; i < secondsAgos.length; i++) {\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\n self,\n time,\n secondsAgos[i],\n tick,\n index,\n liquidity,\n cardinality\n );\n }\n }\n }\n}\n" - }, - "solidity/interfaces/bridges/IConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from './IBridgeReceiverAdapter.sol';\n\ninterface IConnextReceiverAdapter is IBridgeReceiverAdapter {\n // STATE VARIABLES\n\n function connext() external view returns (IConnext _connext);\n\n function source() external view returns (address _originContract);\n\n function originDomain() external view returns (uint32 _originDomain);\n}\n" - }, - "solidity/contracts/bridges/ConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {LibConnextStorage, TransferInfo} from '@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol';\nimport {IConnext, IConnextSenderAdapter, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../../interfaces/bridges/IConnextSenderAdapter.sol';\n\ncontract ConnextSenderAdapter is IConnextSenderAdapter {\n /// @inheritdoc IConnextSenderAdapter\n IConnext public immutable connext;\n\n /// @inheritdoc IConnextSenderAdapter\n IDataFeed public immutable dataFeed;\n\n constructor(IConnext _connext, IDataFeed _dataFeed) {\n connext = _connext;\n dataFeed = _dataFeed;\n }\n\n /// @inheritdoc IBridgeSenderAdapter\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce // TODO: review input parameters packing KMC-\n ) external payable onlyDataFeed {\n bytes memory _callData = abi.encode(_observationsData, _poolSalt, _poolNonce);\n\n connext.xcall({\n _destination: _destinationDomainId, // unique identifier for destination domain\n _to: _to, // recipient of funds, where calldata will be executed\n _asset: address(0), // asset being transferred\n _delegate: address(0), // permissioned address to recover in edgecases on destination domain\n _amount: 0, // amount being transferred\n _slippage: 0, // slippage in bps\n _callData: _callData // to be executed on _to on the destination domain\n });\n }\n\n modifier onlyDataFeed() {\n if (msg.sender != address(dataFeed)) revert OnlyDataFeed();\n _;\n }\n}\n" - }, - "solidity/interfaces/peripherals/IKeep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './IGovernable.sol';\nimport {IKeep3r} from '@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol';\n\ninterface IKeep3rJob is IGovernable {\n // STATE VARIABLES\n\n /// @return _keep3r Address of the Keep3r contract\n function keep3r() external view returns (IKeep3r _keep3r);\n\n // EVENTS\n\n /// @notice Emitted when a new Keep3r contract is set\n /// @param _keep3r Address of the new Keep3r contract\n event Keep3rSet(IKeep3r _keep3r);\n\n // ERRORS\n\n /// @notice Throws when a keeper fails the validation\n error KeeperNotValid();\n\n // FUNCTIONS\n\n /// @notice Allows governor to set a new Keep3r contract\n /// @param _keep3r Address of the new Keep3r contract\n function setKeep3r(IKeep3r _keep3r) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rAccountance.sol';\nimport './peripherals/IKeep3rRoles.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rAccountance, IKeep3rRoles, IKeep3rParameters {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rKeepers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable, IKeep3rKeeperFundable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rJobs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobOwnership, IKeep3rJobDisputable, IKeep3rJobMigration, IKeep3rJobManager, IKeep3rJobWorkable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rAccountance.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rRoles.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rParameters.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\n\ninterface IKeep3rParameters is IBaseErrors {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IBaseErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" - }, - "solidity/interfaces/IStrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IKeep3rJob} from './peripherals/IKeep3rJob.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IStrategyJob is IKeep3rJob {\n // STATE VARIABLES\n\n /// @return _dataFeedStrategy The address of the current DataFeedStrategy\n function dataFeedStrategy() external view returns (IDataFeedStrategy _dataFeedStrategy);\n\n /// @return _dataFeed The address of the DataFeed\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _defaultBridgeSenderAdapter The address of the job bridge sender adapter\n function defaultBridgeSenderAdapter() external view returns (IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n /// @param _chainId The identifier of the chain\n /// @param _poolSalt The identifier of both the pool and oracle\n /// @return _lastPoolNonceBridged Last nonce of the oracle observed\n function lastPoolNonceBridged(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _lastPoolNonceBridged);\n\n // EVENTS\n\n /// @notice Emitted when a new default bridge sender adapter is set\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n event DefaultBridgeSenderAdapterSet(IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n // ERRORS\n\n /// @notice Thrown when the job is not workable\n error NotWorkable();\n\n // FUNCTIONS\n\n /// @notice Calls to send observations in the DataFeed contract\n /// @param _chainId The Ethereum chain identification\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Calls to fetch observations and update the oracle state in the DataFeed contract\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The identifier of the reason to trigger an update\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external;\n\n /// @notice Allows governor to set a new default bridge sender adapter\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external;\n\n /// @notice Returns if the job can be worked\n /// @param _chainId The destination chain ID\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n /// @return _isWorkable Whether the job is workable or not\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external view returns (bool _isWorkable);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the job can be worked\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the job can be worked\n /// @return _isWorkable Whether the job is workable or not\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external view returns (bool _isWorkable);\n}\n" - }, - "solidity/contracts/OracleFactory.sol": { - "content": "//TODO: change license\n//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IOracleFactory, IOracleSidechain, IDataReceiver} from '../interfaces/IOracleFactory.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The OracleFactory contract\n/// @notice Handles the deployment of new OracleSidechains\ncontract OracleFactory is IOracleFactory, Governable {\n /// @inheritdoc IOracleFactory\n IDataReceiver public dataReceiver;\n\n /// @inheritdoc IOracleFactory\n OracleParameters public oracleParameters;\n\n /// @inheritdoc IOracleFactory\n uint16 public initialCardinality = 144;\n\n /// @inheritdoc IOracleFactory\n bytes32 public constant ORACLE_INIT_CODE_HASH = keccak256(type(OracleSidechain).creationCode);\n\n constructor(address _governor, IDataReceiver _dataReceiver) Governable(_governor) {\n dataReceiver = _dataReceiver;\n }\n\n /// @inheritdoc IOracleFactory\n function deployOracle(bytes32 _poolSalt, uint24 _initialNonce) external onlyDataReceiver returns (IOracleSidechain _oracle) {\n oracleParameters = OracleParameters({poolSalt: _poolSalt, poolNonce: _initialNonce, cardinality: initialCardinality});\n _oracle = new OracleSidechain{salt: _poolSalt}();\n\n delete oracleParameters;\n emit OracleDeployed(_poolSalt, address(_oracle), _initialNonce);\n }\n\n /// @inheritdoc IOracleFactory\n function setDataReceiver(IDataReceiver _dataReceiver) external onlyGovernor {\n dataReceiver = _dataReceiver;\n emit DataReceiverSet(_dataReceiver);\n }\n\n /// @inheritdoc IOracleFactory\n function setInitialCardinality(uint16 _initialCardinality) external onlyGovernor {\n initialCardinality = _initialCardinality;\n emit InitialCardinalitySet(_initialCardinality);\n }\n\n function increaseOracleCardinality(bytes32 _poolSalt, uint16 _observationCardinalityNext) external onlyGovernor {\n IOracleSidechain _oracle = getPool(_poolSalt);\n _oracle.increaseObservationCardinalityNext(_observationCardinalityNext);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle) {\n bytes32 _poolSalt = getPoolSalt(_tokenA, _tokenB, _fee);\n _oracle = getPool(_poolSalt);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(bytes32 _poolSalt) public view returns (IOracleSidechain _oracle) {\n _oracle = IOracleSidechain(Create2Address.computeAddress(address(this), _poolSalt, ORACLE_INIT_CODE_HASH));\n if (address(_oracle).code.length == 0) return IOracleSidechain(address(0));\n }\n\n /// @inheritdoc IOracleFactory\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) public pure returns (bytes32 _poolSalt) {\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n _poolSalt = keccak256(abi.encode(_token0, _token1, _fee));\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(dataReceiver)) revert OnlyDataReceiver();\n _;\n }\n}\n" - }, - "solidity/for-test/DummyAdapterForTest.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\nimport {IDataReceiver} from '../interfaces/IDataReceiver.sol';\n\ncontract DummyAdapterForTest {\n // TODO: factorize interfaces so that this adapter can use same as sender/receiver\n event SentData(IDataReceiver, IOracleSidechain.ObservationData[]);\n event Create2Hash(bytes32);\n\n bool public ignoreTxs;\n\n constructor() {\n /// @dev Emitted to validate correct calculation of ORACLE_INIT_CODE_HASH\n emit Create2Hash(keccak256(type(OracleSidechain).creationCode));\n }\n\n function bridgeObservations(\n IDataReceiver _to,\n uint32,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable {\n if (!ignoreTxs) {\n _to.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n emit SentData(_to, _observationsData);\n }\n\n function setIgnoreTxs(bool _ignoreTxs) external {\n ignoreTxs = _ignoreTxs;\n }\n}\n" - }, - "solidity/for-test/GovernableForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" - }, - "solidity/contracts/DataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {IDataFeedStrategy, IUniswapV3Pool, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeedStrategy.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The DataFeed Strategy contract\n/// @notice Handles when and how a history of a pool should be updated\ncontract DataFeedStrategy is IDataFeedStrategy, Governable {\n /// @inheritdoc IDataFeedStrategy\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public periodDuration;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public strategyCooldown;\n\n /// @inheritdoc IDataFeedStrategy\n uint24 public twapThreshold;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public twapLength;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(\n address _governor,\n IDataFeed _dataFeed,\n StrategySettings memory _params\n ) Governable(_governor) {\n dataFeed = _dataFeed;\n _setStrategyCooldown(_params.cooldown);\n _setTwapLength(_params.twapLength);\n _setTwapThreshold(_params.twapThreshold);\n _setPeriodDuration(_params.periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n if (!_isStrategic(_poolSalt, _lastPoolStateObserved, _reason)) revert NotStrategic();\n uint32[] memory _secondsAgos = calculateSecondsAgos(_lastPoolStateObserved.blockTimestamp);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n emit StrategicFetch(_poolSalt, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n /// @dev Allows governor to choose a timestamp from which to send data (overcome !OLD error)\n function forceFetchObservations(bytes32 _poolSalt, uint32 _fromTimestamp) external onlyGovernor {\n uint32[] memory _secondsAgos = calculateSecondsAgos(_fromTimestamp);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setStrategyCooldown(uint32 _strategyCooldown) external onlyGovernor {\n _setStrategyCooldown(_strategyCooldown);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapLength(uint32 _twapLength) external onlyGovernor {\n _setTwapLength(_twapLength);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapThreshold(uint24 _twapThreshold) external onlyGovernor {\n _setTwapThreshold(_twapThreshold);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setPeriodDuration(uint32 _periodDuration) external onlyGovernor {\n _setPeriodDuration(_periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason) {\n if (isStrategic(_poolSalt, TriggerReason.TIME)) return TriggerReason.TIME;\n if (isStrategic(_poolSalt, TriggerReason.TWAP)) return TriggerReason.TWAP;\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) public view returns (bool _strategic) {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n return _isStrategic(_poolSalt, _lastPoolStateObserved, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function calculateSecondsAgos(uint32 _fromTimestamp) public view returns (uint32[] memory _secondsAgos) {\n if (_fromTimestamp == 0) return _initializeSecondsAgos();\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _timeSinceLastObservation = _secondsNow - _fromTimestamp;\n uint32 _periodDuration = periodDuration;\n uint32 _periods = _timeSinceLastObservation / _periodDuration;\n uint32 _remainder = _timeSinceLastObservation % _periodDuration;\n uint32 _i;\n\n if (_remainder != 0) {\n _secondsAgos = new uint32[](++_periods);\n _timeSinceLastObservation -= _remainder;\n _secondsAgos[_i++] = _timeSinceLastObservation;\n } else {\n _secondsAgos = new uint32[](_periods);\n }\n\n while (_timeSinceLastObservation > 0) {\n _timeSinceLastObservation -= _periodDuration;\n _secondsAgos[_i++] = _timeSinceLastObservation;\n }\n }\n\n function _isStrategic(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n TriggerReason _reason\n ) internal view returns (bool _strategic) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n if (_reason == TriggerReason.TIME) {\n return _secondsNow >= _lastPoolStateObserved.blockTimestamp + strategyCooldown;\n } else if (_reason == TriggerReason.TWAP) {\n return _twapIsOutOfThresholds(_poolSalt, _lastPoolStateObserved, _secondsNow);\n }\n }\n\n function _twapIsOutOfThresholds(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n uint32 _secondsNow\n ) internal view returns (bool _isOutOfThresholds) {\n uint32 _twapLength = twapLength;\n\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[0] = _twapLength;\n _secondsAgos[1] = 0;\n\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _poolTickCumulatives, ) = _pool.observe(_secondsAgos);\n\n int24 _poolArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _poolTickCumulatives[1], _twapLength);\n\n uint32 _oracleDelta = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n int56 _oracleTickCumulative = _lastPoolStateObserved.tickCumulative + int56(_lastPoolStateObserved.arithmeticMeanTick) * int32(_oracleDelta);\n\n int24 _oracleArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _oracleTickCumulative, _twapLength);\n\n return\n _poolArithmeticMeanTick > _oracleArithmeticMeanTick + int24(twapThreshold) ||\n _poolArithmeticMeanTick < _oracleArithmeticMeanTick - int24(twapThreshold);\n }\n\n function _computeTwap(\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n uint32 _delta\n ) internal pure returns (int24 _arithmeticMeanTick) {\n int56 _tickCumulativesDelta = _tickCumulative2 - _tickCumulative1;\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n }\n\n function _initializeSecondsAgos() internal view returns (uint32[] memory _secondsAgos) {\n // TODO: define initialization of _secondsAgos\n _secondsAgos = new uint32[](2);\n _secondsAgos[0] = periodDuration;\n _secondsAgos[1] = 0; // as if _fromTimestamp = _secondsNow - (periodDuration + 1)\n }\n\n function _setStrategyCooldown(uint32 _strategyCooldown) private {\n if (_strategyCooldown < twapLength) revert WrongSetting();\n\n strategyCooldown = _strategyCooldown;\n emit StrategyCooldownSet(_strategyCooldown);\n }\n\n function _setTwapLength(uint32 _twapLength) private {\n if ((_twapLength > strategyCooldown) || (_twapLength < periodDuration)) revert WrongSetting();\n\n twapLength = _twapLength;\n emit TwapLengthSet(_twapLength);\n }\n\n function _setTwapThreshold(uint24 _twapThreshold) private {\n twapThreshold = _twapThreshold;\n emit TwapThresholdSet(_twapThreshold);\n }\n\n function _setPeriodDuration(uint32 _periodDuration) private {\n if (_periodDuration > twapLength) revert WrongSetting();\n\n periodDuration = _periodDuration;\n emit PeriodDurationSet(_periodDuration);\n }\n}\n" - }, - "solidity/contracts/peripherals/Keep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './Governable.sol';\nimport {IKeep3rJob, IKeep3r} from '../../interfaces/peripherals/IKeep3rJob.sol';\n\nabstract contract Keep3rJob is IKeep3rJob, Governable {\n /// @inheritdoc IKeep3rJob\n IKeep3r public keep3r = IKeep3r(0xeb02addCfD8B773A5FFA6B9d1FE99c566f8c44CC);\n\n /// @inheritdoc IKeep3rJob\n function setKeep3r(IKeep3r _keep3r) public onlyGovernor {\n _setKeep3r(_keep3r);\n }\n\n function _setKeep3r(IKeep3r _keep3r) internal {\n keep3r = _keep3r;\n emit Keep3rSet(_keep3r);\n }\n\n function _isValidKeeper(address _keeper) internal virtual {\n if (!keep3r.isKeeper(_keeper)) revert KeeperNotValid();\n }\n\n modifier upkeep() {\n _isValidKeeper(msg.sender);\n _;\n keep3r.worked(msg.sender);\n }\n}\n" - }, - "solidity/for-test/Keep3rJobForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from '../contracts/peripherals/Keep3rJob.sol';\n\ncontract Keep3rJobForTest is Keep3rJob {\n constructor(address _governor) Governable(_governor) {}\n\n function internalIsValidKeeper(address _keeper) external {\n _isValidKeeper(_keeper);\n }\n}\n" - }, - "solidity/contracts/StrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from './peripherals/Keep3rJob.sol';\nimport {IStrategyJob, IDataFeedStrategy, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IStrategyJob.sol';\n\n/// @title The StrategyJob contract\n/// @notice Adds a reward layer for triggering fetch and bridge transactions\ncontract StrategyJob is IStrategyJob, Keep3rJob {\n /// @inheritdoc IStrategyJob\n IDataFeedStrategy public immutable dataFeedStrategy;\n\n /// @inheritdoc IStrategyJob\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IStrategyJob\n IBridgeSenderAdapter public defaultBridgeSenderAdapter;\n\n /// @inheritdoc IStrategyJob\n mapping(uint32 => mapping(bytes32 => uint24)) public lastPoolNonceBridged;\n\n constructor(\n address _governor,\n IDataFeedStrategy _dataFeedStrategy,\n IDataFeed _dataFeed,\n IBridgeSenderAdapter _defaultBridgeSenderAdapter\n ) Governable(_governor) {\n dataFeedStrategy = _dataFeedStrategy;\n dataFeed = _dataFeed;\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external upkeep {\n // TODO: change criteria for workable (if there's a new nonce, bridge)\n if (!_workable(_chainId, _poolSalt, _poolNonce)) revert NotWorkable();\n lastPoolNonceBridged[_chainId][_poolSalt] = _poolNonce;\n dataFeed.sendObservations(defaultBridgeSenderAdapter, _chainId, _poolSalt, _poolNonce, _observationsData);\n }\n\n /// @inheritdoc IStrategyJob\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external upkeep {\n dataFeedStrategy.strategicFetchObservations(_poolSalt, _reason);\n }\n\n /// @inheritdoc IStrategyJob\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external onlyGovernor {\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) public view returns (bool _isWorkable) {\n uint24 _whitelistedNonce = dataFeed.whitelistedNonces(_chainId, _poolSalt);\n if (_whitelistedNonce != 0 && _whitelistedNonce <= _poolNonce) return _workable(_chainId, _poolSalt, _poolNonce);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) public view returns (bool _isWorkable) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt, _reason);\n }\n\n function _workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal view returns (bool _isWorkable) {\n uint24 _lastPoolNonceBridged = lastPoolNonceBridged[_chainId][_poolSalt];\n if (_lastPoolNonceBridged == 0) {\n (uint24 _lastPoolNonceObserved, , , ) = dataFeed.lastPoolStateObserved(_poolSalt);\n return _poolNonce == _lastPoolNonceObserved;\n } else {\n return _poolNonce == ++_lastPoolNonceBridged;\n }\n }\n\n function _setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) private {\n defaultBridgeSenderAdapter = _defaultBridgeSenderAdapter;\n emit DefaultBridgeSenderAdapterSet(_defaultBridgeSenderAdapter);\n }\n}\n" - }, - "@openzeppelin/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" - }, - "@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "solidity/for-test/ERC20ForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n // solhint-disable-next-line no-empty-blocks\n function deposit(uint256 _amount) external payable {\n // Function added for compatibility with WETH\n }\n}\n" - }, - "solidity/contracts/bridges/ConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {BridgeReceiverAdapter} from './BridgeReceiverAdapter.sol';\nimport {IConnext, IConnextReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IConnextReceiverAdapter.sol';\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextReceiverAdapter is BridgeReceiverAdapter, IXReceiver, IConnextReceiverAdapter {\n // The connectHandler contract on this domain\n IConnext public immutable connext;\n // The origin domain ID\n uint32 public immutable originDomain;\n // The DAO that's expected as the xcaller\n address public immutable source;\n\n constructor(\n IDataReceiver _dataReceiver,\n address _source,\n uint32 _originDomain,\n IConnext _connext\n ) BridgeReceiverAdapter(_dataReceiver) {\n source = _source;\n originDomain = _originDomain;\n connext = _connext;\n }\n\n function xReceive(\n bytes32, // _transferId\n uint256, // _amount\n address, // _asset\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external onlyExecutor(_originSender, _origin) returns (bytes memory) {\n (IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, uint24 _poolNonce) = abi.decode(\n _callData,\n (IOracleSidechain.ObservationData[], bytes32, uint24)\n );\n\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n return bytes(abi.encode(''));\n }\n\n modifier onlyExecutor(address _originSender, uint32 _originDomain) {\n if (msg.sender != address(connext) || _originSender != source || _originDomain != originDomain) revert UnauthorizedCaller();\n _;\n }\n}\n" - }, - "solidity/contracts/bridges/BridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IBridgeReceiverAdapter.sol';\n\nabstract contract BridgeReceiverAdapter is IBridgeReceiverAdapter {\n /// @inheritdoc IBridgeReceiverAdapter\n IDataReceiver public immutable dataReceiver;\n\n constructor(IDataReceiver _dataReceiver) {\n dataReceiver = _dataReceiver;\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n dataReceiver.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface IXReceiver {\n function xReceive(\n bytes32 _transferId,\n uint256 _amount,\n address _asset,\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external returns (bytes memory);\n}\n" - }, - "solidity/for-test/ConnextHandlerForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextHandlerForTest {\n uint32 public origin;\n\n constructor() {\n // TODO: set in constructor\n origin = 1111;\n }\n\n function xcall(\n uint32, // _destination, unique identifier for destination domain\n address _to, // recipient of funds, where calldata will be executed\n address, // _asset, asset being transferred\n address, // _delegate, permissioned address to recover in edgecases on destination domain\n uint256, // _amount, amount being transferred\n uint256, // _slippage, slippage in bps\n bytes calldata _callData // to be executed on _to on the destination domain\n ) external payable returns (bytes32) {\n IXReceiver(_to).xReceive({_transferId: 0, _amount: 0, _asset: address(0), _originSender: msg.sender, _origin: origin, _callData: _callData});\n\n return bytes32(abi.encode('random'));\n }\n}\n" - }, - "solidity/for-test/UniswapV3Importer.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Factory} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';\nimport {ISwapRouter} from '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';\n\n//import {INonfungiblePositionManager} from '@uniswap/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol';\n\ninterface INFTPositionManager {\n struct MintParams {\n address token0;\n address token1;\n uint24 fee;\n int24 tickLower;\n int24 tickUpper;\n uint256 amount0Desired;\n uint256 amount1Desired;\n uint256 amount0Min;\n uint256 amount1Min;\n address recipient;\n uint256 deadline;\n }\n\n function mint(MintParams calldata _params)\n external\n payable\n returns (\n uint256 _tokenId,\n uint128 _liquidity,\n uint256 _amount0,\n uint256 _amount1\n );\n}\n\n// solhint-disable-next-line no-empty-blocks\ncontract UniswapV3Importer {\n\n}\n" - }, - "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\npragma abicoder v2;\n\nimport '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface ISwapRouter is IUniswapV3SwapCallback {\n struct ExactInputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactOutputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);\n\n struct ExactOutputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title The interface for the Uniswap V3 Factory\n/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees\ninterface IUniswapV3Factory {\n /// @notice Emitted when the owner of the factory is changed\n /// @param oldOwner The owner before the owner was changed\n /// @param newOwner The owner after the owner was changed\n event OwnerChanged(address indexed oldOwner, address indexed newOwner);\n\n /// @notice Emitted when a pool is created\n /// @param token0 The first token of the pool by address sort order\n /// @param token1 The second token of the pool by address sort order\n /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip\n /// @param tickSpacing The minimum number of ticks between initialized ticks\n /// @param pool The address of the created pool\n event PoolCreated(\n address indexed token0,\n address indexed token1,\n uint24 indexed fee,\n int24 tickSpacing,\n address pool\n );\n\n /// @notice Emitted when a new fee amount is enabled for pool creation via the factory\n /// @param fee The enabled fee, denominated in hundredths of a bip\n /// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee\n event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing);\n\n /// @notice Returns the current owner of the factory\n /// @dev Can be changed by the current owner via setOwner\n /// @return The address of the factory owner\n function owner() external view returns (address);\n\n /// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled\n /// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context\n /// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee\n /// @return The tick spacing\n function feeAmountTickSpacing(uint24 fee) external view returns (int24);\n\n /// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist\n /// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order\n /// @param tokenA The contract address of either token0 or token1\n /// @param tokenB The contract address of the other token\n /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip\n /// @return pool The pool address\n function getPool(\n address tokenA,\n address tokenB,\n uint24 fee\n ) external view returns (address pool);\n\n /// @notice Creates a pool for the given two tokens and fee\n /// @param tokenA One of the two tokens in the desired pool\n /// @param tokenB The other of the two tokens in the desired pool\n /// @param fee The desired fee for the pool\n /// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved\n /// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments\n /// are invalid.\n /// @return pool The address of the newly created pool\n function createPool(\n address tokenA,\n address tokenB,\n uint24 fee\n ) external returns (address pool);\n\n /// @notice Updates the owner of the factory\n /// @dev Must be called by the current owner\n /// @param _owner The new owner of the factory\n function setOwner(address _owner) external;\n\n /// @notice Enables a fee amount with the given tickSpacing\n /// @dev Fee amounts may never be removed once enabled\n /// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6)\n /// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount\n function enableFeeAmount(uint24 fee, int24 tickSpacing) external;\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Callback for IUniswapV3PoolActions#swap\n/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface\ninterface IUniswapV3SwapCallback {\n /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n /// @dev In the implementation you must pay the pool tokens owed for the swap.\n /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n function uniswapV3SwapCallback(\n int256 amount0Delta,\n int256 amount1Delta,\n bytes calldata data\n ) external;\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file diff --git a/deployments/optimism/ConnextReceiverAdapter.json b/deployments/optimism/ConnextReceiverAdapter.json index fc4b062..d504d44 100644 --- a/deployments/optimism/ConnextReceiverAdapter.json +++ b/deployments/optimism/ConnextReceiverAdapter.json @@ -1,5 +1,5 @@ { - "address": "0x5bBa978A823a8f1fBFBb61d440ea1483Ad1737a6", + "address": "0xe5BE7f12B94D185f892c4BBe6F88ABE65CE1A8af", "abi": [ { "inputs": [ @@ -154,33 +154,33 @@ "type": "function" } ], - "transactionHash": "0xc3d01518292b7d021a9165b5e33c8552cb13e5634d6a4e7278dc49f7e84ad2e3", + "transactionHash": "0x217662ad31c2a95eab8b208894764925b02780202f48467c630d48beaa2dd932", "receipt": { "to": null, - "from": "0xb7157Be5c36aE31344e13F49bb4d55066DbB6aC4", - "contractAddress": "0x5bBa978A823a8f1fBFBb61d440ea1483Ad1737a6", - "transactionIndex": 0, - "gasUsed": "408143", + "from": "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "contractAddress": "0xe5BE7f12B94D185f892c4BBe6F88ABE65CE1A8af", + "transactionIndex": 15, + "gasUsed": "408291", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4308d902660afbb2c82a556198197418e5a092fa55db608ebf2fba3337884ede", - "transactionHash": "0xc3d01518292b7d021a9165b5e33c8552cb13e5634d6a4e7278dc49f7e84ad2e3", + "blockHash": "0xf7865028a4c3b6f86f53633bdc29871ded5c233e897addade508e1e9b5317d22", + "transactionHash": "0x217662ad31c2a95eab8b208894764925b02780202f48467c630d48beaa2dd932", "logs": [], - "blockNumber": 72612310, - "cumulativeGasUsed": "408143", + "blockNumber": 124330065, + "cumulativeGasUsed": "8060469", "status": 1, "byzantium": true }, "args": [ - "0x5b9315CE1304DF3B2A83B2074cbF849D160642Ab", + "0x4E0CeF6426eb70b5708845825A5375688808891d", "0x8f7492DE823025b4CfaAB1D34c58963F2af5DEDA", "0x5b9315CE1304DF3B2A83B2074cbF849D160642Ab", 6648936 ], - "numDeployments": 4, - "solcInputHash": "1a064550c306047de745b0aa850ace2a", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"},{\"internalType\":\"contract IConnext\",\"name\":\"_connext\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_source\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_originDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"connext\",\"outputs\":[{\"internalType\":\"contract IConnext\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dataReceiver\",\"outputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"originDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"source\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_originSender\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_callData\",\"type\":\"bytes\"}],\"name\":\"xReceive\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"connext\":{\"return\":\"Address of the ConnextHandler contract\",\"returns\":{\"_0\":\"Address of the ConnextHandler contract\"}},\"originDomain\":{\"return\":\"The origin domain id\",\"returns\":{\"_0\":\"The origin domain id\"}},\"source\":{\"return\":\"Address of the xcaller contract\",\"returns\":{\"_0\":\"Address of the xcaller contract\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"UnauthorizedCaller()\":[{\"notice\":\"Thrown if a caller is not authorized\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"kind\":\"user\",\"methods\":{\"connext()\":{\"notice\":\"Gets the ConnextHandler contract on this domain\"},\"dataReceiver()\":{\"notice\":\"Gets the address of the DataReceiver contract\"},\"originDomain()\":{\"notice\":\"Gets the origin domain id\"},\"source()\":{\"notice\":\"Gets the DAO that is expected as the xcaller\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/bridges/ConnextReceiverAdapter.sol\":\"ConnextReceiverAdapter\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {ERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title Liquidity Provider Token\\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\\n * It is used to represent user's shares when providing liquidity to swap contracts.\\n * @dev Only Swap contracts should initialize and own LPToken contracts.\\n */\\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\\n // ============ Upgrade Gap ============\\n\\n uint256[49] private __GAP; // gap for upgrade safety\\n\\n // ============ Storage ============\\n\\n /**\\n * @notice Used to enforce proper token dilution\\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\\n * See audit recommendations here:\\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\\n * and uniswap v2 implementation here:\\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\\n */\\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\\n\\n // ============ Initializer ============\\n\\n /**\\n * @notice Initializes this LPToken contract with the given name and symbol\\n * @dev The caller of this function will become the owner. A Swap contract should call this\\n * in its initializer function.\\n * @param name name of this token\\n * @param symbol symbol of this token\\n */\\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\\n __Context_init_unchained();\\n __ERC20_init_unchained(name, symbol);\\n __Ownable_init_unchained();\\n return true;\\n }\\n\\n // ============ External functions ============\\n\\n /**\\n * @notice Mints the given amount of LPToken to the recipient.\\n * @dev only owner can call this mint function\\n * @param recipient address of account to receive the tokens\\n * @param amount amount of tokens to mint\\n */\\n function mint(address recipient, uint256 amount) external onlyOwner {\\n require(amount != 0, \\\"LPToken: cannot mint 0\\\");\\n if (totalSupply() == 0) {\\n // NOTE: using the _mint function directly will error because it is going\\n // to the 0 address. fix by using the address(1) here instead\\n _mint(address(1), MINIMUM_LIQUIDITY);\\n }\\n _mint(recipient, amount);\\n }\\n\\n /**\\n * @notice Burns the given amount of LPToken from provided account\\n * @dev only owner can call this burn function\\n * @param account address of account from which to burn token\\n * @param amount amount of tokens to mint\\n */\\n function burnFrom(address account, uint256 amount) external onlyOwner {\\n require(amount != 0, \\\"LPToken: cannot burn 0\\\");\\n _burn(account, amount);\\n }\\n\\n // ============ Internal functions ============\\n\\n /**\\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\\n * This assumes the owner is set to a Swap contract's address.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20Upgradeable) {\\n super._beforeTokenTransfer(from, to, amount);\\n require(to != address(this), \\\"LPToken: cannot send to itself\\\");\\n }\\n}\\n\",\"keccak256\":\"0x1d3f871488111c70a6f9b09ad3baeb21ebc635c82aa2c6d627d07e09720e4126\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport {ExecuteArgs, TransferInfo, TokenId, DestinationTransferStatus} from \\\"../libraries/LibConnextStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {SwapUtils} from \\\"../libraries/SwapUtils.sol\\\";\\n\\nimport {IStableSwap} from \\\"./IStableSwap.sol\\\";\\n\\nimport {IDiamondCut} from \\\"./IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\ninterface IConnext is IDiamondLoupe, IDiamondCut {\\n // TokenFacet\\n function canonicalToAdopted(bytes32 _key) external view returns (address);\\n\\n function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\\n\\n function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\\n\\n function canonicalToRepresentation(bytes32 _key) external view returns (address);\\n\\n function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\\n\\n function representationToCanonical(address _adopted) external view returns (TokenId memory);\\n\\n function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\\n\\n function approvedAssets(bytes32 _key) external view returns (bool);\\n\\n function approvedAssets(TokenId calldata _canonical) external view returns (bool);\\n\\n function adoptedToLocalPools(bytes32 _key) external view returns (IStableSwap);\\n\\n function adoptedToLocalPools(TokenId calldata _canonical) external view returns (IStableSwap);\\n\\n function getTokenId(address _candidate) external view returns (TokenId memory);\\n\\n function setupAsset(\\n TokenId calldata _canonical,\\n uint8 _canonicalDecimals,\\n string memory _representationName,\\n string memory _representationSymbol,\\n address _adoptedAssetId,\\n address _stableSwapPool,\\n uint256 _cap\\n ) external returns (address);\\n\\n function setupAssetWithDeployedRepresentation(\\n TokenId calldata _canonical,\\n address _representation,\\n address _adoptedAssetId,\\n address _stableSwapPool,\\n uint256 _cap\\n ) external returns (address);\\n\\n function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\\n\\n function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\\n\\n function removeAssetId(\\n bytes32 _key,\\n address _adoptedAssetId,\\n address _representation\\n ) external;\\n\\n function removeAssetId(\\n TokenId calldata _canonical,\\n address _adoptedAssetId,\\n address _representation\\n ) external;\\n\\n function updateDetails(\\n TokenId calldata _canonical,\\n string memory _name,\\n string memory _symbol\\n ) external;\\n\\n // BaseConnextFacet\\n\\n // BridgeFacet\\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\\n\\n function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\\n\\n function remote(uint32 _domain) external view returns (address);\\n\\n function domain() external view returns (uint256);\\n\\n function nonce() external view returns (uint256);\\n\\n function approvedSequencers(address _sequencer) external view returns (bool);\\n\\n function xAppConnectionManager() external view returns (address);\\n\\n function addConnextion(uint32 _domain, address _connext) external;\\n\\n function addSequencer(address _sequencer) external;\\n\\n function removeSequencer(address _sequencer) external;\\n\\n function xcall(\\n uint32 _destination,\\n address _to,\\n address _asset,\\n address _delegate,\\n uint256 _amount,\\n uint256 _slippage,\\n bytes calldata _callData\\n ) external payable returns (bytes32);\\n\\n function xcallIntoLocal(\\n uint32 _destination,\\n address _to,\\n address _asset,\\n address _delegate,\\n uint256 _amount,\\n uint256 _slippage,\\n bytes calldata _callData\\n ) external payable returns (bytes32);\\n\\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\\n\\n function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\\n\\n function bumpTransfer(bytes32 _transferId) external payable;\\n\\n function setXAppConnectionManager(address _xAppConnectionManager) external;\\n\\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\\n\\n function enrollCustom(\\n uint32 _domain,\\n bytes32 _id,\\n address _custom\\n ) external;\\n\\n // InboxFacet\\n\\n function handle(\\n uint32 _origin,\\n uint32 _nonce,\\n bytes32 _sender,\\n bytes memory _message\\n ) external;\\n\\n // ProposedOwnableFacet\\n\\n function owner() external view returns (address);\\n\\n function routerWhitelistRemoved() external view returns (bool);\\n\\n function assetWhitelistRemoved() external view returns (bool);\\n\\n function proposed() external view returns (address);\\n\\n function proposedTimestamp() external view returns (uint256);\\n\\n function routerWhitelistTimestamp() external view returns (uint256);\\n\\n function assetWhitelistTimestamp() external view returns (uint256);\\n\\n function delay() external view returns (uint256);\\n\\n function proposeRouterWhitelistRemoval() external;\\n\\n function removeRouterWhitelist() external;\\n\\n function proposeAssetWhitelistRemoval() external;\\n\\n function removeAssetWhitelist() external;\\n\\n function renounced() external view returns (bool);\\n\\n function proposeNewOwner(address newlyProposed) external;\\n\\n function renounceOwnership() external;\\n\\n function acceptProposedOwner() external;\\n\\n function pause() external;\\n\\n function unpause() external;\\n\\n // RelayerFacet\\n function approvedRelayers(address _relayer) external view returns (bool);\\n\\n function relayerFeeVault() external view returns (address);\\n\\n function setRelayerFeeVault(address _relayerFeeVault) external;\\n\\n function addRelayer(address _relayer) external;\\n\\n function removeRelayer(address _relayer) external;\\n\\n // RoutersFacet\\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\\n\\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\\n\\n function getRouterApproval(address _router) external view returns (bool);\\n\\n function getRouterRecipient(address _router) external view returns (address);\\n\\n function getRouterOwner(address _router) external view returns (address);\\n\\n function getProposedRouterOwner(address _router) external view returns (address);\\n\\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\\n\\n function maxRoutersPerTransfer() external view returns (uint256);\\n\\n function routerBalances(address _router, address _asset) external view returns (uint256);\\n\\n function getRouterApprovalForPortal(address _router) external view returns (bool);\\n\\n function setupRouter(\\n address router,\\n address owner,\\n address recipient\\n ) external;\\n\\n function removeRouter(address router) external;\\n\\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\\n\\n function setLiquidityFeeNumerator(uint256 _numerator) external;\\n\\n function approveRouterForPortal(address _router) external;\\n\\n function unapproveRouterForPortal(address _router) external;\\n\\n function setRouterRecipient(address router, address recipient) external;\\n\\n function proposeRouterOwner(address router, address proposed) external;\\n\\n function acceptProposedRouterOwner(address router) external;\\n\\n function addRouterLiquidityFor(\\n uint256 _amount,\\n address _local,\\n address _router\\n ) external payable;\\n\\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\\n\\n function removeRouterLiquidityFor(\\n uint256 _amount,\\n address _local,\\n address payable _to,\\n address _router\\n ) external;\\n\\n function removeRouterLiquidity(\\n uint256 _amount,\\n address _local,\\n address payable _to\\n ) external;\\n\\n // PortalFacet\\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\\n\\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\\n\\n function aavePool() external view returns (address);\\n\\n function aavePortalFee() external view returns (uint256);\\n\\n function setAavePool(address _aavePool) external;\\n\\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\\n\\n function repayAavePortal(\\n TransferInfo calldata _params,\\n uint256 _backingAmount,\\n uint256 _feeAmount,\\n uint256 _maxIn\\n ) external;\\n\\n function repayAavePortalFor(\\n TransferInfo calldata _params,\\n uint256 _backingAmount,\\n uint256 _feeAmount\\n ) external;\\n\\n // StableSwapFacet\\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\\n\\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\\n\\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\\n\\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\\n\\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\\n\\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\\n\\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\\n\\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\\n\\n function calculateSwap(\\n bytes32 canonicalId,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx\\n ) external view returns (uint256);\\n\\n function calculateSwapTokenAmount(\\n bytes32 canonicalId,\\n uint256[] calldata amounts,\\n bool deposit\\n ) external view returns (uint256);\\n\\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\\n\\n function calculateRemoveSwapLiquidityOneToken(\\n bytes32 canonicalId,\\n uint256 tokenAmount,\\n uint8 tokenIndex\\n ) external view returns (uint256);\\n\\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\\n\\n function swap(\\n bytes32 canonicalId,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function swapExact(\\n bytes32 canonicalId,\\n uint256 amountIn,\\n address assetIn,\\n address assetOut,\\n uint256 minAmountOut,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function swapExactOut(\\n bytes32 canonicalId,\\n uint256 amountOut,\\n address assetIn,\\n address assetOut,\\n uint256 maxAmountIn,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function addSwapLiquidity(\\n bytes32 canonicalId,\\n uint256[] calldata amounts,\\n uint256 minToMint,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeSwapLiquidity(\\n bytes32 canonicalId,\\n uint256 amount,\\n uint256[] calldata minAmounts,\\n uint256 deadline\\n ) external returns (uint256[] memory);\\n\\n function removeSwapLiquidityOneToken(\\n bytes32 canonicalId,\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 minAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeSwapLiquidityImbalance(\\n bytes32 canonicalId,\\n uint256[] calldata amounts,\\n uint256 maxBurnAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n // SwapAdminFacet\\n\\n function initializeSwap(\\n bytes32 _canonicalId,\\n IERC20[] memory _pooledTokens,\\n uint8[] memory decimals,\\n string memory lpTokenName,\\n string memory lpTokenSymbol,\\n uint256 _a,\\n uint256 _fee,\\n uint256 _adminFee,\\n address lpTokenTargetAddress\\n ) external;\\n\\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\\n\\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\\n\\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\\n\\n function rampA(\\n bytes32 canonicalId,\\n uint256 futureA,\\n uint256 futureTime\\n ) external;\\n\\n function stopRampA(bytes32 canonicalId) external;\\n}\\n\",\"keccak256\":\"0xf4e97b6638cb0af7c41f69b151ec5c66e8d1532067674aecd71d8587a376be4a\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function proposeDiamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function rescindDiamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xd75a7bfdb3aeac3acebf8cf999330a0fc7bec65e9a68711bbb58f4554ef087b2\",\"license\":\"MIT\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xe6d71029d0a1846712477ccf17aa2124b82996c77b6e6486a208a68ea421f563\",\"license\":\"MIT\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IStableSwap {\\n /*** EVENTS ***/\\n\\n // events replicated from SwapUtils to make the ABI easier for dumb\\n // clients\\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\\n event AddLiquidity(\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\\n event RemoveLiquidityOne(\\n address indexed provider,\\n uint256 lpTokenAmount,\\n uint256 lpTokenSupply,\\n uint256 boughtId,\\n uint256 tokensBought\\n );\\n event RemoveLiquidityImbalance(\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event NewAdminFee(uint256 newAdminFee);\\n event NewSwapFee(uint256 newSwapFee);\\n event NewWithdrawFee(uint256 newWithdrawFee);\\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\\n event StopRampA(uint256 currentA, uint256 time);\\n\\n function swap(\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function swapExact(\\n uint256 amountIn,\\n address assetIn,\\n address assetOut,\\n uint256 minAmountOut,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function swapExactOut(\\n uint256 amountOut,\\n address assetIn,\\n address assetOut,\\n uint256 maxAmountIn,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function getA() external view returns (uint256);\\n\\n function getToken(uint8 index) external view returns (IERC20);\\n\\n function getTokenIndex(address tokenAddress) external view returns (uint8);\\n\\n function getTokenBalance(uint8 index) external view returns (uint256);\\n\\n function getVirtualPrice() external view returns (uint256);\\n\\n // min return calculation functions\\n function calculateSwap(\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx\\n ) external view returns (uint256);\\n\\n function calculateSwapOut(\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy\\n ) external view returns (uint256);\\n\\n function calculateSwapFromAddress(\\n address assetIn,\\n address assetOut,\\n uint256 amountIn\\n ) external view returns (uint256);\\n\\n function calculateSwapOutFromAddress(\\n address assetIn,\\n address assetOut,\\n uint256 amountOut\\n ) external view returns (uint256);\\n\\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\\n\\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\\n\\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\\n external\\n view\\n returns (uint256 availableTokenAmount);\\n\\n // state modifying functions\\n function initialize(\\n IERC20[] memory pooledTokens,\\n uint8[] memory decimals,\\n string memory lpTokenName,\\n string memory lpTokenSymbol,\\n uint256 a,\\n uint256 fee,\\n uint256 adminFee,\\n address lpTokenTargetAddress\\n ) external;\\n\\n function addLiquidity(\\n uint256[] calldata amounts,\\n uint256 minToMint,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeLiquidity(\\n uint256 amount,\\n uint256[] calldata minAmounts,\\n uint256 deadline\\n ) external returns (uint256[] memory);\\n\\n function removeLiquidityOneToken(\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 minAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeLiquidityImbalance(\\n uint256[] calldata amounts,\\n uint256 maxBurnAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n}\\n\",\"keccak256\":\"0xfbbb2cad0639658aa781212c69df10718250a6926d94a1a7508fc9927216abe8\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\ninterface IXReceiver {\\n function xReceive(\\n bytes32 _transferId,\\n uint256 _amount,\\n address _asset,\\n address _originSender,\\n uint32 _origin,\\n bytes memory _callData\\n ) external returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x75286f6ac1b1d5d7f4e508a478c0dad3a26d92675dabbf180d0b46d892618a1a\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport {SwapUtils} from \\\"./SwapUtils.sol\\\";\\n\\n/**\\n * @title AmplificationUtils library\\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\\n * This library assumes the struct is fully validated.\\n */\\nlibrary AmplificationUtils {\\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\\n event StopRampA(uint256 currentA, uint256 time);\\n\\n // Constant values used in ramping A calculations\\n uint256 public constant A_PRECISION = 100;\\n uint256 public constant MAX_A = 10**6;\\n uint256 private constant MAX_A_CHANGE = 2;\\n uint256 private constant MIN_RAMP_TIME = 14 days;\\n\\n /**\\n * @notice Return A, the amplification coefficient * n * (n - 1)\\n * @dev See the StableSwap paper for details\\n * @param self Swap struct to read from\\n * @return A parameter\\n */\\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\\n return _getAPrecise(self) / A_PRECISION;\\n }\\n\\n /**\\n * @notice Return A in its raw precision\\n * @dev See the StableSwap paper for details\\n * @param self Swap struct to read from\\n * @return A parameter in its raw precision form\\n */\\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\\n return _getAPrecise(self);\\n }\\n\\n /**\\n * @notice Return A in its raw precision\\n * @dev See the StableSwap paper for details\\n * @param self Swap struct to read from\\n * @return A parameter in its raw precision form\\n */\\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\\n uint256 t1 = self.futureATime; // time when ramp is finished\\n uint256 a1 = self.futureA; // final A value when ramp is finished\\n\\n if (block.timestamp < t1) {\\n uint256 t0 = self.initialATime; // time when ramp is started\\n uint256 a0 = self.initialA; // initial A value when ramp is started\\n if (a1 > a0) {\\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\\n return a0 + ((a1 - a0) * (block.timestamp - t0)) / (t1 - t0);\\n } else {\\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\\n return a0 - ((a0 - a1) * (block.timestamp - t0)) / (t1 - t0);\\n }\\n } else {\\n return a1;\\n }\\n }\\n\\n /**\\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\\n * Checks if the change is too rapid, and commits the new A value only when it falls under\\n * the limit range.\\n * @param self Swap struct to update\\n * @param futureA_ the new A to ramp towards\\n * @param futureTime_ timestamp when the new A should be reached\\n */\\n function rampA(\\n SwapUtils.Swap storage self,\\n uint256 futureA_,\\n uint256 futureTime_\\n ) internal {\\n require(block.timestamp >= self.initialATime + 1 days, \\\"Wait 1 day before starting ramp\\\");\\n require(futureTime_ >= block.timestamp + MIN_RAMP_TIME, \\\"Insufficient ramp time\\\");\\n require(futureA_ != 0 && futureA_ < MAX_A, \\\"futureA_ must be > 0 and < MAX_A\\\");\\n\\n uint256 initialAPrecise = _getAPrecise(self);\\n uint256 futureAPrecise = futureA_ * A_PRECISION;\\n\\n if (futureAPrecise < initialAPrecise) {\\n require(futureAPrecise * MAX_A_CHANGE >= initialAPrecise, \\\"futureA_ is too small\\\");\\n } else {\\n require(futureAPrecise <= initialAPrecise * MAX_A_CHANGE, \\\"futureA_ is too large\\\");\\n }\\n\\n self.initialA = initialAPrecise;\\n self.futureA = futureAPrecise;\\n self.initialATime = block.timestamp;\\n self.futureATime = futureTime_;\\n\\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\\n }\\n\\n /**\\n * @notice Stops ramping A immediately. Once this function is called, rampA()\\n * cannot be called for another 24 hours\\n * @param self Swap struct to update\\n */\\n function stopRampA(SwapUtils.Swap storage self) internal {\\n require(self.futureATime > block.timestamp, \\\"Ramp is already stopped\\\");\\n\\n uint256 currentA = _getAPrecise(self);\\n self.initialA = currentA;\\n self.futureA = currentA;\\n self.initialATime = block.timestamp;\\n self.futureATime = block.timestamp;\\n\\n emit StopRampA(currentA, block.timestamp);\\n }\\n}\\n\",\"keccak256\":\"0x7dca96b10fa307f469c142aaea0855d3c9ba45f79066eaeae1467ce113fc8d28\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {IStableSwap} from \\\"../interfaces/IStableSwap.sol\\\";\\nimport {IConnectorManager} from \\\"../../../messaging/interfaces/IConnectorManager.sol\\\";\\nimport {SwapUtils} from \\\"./SwapUtils.sol\\\";\\n\\n// ============= Enum =============\\n\\n/// @notice Enum representing address role\\n// Returns uint\\n// None - 0\\n// Router - 1\\n// Watcher - 2\\n// Admin - 3\\nenum Role {\\n None,\\n Router,\\n Watcher,\\n Admin\\n}\\n\\n/**\\n * @notice Enum representing status of destination transfer\\n * @dev Status is only assigned on the destination domain, will always be \\\"none\\\" for the\\n * origin domains\\n * @return uint - Index of value in enum\\n */\\nenum DestinationTransferStatus {\\n None, // 0\\n Reconciled, // 1\\n Executed, // 2\\n Completed // 3 - executed + reconciled\\n}\\n\\n// ============= Structs =============\\n\\nstruct TokenId {\\n uint32 domain;\\n bytes32 id;\\n}\\n\\n/**\\n * @notice These are the parameters that will remain constant between the\\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\\n * @property to - The account that receives funds, in the event of a crosschain call,\\n * will receive funds if the call fails.\\n *\\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\\n * @param canonicalDomain - The canonical domain of the asset you are bridging\\n * @param to - The address you are sending funds (and potentially data) to\\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\\n * a user takes 1% slippage, this is expressed as 1_000)\\n * @param originSender - The msg.sender of the xcall\\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\\n */\\nstruct TransferInfo {\\n uint32 originDomain;\\n uint32 destinationDomain;\\n uint32 canonicalDomain;\\n address to;\\n address delegate;\\n bool receiveLocal;\\n bytes callData;\\n uint256 slippage;\\n address originSender;\\n uint256 bridgedAmt;\\n uint256 normalizedIn;\\n uint256 nonce;\\n bytes32 canonicalId;\\n}\\n\\n/**\\n * @notice\\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\\n * @param routers - The routers who you are sending the funds on behalf of.\\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\\n * for the signed transfer ID.\\n * @param sequencer - The sequencer who assigned the router path to this transfer.\\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\\n * for the path that was signed.\\n */\\nstruct ExecuteArgs {\\n TransferInfo params;\\n address[] routers;\\n bytes[] routerSignatures;\\n address sequencer;\\n bytes sequencerSignature;\\n}\\n\\n/**\\n * @notice Contains RouterFacet related state\\n * @param approvedRouters - Mapping of whitelisted router addresses\\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\\n * (if configured) or the router itself\\n * @param routerOwners - Mapping of router owners\\n * If set, can update the routerRecipient\\n * @param proposedRouterOwners - Mapping of proposed router owners\\n * Must wait timeout to set the\\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\\n * When accepting a proposed owner, must wait for delay to elapse\\n */\\nstruct RouterPermissionsManagerInfo {\\n mapping(address => bool) approvedRouters;\\n mapping(address => bool) approvedForPortalRouters;\\n mapping(address => address) routerRecipients;\\n mapping(address => address) routerOwners;\\n mapping(address => address) proposedRouterOwners;\\n mapping(address => uint256) proposedRouterTimestamp;\\n}\\n\\nstruct AppStorage {\\n //\\n // 0\\n bool initialized;\\n //\\n // Connext\\n //\\n // 1\\n uint256 LIQUIDITY_FEE_NUMERATOR;\\n /**\\n * @notice The local address that is custodying relayer fees\\n */\\n // 2\\n address relayerFeeVault;\\n /**\\n * @notice Nonce for the contract, used to keep unique transfer ids.\\n * @dev Assigned at first interaction (xcall on origin domain).\\n */\\n // 3\\n uint256 nonce;\\n /**\\n * @notice The domain this contract exists on.\\n * @dev Must match the nomad domain, which is distinct from the \\\"chainId\\\".\\n */\\n // 4\\n uint32 domain;\\n /**\\n * @notice Mapping holding the AMMs for swapping in and out of local assets.\\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon).\\n * This mapping is keyed on the hash of the canonical id + domain for local asset.\\n */\\n // 6\\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\\n /**\\n * @notice Mapping of whitelisted assets on same domain as contract.\\n * @dev Mapping is keyed on the hash of the canonical id and domain\\n */\\n // 7\\n mapping(bytes32 => bool) approvedAssets;\\n /**\\n * @notice Mapping of liquidity caps of whitelisted assets. If 0, no cap is enforced.\\n * @dev Mapping is keyed on the hash of the canonical id and domain\\n */\\n // 7\\n mapping(bytes32 => uint256) caps;\\n /**\\n * @notice Mapping of adopted to canonical asset information.\\n * @dev If the adopted asset is the native asset, the keyed address will\\n * be the wrapped asset address.\\n */\\n // 8\\n mapping(address => TokenId) adoptedToCanonical;\\n /**\\n * @notice Mapping of representation to canonical asset information.\\n */\\n // 9\\n mapping(address => TokenId) representationToCanonical;\\n /**\\n * @notice Mapping of hash(canonicalId, canonicalDomain) to adopted asset on this domain.\\n * @dev If the adopted asset is the native asset, the stored address will be the\\n * wrapped asset address.\\n */\\n // 10\\n mapping(bytes32 => address) canonicalToAdopted;\\n /**\\n * @notice Mapping of canonical to representation asset information.\\n * @dev If the token is of local origin (meaning it was originanlly deployed on this chain),\\n * this MUST map to address(0).\\n */\\n // 11\\n mapping(bytes32 => address) canonicalToRepresentation;\\n /**\\n * @notice Mapping to track transfer status on destination domain\\n */\\n // 12\\n mapping(bytes32 => DestinationTransferStatus) transferStatus;\\n /**\\n * @notice Mapping holding router address that provided fast liquidity.\\n */\\n // 13\\n mapping(bytes32 => address[]) routedTransfers;\\n /**\\n * @notice Mapping of router to available balance of an asset.\\n * @dev Routers should always store liquidity that they can expect to receive via the bridge on\\n * this domain (the nomad local asset).\\n */\\n // 14\\n mapping(address => mapping(address => uint256)) routerBalances;\\n /**\\n * @notice Mapping of approved relayers\\n * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\\n */\\n // 15\\n mapping(address => bool) approvedRelayers;\\n /**\\n * @notice The max amount of routers a payment can be routed through.\\n */\\n // 18\\n uint256 maxRoutersPerTransfer;\\n /**\\n * @notice Stores a mapping of transfer id to slippage overrides.\\n */\\n // 20\\n mapping(bytes32 => uint256) slippage;\\n /**\\n * @notice Stores a mapping of remote routers keyed on domains.\\n * @dev Addresses are cast to bytes32.\\n * This mapping is required because the Connext now contains the BridgeRouter and must implement\\n * the remotes interface.\\n */\\n // 21\\n mapping(uint32 => bytes32) remotes;\\n //\\n // ProposedOwnable\\n //\\n // 22\\n address _proposed;\\n // 23\\n uint256 _proposedOwnershipTimestamp;\\n // 24\\n bool _routerWhitelistRemoved;\\n // 25\\n uint256 _routerWhitelistTimestamp;\\n // 26\\n bool _assetWhitelistRemoved;\\n // 27\\n uint256 _assetWhitelistTimestamp;\\n /**\\n * @notice Stores a mapping of address to Roles\\n * @dev returns uint representing the enum Role value\\n */\\n // 28\\n mapping(address => Role) roles;\\n //\\n // RouterFacet\\n //\\n // 29\\n RouterPermissionsManagerInfo routerPermissionInfo;\\n //\\n // ReentrancyGuard\\n //\\n // 30\\n uint256 _status;\\n //\\n // StableSwap\\n //\\n /**\\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\\n * Struct storing data responsible for automatic market maker functionalities. In order to\\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\\n */\\n // 31\\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\\n /**\\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\\n */\\n // 32\\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\\n /**\\n * @notice Stores whether or not bribing, AMMs, have been paused.\\n */\\n // 33\\n bool _paused;\\n //\\n // AavePortals\\n //\\n /**\\n * @notice Address of Aave Pool contract.\\n */\\n // 34\\n address aavePool;\\n /**\\n * @notice Fee percentage numerator for using Portal liquidity.\\n * @dev Assumes the same basis points as the liquidity fee.\\n */\\n // 35\\n uint256 aavePortalFeeNumerator;\\n /**\\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\\n */\\n // 36\\n mapping(bytes32 => uint256) portalDebt;\\n /**\\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\\n */\\n // 37\\n mapping(bytes32 => uint256) portalFeeDebt;\\n /**\\n * @notice Mapping of approved sequencers\\n * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\\n * for the fast liquidity route.\\n */\\n // 38\\n mapping(address => bool) approvedSequencers;\\n /**\\n * @notice Remote connection manager for xapp.\\n */\\n // 39\\n IConnectorManager xAppConnectionManager;\\n}\\n\\nlibrary LibConnextStorage {\\n function connextStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n}\\n\",\"keccak256\":\"0x24f998cc9edbb1f3f00c7148d18b7ca0d40eaaac7e3f7fa990ffe89bdee8ec32\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n // hash of proposed facets => acceptance time\\n mapping(bytes32 => uint256) acceptanceTimes;\\n // acceptance delay for upgrading facets\\n uint256 acceptanceDelay;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function acceptanceDelay() internal view returns (uint256) {\\n return diamondStorage().acceptanceDelay;\\n }\\n\\n function acceptanceTime(bytes32 _key) internal view returns (uint256) {\\n return diamondStorage().acceptanceTimes[_key];\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, \\\"LibDiamond: !contract owner\\\");\\n }\\n\\n event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\\n\\n function proposeDiamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 acceptance = block.timestamp + ds.acceptanceDelay;\\n ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\\n emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\\n }\\n\\n event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n function rescindDiamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\\n // period or befor the delay elpases\\n diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = 0;\\n emit DiamondCutRescinded(_diamondCut, _init, _calldata);\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n if (ds.facetAddresses.length != 0) {\\n uint256 time = ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\\n require(time != 0 && time <= block.timestamp, \\\"LibDiamond: delay not elapsed\\\");\\n } // Otherwise, this is the first instance of deployment and it can be set automatically\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length != 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(oldFacetAddress == address(0), \\\"LibDiamondCut: Can't add function that already exists\\\");\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length != 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(oldFacetAddress != _facetAddress, \\\"LibDiamondCut: Can't replace function with same function\\\");\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length != 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), \\\"LibDiamondCut: Remove facet address must be address(0)\\\");\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, \\\"LibDiamondCut: New facet has no code\\\");\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n require(_calldata.length == 0, \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\");\\n } else {\\n require(_calldata.length != 0, \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\");\\n if (_init != address(this)) {\\n enforceHasContractCode(_init, \\\"LibDiamondCut: _init address has no code\\\");\\n }\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length != 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize != 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x0ca55de8a7f4e2256b8b7a5e9ae6cca6d6ff850bbd9fd79542dfc4236871c6d8\",\"license\":\"MIT\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\n/**\\n * @title MathUtils library\\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\\n * differences between two uint256.\\n */\\nlibrary MathUtils {\\n /**\\n * @notice Compares a and b and returns true if the difference between a and b\\n * is less than 1 or equal to each other.\\n * @param a uint256 to compare with\\n * @param b uint256 to compare with\\n * @return True if the difference between a and b is less than 1 or equal,\\n * otherwise return false\\n */\\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\\n return (difference(a, b) <= 1);\\n }\\n\\n /**\\n * @notice Calculates absolute difference between a and b\\n * @param a uint256 to compare with\\n * @param b uint256 to compare with\\n * @return Difference between a and b\\n */\\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a > b) {\\n return a - b;\\n }\\n return b - a;\\n }\\n}\\n\",\"keccak256\":\"0xc0e55e78b6b5fec92fbf16f77f10103450f012394d995c8ace507f1abae29371\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {SafeERC20, IERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport {LPToken} from \\\"../helpers/LPToken.sol\\\";\\n\\nimport {AmplificationUtils} from \\\"./AmplificationUtils.sol\\\";\\nimport {MathUtils} from \\\"./MathUtils.sol\\\";\\n\\n/**\\n * @title SwapUtils library\\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\\n * Admin functions should be protected within contracts using this library.\\n */\\nlibrary SwapUtils {\\n using SafeERC20 for IERC20;\\n using MathUtils for uint256;\\n\\n /*** EVENTS ***/\\n\\n event TokenSwap(\\n bytes32 indexed key,\\n address indexed buyer,\\n uint256 tokensSold,\\n uint256 tokensBought,\\n uint128 soldId,\\n uint128 boughtId\\n );\\n event AddLiquidity(\\n bytes32 indexed key,\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\\n event RemoveLiquidityOne(\\n bytes32 indexed key,\\n address indexed provider,\\n uint256 lpTokenAmount,\\n uint256 lpTokenSupply,\\n uint256 boughtId,\\n uint256 tokensBought\\n );\\n event RemoveLiquidityImbalance(\\n bytes32 indexed key,\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\\n event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\\n\\n struct Swap {\\n // variables around the ramp management of A,\\n // the amplification coefficient * n * (n - 1)\\n // see https://www.curve.fi/stableswap-paper.pdf for details\\n bytes32 key;\\n uint256 initialA;\\n uint256 futureA;\\n uint256 initialATime;\\n uint256 futureATime;\\n // fee calculation\\n uint256 swapFee;\\n uint256 adminFee;\\n LPToken lpToken;\\n // contract references for all tokens being pooled\\n IERC20[] pooledTokens;\\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\\n uint256[] tokenPrecisionMultipliers;\\n // the pool balance of each token, in the token's precision\\n // the contract's actual token balance might differ\\n uint256[] balances;\\n // the admin fee balance of each token, in the token's precision\\n uint256[] adminFees;\\n }\\n\\n // Struct storing variables used in calculations in the\\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\\n struct CalculateWithdrawOneTokenDYInfo {\\n uint256 d0;\\n uint256 d1;\\n uint256 newY;\\n uint256 feePerToken;\\n uint256 preciseA;\\n }\\n\\n // Struct storing variables used in calculations in the\\n // {add,remove}Liquidity functions to avoid stack too deep errors\\n struct ManageLiquidityInfo {\\n uint256 d0;\\n uint256 d1;\\n uint256 d2;\\n uint256 preciseA;\\n LPToken lpToken;\\n uint256 totalSupply;\\n uint256[] balances;\\n uint256[] multipliers;\\n }\\n\\n // the precision all pools tokens will be converted to\\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\\n\\n // the denominator used to calculate admin and LP fees. For example, an\\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\\n uint256 internal constant FEE_DENOMINATOR = 1e10;\\n\\n // Max swap fee is 1% or 100bps of each swap\\n uint256 internal constant MAX_SWAP_FEE = 1e8;\\n\\n // Max adminFee is 100% of the swapFee\\n // adminFee does not add additional fee on top of swapFee\\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\\n // users but only on the earnings of LPs\\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\\n\\n // Constant value used as max loop limit\\n uint256 internal constant MAX_LOOP_LIMIT = 256;\\n\\n /*** VIEW & PURE FUNCTIONS ***/\\n\\n function _getAPrecise(Swap storage self) private view returns (uint256) {\\n return AmplificationUtils._getAPrecise(self);\\n }\\n\\n /**\\n * @notice Calculate the dy, the amount of selected token that user receives and\\n * the fee of withdrawing in one token\\n * @param tokenAmount the amount to withdraw in the pool's precision\\n * @param tokenIndex which token will be withdrawn\\n * @param self Swap struct to read from\\n * @return the amount of token user will receive\\n */\\n function calculateWithdrawOneToken(\\n Swap storage self,\\n uint256 tokenAmount,\\n uint8 tokenIndex\\n ) internal view returns (uint256) {\\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\\n self,\\n tokenAmount,\\n tokenIndex,\\n self.lpToken.totalSupply()\\n );\\n return availableTokenAmount;\\n }\\n\\n function _calculateWithdrawOneToken(\\n Swap storage self,\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 totalSupply\\n ) private view returns (uint256, uint256) {\\n uint256 dy;\\n uint256 newY;\\n uint256 currentY;\\n\\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\\n\\n // dy_0 (without fees)\\n // dy, dy_0 - dy\\n\\n uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\\n\\n return (dy, dySwapFee);\\n }\\n\\n /**\\n * @notice Calculate the dy of withdrawing in one token\\n * @param self Swap struct to read from\\n * @param tokenIndex which token will be withdrawn\\n * @param tokenAmount the amount to withdraw in the pools precision\\n * @return the d and the new y after withdrawing one token\\n */\\n function calculateWithdrawOneTokenDY(\\n Swap storage self,\\n uint8 tokenIndex,\\n uint256 tokenAmount,\\n uint256 totalSupply\\n )\\n internal\\n view\\n returns (\\n uint256,\\n uint256,\\n uint256\\n )\\n {\\n // Get the current D, then solve the stableswap invariant\\n // y_i for D - tokenAmount\\n uint256[] memory xp = _xp(self);\\n\\n require(tokenIndex < xp.length, \\\"index out of range\\\");\\n\\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\\n v.preciseA = _getAPrecise(self);\\n v.d0 = getD(xp, v.preciseA);\\n v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\\n\\n require(tokenAmount <= xp[tokenIndex], \\\"exceeds available\\\");\\n\\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\\n\\n uint256[] memory xpReduced = new uint256[](xp.length);\\n\\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\\n for (uint256 i; i < xp.length; ) {\\n uint256 xpi = xp[i];\\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\\n xpReduced[i] =\\n xpi -\\n ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\\n FEE_DENOMINATOR);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\\n dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\\n\\n return (dy, v.newY, xp[tokenIndex]);\\n }\\n\\n /**\\n * @notice Calculate the price of a token in the pool with given\\n * precision-adjusted balances and a particular D.\\n *\\n * @dev This is accomplished via solving the invariant iteratively.\\n * See the StableSwap paper and Curve.fi implementation for further details.\\n *\\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\\n * x_1**2 + b*x_1 = c\\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\\n *\\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\\n * @param tokenIndex Index of token we are calculating for.\\n * @param xp a precision-adjusted set of pool balances. Array should be\\n * the same cardinality as the pool.\\n * @param d the stableswap invariant\\n * @return the price of the token, in the same precision as in xp\\n */\\n function getYD(\\n uint256 a,\\n uint8 tokenIndex,\\n uint256[] memory xp,\\n uint256 d\\n ) internal pure returns (uint256) {\\n uint256 numTokens = xp.length;\\n require(tokenIndex < numTokens, \\\"Token not found\\\");\\n\\n uint256 c = d;\\n uint256 s;\\n uint256 nA = a * numTokens;\\n\\n for (uint256 i; i < numTokens; ) {\\n if (i != tokenIndex) {\\n s += xp[i];\\n c = (c * d) / (xp[i] * numTokens);\\n // If we were to protect the division loss we would have to keep the denominator separate\\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\\n // c = c * D * D * D * ... overflow!\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\\n\\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\\n uint256 yPrev;\\n uint256 y = d;\\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\\n yPrev = y;\\n y = ((y * y) + c) / ((y * 2) + b - d);\\n if (y.within1(yPrev)) {\\n return y;\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n revert(\\\"Approximation did not converge\\\");\\n }\\n\\n /**\\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\\n * as the pool.\\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\\n * See the StableSwap paper for details\\n * @return the invariant, at the precision of the pool\\n */\\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\\n uint256 numTokens = xp.length;\\n uint256 s;\\n for (uint256 i; i < numTokens; ) {\\n s += xp[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n if (s == 0) {\\n return 0;\\n }\\n\\n uint256 prevD;\\n uint256 d = s;\\n uint256 nA = a * numTokens;\\n\\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\\n uint256 dP = d;\\n for (uint256 j; j < numTokens; ) {\\n dP = (dP * d) / (xp[j] * numTokens);\\n // If we were to protect the division loss we would have to keep the denominator separate\\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\\n // dP = dP * D * D * D * ... overflow!\\n\\n unchecked {\\n ++j;\\n }\\n }\\n prevD = d;\\n d =\\n (((nA * s) / AmplificationUtils.A_PRECISION + dP * numTokens) * d) /\\n ((((nA - AmplificationUtils.A_PRECISION) * d) / AmplificationUtils.A_PRECISION + (numTokens + 1) * dP));\\n if (d.within1(prevD)) {\\n return d;\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\\n // function which does not rely on D.\\n revert(\\\"D does not converge\\\");\\n }\\n\\n /**\\n * @notice Given a set of balances and precision multipliers, return the\\n * precision-adjusted balances.\\n *\\n * @param balances an array of token balances, in their native precisions.\\n * These should generally correspond with pooled tokens.\\n *\\n * @param precisionMultipliers an array of multipliers, corresponding to\\n * the amounts in the balances array. When multiplied together they\\n * should yield amounts at the pool's precision.\\n *\\n * @return an array of amounts \\\"scaled\\\" to the pool's precision\\n */\\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\\n internal\\n pure\\n returns (uint256[] memory)\\n {\\n uint256 numTokens = balances.length;\\n require(numTokens == precisionMultipliers.length, \\\"mismatch multipliers\\\");\\n uint256[] memory xp = new uint256[](numTokens);\\n for (uint256 i; i < numTokens; ) {\\n xp[i] = balances[i] * precisionMultipliers[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n return xp;\\n }\\n\\n /**\\n * @notice Return the precision-adjusted balances of all tokens in the pool\\n * @param self Swap struct to read from\\n * @return the pool balances \\\"scaled\\\" to the pool's precision, allowing\\n * them to be more easily compared.\\n */\\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\\n return _xp(self.balances, self.tokenPrecisionMultipliers);\\n }\\n\\n /**\\n * @notice Get the virtual price, to help calculate profit\\n * @param self Swap struct to read from\\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\\n */\\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\\n uint256 d = getD(_xp(self), _getAPrecise(self));\\n LPToken lpToken = self.lpToken;\\n uint256 supply = lpToken.totalSupply();\\n if (supply != 0) {\\n return (d * (10**uint256(POOL_PRECISION_DECIMALS))) / supply;\\n }\\n return 0;\\n }\\n\\n /**\\n * @notice Calculate the new balances of the tokens given the indexes of the token\\n * that is swapped from (FROM) and the token that is swapped to (TO).\\n * This function is used as a helper function to calculate how much TO token\\n * the user should receive on swap.\\n *\\n * @param preciseA precise form of amplification coefficient\\n * @param tokenIndexFrom index of FROM token\\n * @param tokenIndexTo index of TO token\\n * @param x the new total amount of FROM token\\n * @param xp balances of the tokens in the pool\\n * @return the amount of TO token that should remain in the pool\\n */\\n function getY(\\n uint256 preciseA,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 x,\\n uint256[] memory xp\\n ) internal pure returns (uint256) {\\n uint256 numTokens = xp.length;\\n require(tokenIndexFrom != tokenIndexTo, \\\"compare token to itself\\\");\\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \\\"token not found\\\");\\n\\n uint256 d = getD(xp, preciseA);\\n uint256 c = d;\\n uint256 s;\\n uint256 nA = numTokens * preciseA;\\n\\n uint256 _x;\\n for (uint256 i; i < numTokens; ) {\\n if (i == tokenIndexFrom) {\\n _x = x;\\n } else if (i != tokenIndexTo) {\\n _x = xp[i];\\n } else {\\n unchecked {\\n ++i;\\n }\\n continue;\\n }\\n s += _x;\\n c = (c * d) / (_x * numTokens);\\n // If we were to protect the division loss we would have to keep the denominator separate\\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\\n // c = c * D * D * D * ... overflow!\\n\\n unchecked {\\n ++i;\\n }\\n }\\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\\n uint256 yPrev;\\n uint256 y = d;\\n\\n // iterative approximation\\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\\n yPrev = y;\\n y = ((y * y) + c) / ((y * 2) + b - d);\\n if (y.within1(yPrev)) {\\n return y;\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n revert(\\\"Approximation did not converge\\\");\\n }\\n\\n /**\\n * @notice Externally calculates a swap between two tokens.\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @return dy the number of tokens the user will get\\n */\\n function calculateSwap(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx\\n ) internal view returns (uint256 dy) {\\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\\n }\\n\\n /**\\n * @notice Externally calculates a swap between two tokens.\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dy the number of tokens to buy.\\n * @return dx the number of tokens the user have to transfer + fee\\n */\\n function calculateSwapInv(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy\\n ) internal view returns (uint256 dx) {\\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\\n }\\n\\n /**\\n * @notice Internally calculates a swap between two tokens.\\n *\\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\\n * using the token contracts.\\n *\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\\n * @return dyFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\\n */\\n function _calculateSwap(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256[] memory balances\\n ) internal view returns (uint256 dy, uint256 dyFee) {\\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\\n uint256[] memory xp = _xp(balances, multipliers);\\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \\\"index out of range\\\");\\n uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\\n dy = xp[tokenIndexTo] - y - 1;\\n dyFee = (dy * self.swapFee) / FEE_DENOMINATOR;\\n dy = (dy - dyFee) / multipliers[tokenIndexTo];\\n }\\n\\n /**\\n * @notice Internally calculates a swap between two tokens.\\n *\\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\\n * using the token contracts.\\n *\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\\n * @return dxFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\\n */\\n function _calculateSwapInv(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy,\\n uint256[] memory balances\\n ) internal view returns (uint256 dx, uint256 dxFee) {\\n require(tokenIndexFrom != tokenIndexTo, \\\"compare token to itself\\\");\\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\\n uint256[] memory xp = _xp(balances, multipliers);\\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \\\"index out of range\\\");\\n\\n uint256 a = _getAPrecise(self);\\n uint256 d0 = getD(xp, a);\\n\\n xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\\n dx = x - xp[tokenIndexFrom] + 1;\\n dxFee = (dx * self.swapFee) / FEE_DENOMINATOR;\\n dx = (dx + dxFee) / multipliers[tokenIndexFrom];\\n }\\n\\n /**\\n * @notice A simple method to calculate amount of each underlying\\n * tokens that is returned upon burning given amount of\\n * LP tokens\\n *\\n * @param amount the amount of LP tokens that would to be burned on\\n * withdrawal\\n * @return array of amounts of tokens user will receive\\n */\\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\\n }\\n\\n function _calculateRemoveLiquidity(\\n uint256[] memory balances,\\n uint256 amount,\\n uint256 totalSupply\\n ) internal pure returns (uint256[] memory) {\\n require(amount <= totalSupply, \\\"exceed total supply\\\");\\n\\n uint256 numBalances = balances.length;\\n uint256[] memory amounts = new uint256[](numBalances);\\n\\n for (uint256 i; i < numBalances; ) {\\n amounts[i] = (balances[i] * amount) / totalSupply;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n return amounts;\\n }\\n\\n /**\\n * @notice A simple method to calculate prices from deposits or\\n * withdrawals, excluding fees but including slippage. This is\\n * helpful as an input into the various \\\"min\\\" parameters on calls\\n * to fight front-running\\n *\\n * @dev This shouldn't be used outside frontends for user estimates.\\n *\\n * @param self Swap struct to read from\\n * @param amounts an array of token amounts to deposit or withdrawal,\\n * corresponding to pooledTokens. The amount should be in each\\n * pooled token's native precision. If a token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @param deposit whether this is a deposit or a withdrawal\\n * @return if deposit was true, total amount of lp token that will be minted and if\\n * deposit was false, total amount of lp token that will be burned\\n */\\n function calculateTokenAmount(\\n Swap storage self,\\n uint256[] calldata amounts,\\n bool deposit\\n ) internal view returns (uint256) {\\n uint256 a = _getAPrecise(self);\\n uint256[] memory balances = self.balances;\\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\\n\\n uint256 numBalances = balances.length;\\n uint256 d0 = getD(_xp(balances, multipliers), a);\\n for (uint256 i; i < numBalances; ) {\\n if (deposit) {\\n balances[i] = balances[i] + amounts[i];\\n } else {\\n balances[i] = balances[i] - amounts[i];\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n uint256 d1 = getD(_xp(balances, multipliers), a);\\n uint256 totalSupply = self.lpToken.totalSupply();\\n\\n if (deposit) {\\n return ((d1 - d0) * totalSupply) / d0;\\n } else {\\n return ((d0 - d1) * totalSupply) / d0;\\n }\\n }\\n\\n /**\\n * @notice return accumulated amount of admin fees of the token with given index\\n * @param self Swap struct to read from\\n * @param index Index of the pooled token\\n * @return admin balance in the token's precision\\n */\\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\\n require(index < self.pooledTokens.length, \\\"index out of range\\\");\\n return self.adminFees[index];\\n }\\n\\n /**\\n * @notice internal helper function to calculate fee per token multiplier used in\\n * swap fee calculations\\n * @param swapFee swap fee for the tokens\\n * @param numTokens number of tokens pooled\\n */\\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\\n return (swapFee * numTokens) / ((numTokens - 1) * 4);\\n }\\n\\n /*** STATE MODIFYING FUNCTIONS ***/\\n\\n /**\\n * @notice swap two tokens in the pool\\n * @param self Swap struct to read from and write to\\n * @param tokenIndexFrom the token the user wants to sell\\n * @param tokenIndexTo the token the user wants to buy\\n * @param dx the amount of tokens the user wants to sell\\n * @param minDy the min amount the user would like to receive, or revert.\\n * @return amount of token user received on swap\\n */\\n function swap(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy\\n ) internal returns (uint256) {\\n {\\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\\n require(dx <= tokenFrom.balanceOf(msg.sender), \\\"swap more than you own\\\");\\n // Transfer tokens first to see if a fee was charged on transfer\\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\\n\\n // Use the actual transferred amount for AMM math\\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \\\"no fee token support\\\");\\n }\\n\\n uint256 dy;\\n uint256 dyFee;\\n uint256[] memory balances = self.balances;\\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\\n require(dy >= minDy, \\\"dy < minDy\\\");\\n\\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\\n if (dyAdminFee != 0) {\\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\\n }\\n\\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dy;\\n }\\n\\n /**\\n * @notice swap two tokens in the pool\\n * @param self Swap struct to read from and write to\\n * @param tokenIndexFrom the token the user wants to sell\\n * @param tokenIndexTo the token the user wants to buy\\n * @param dy the amount of tokens the user wants to buy\\n * @param maxDx the max amount the user would like to send.\\n * @return amount of token user have to transfer on swap\\n */\\n function swapOut(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy,\\n uint256 maxDx\\n ) internal returns (uint256) {\\n require(dy <= self.balances[tokenIndexTo], \\\">pool balance\\\");\\n\\n uint256 dx;\\n uint256 dxFee;\\n uint256[] memory balances = self.balances;\\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\\n require(dx <= maxDx, \\\"dx > maxDx\\\");\\n\\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\\n if (dxAdminFee != 0) {\\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\\n }\\n\\n {\\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\\n require(dx <= tokenFrom.balanceOf(msg.sender), \\\"more than you own\\\");\\n // Transfer tokens first to see if a fee was charged on transfer\\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\\n\\n // Use the actual transferred amount for AMM math\\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \\\"not support fee token\\\");\\n }\\n\\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dx;\\n }\\n\\n /**\\n * @notice swap two tokens in the pool internally\\n * @param self Swap struct to read from and write to\\n * @param tokenIndexFrom the token the user wants to sell\\n * @param tokenIndexTo the token the user wants to buy\\n * @param dx the amount of tokens the user wants to sell\\n * @param minDy the min amount the user would like to receive, or revert.\\n * @return amount of token user received on swap\\n */\\n function swapInternal(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy\\n ) internal returns (uint256) {\\n require(dx <= self.balances[tokenIndexFrom], \\\"more than pool balance\\\");\\n\\n uint256 dy;\\n uint256 dyFee;\\n uint256[] memory balances = self.balances;\\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\\n require(dy >= minDy, \\\"dy < minDy\\\");\\n\\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\\n\\n if (dyAdminFee != 0) {\\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\\n }\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dy;\\n }\\n\\n /**\\n * @notice Should get exact amount out of AMM for asset put in\\n */\\n function swapInternalOut(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy,\\n uint256 maxDx\\n ) internal returns (uint256) {\\n require(dy <= self.balances[tokenIndexTo], \\\"more than pool balance\\\");\\n\\n uint256 dx;\\n uint256 dxFee;\\n uint256[] memory balances = self.balances;\\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\\n require(dx <= maxDx, \\\"dx > maxDx\\\");\\n\\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\\n\\n if (dxAdminFee != 0) {\\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\\n }\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dx;\\n }\\n\\n /**\\n * @notice Add liquidity to the pool\\n * @param self Swap struct to read from and write to\\n * @param amounts the amounts of each token to add, in their native precision\\n * @param minToMint the minimum LP tokens adding this amount of liquidity\\n * should mint, otherwise revert. Handy for front-running mitigation\\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\\n * @return amount of LP token user received\\n */\\n function addLiquidity(\\n Swap storage self,\\n uint256[] memory amounts,\\n uint256 minToMint\\n ) internal returns (uint256) {\\n uint256 numTokens = self.pooledTokens.length;\\n require(amounts.length == numTokens, \\\"mismatch pooled tokens\\\");\\n\\n // current state\\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\\n 0,\\n 0,\\n 0,\\n _getAPrecise(self),\\n self.lpToken,\\n 0,\\n self.balances,\\n self.tokenPrecisionMultipliers\\n );\\n v.totalSupply = v.lpToken.totalSupply();\\n if (v.totalSupply != 0) {\\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\\n }\\n\\n uint256[] memory newBalances = new uint256[](numTokens);\\n\\n for (uint256 i; i < numTokens; ) {\\n require(v.totalSupply != 0 || amounts[i] != 0, \\\"!supply all tokens\\\");\\n\\n // Transfer tokens first to see if a fee was charged on transfer\\n if (amounts[i] != 0) {\\n IERC20 token = self.pooledTokens[i];\\n uint256 beforeBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), amounts[i]);\\n\\n // Update the amounts[] with actual transfer amount\\n amounts[i] = token.balanceOf(address(this)) - beforeBalance;\\n }\\n\\n newBalances[i] = v.balances[i] + amounts[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // invariant after change\\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\\n require(v.d1 > v.d0, \\\"D should increase\\\");\\n\\n // updated to reflect fees and calculate the user's LP tokens\\n v.d2 = v.d1;\\n uint256[] memory fees = new uint256[](numTokens);\\n\\n if (v.totalSupply != 0) {\\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\\n for (uint256 i; i < numTokens; ) {\\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\\n fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / FEE_DENOMINATOR;\\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\\n self.balances[i] = newBalances[i] - adminFee;\\n self.adminFees[i] = self.adminFees[i] + adminFee;\\n newBalances[i] = newBalances[i] - fees[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\\n } else {\\n // the initial depositor doesn't pay fees\\n self.balances = newBalances;\\n }\\n\\n uint256 toMint;\\n if (v.totalSupply == 0) {\\n toMint = v.d1;\\n } else {\\n toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\\n }\\n\\n require(toMint >= minToMint, \\\"mint < min\\\");\\n\\n // mint the user's LP tokens\\n v.lpToken.mint(msg.sender, toMint);\\n\\n emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\\n\\n return toMint;\\n }\\n\\n /**\\n * @notice Burn LP tokens to remove liquidity from the pool.\\n * @dev Liquidity can always be removed, even when the pool is paused.\\n * @param self Swap struct to read from and write to\\n * @param amount the amount of LP tokens to burn\\n * @param minAmounts the minimum amounts of each token in the pool\\n * acceptable for this burn. Useful as a front-running mitigation\\n * @return amounts of tokens the user received\\n */\\n function removeLiquidity(\\n Swap storage self,\\n uint256 amount,\\n uint256[] calldata minAmounts\\n ) internal returns (uint256[] memory) {\\n LPToken lpToken = self.lpToken;\\n require(amount <= lpToken.balanceOf(msg.sender), \\\">LP.balanceOf\\\");\\n uint256 numTokens = self.pooledTokens.length;\\n require(minAmounts.length == numTokens, \\\"mismatch poolTokens\\\");\\n\\n uint256[] memory balances = self.balances;\\n uint256 totalSupply = lpToken.totalSupply();\\n\\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\\n\\n uint256 numAmounts = amounts.length;\\n for (uint256 i; i < numAmounts; ) {\\n require(amounts[i] >= minAmounts[i], \\\"amounts[i] < minAmounts[i]\\\");\\n self.balances[i] = balances[i] - amounts[i];\\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n lpToken.burnFrom(msg.sender, amount);\\n\\n emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\\n\\n return amounts;\\n }\\n\\n /**\\n * @notice Remove liquidity from the pool all in one token.\\n * @param self Swap struct to read from and write to\\n * @param tokenAmount the amount of the lp tokens to burn\\n * @param tokenIndex the index of the token you want to receive\\n * @param minAmount the minimum amount to withdraw, otherwise revert\\n * @return amount chosen token that user received\\n */\\n function removeLiquidityOneToken(\\n Swap storage self,\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 minAmount\\n ) internal returns (uint256) {\\n LPToken lpToken = self.lpToken;\\n\\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \\\">LP.balanceOf\\\");\\n uint256 numTokens = self.pooledTokens.length;\\n require(tokenIndex < numTokens, \\\"not found\\\");\\n\\n uint256 totalSupply = lpToken.totalSupply();\\n\\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\\n\\n require(dy >= minAmount, \\\"dy < minAmount\\\");\\n\\n uint256 adminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR;\\n self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\\n if (adminFee != 0) {\\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\\n }\\n lpToken.burnFrom(msg.sender, tokenAmount);\\n self.pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\\n\\n emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\\n\\n return dy;\\n }\\n\\n /**\\n * @notice Remove liquidity from the pool, weighted differently than the\\n * pool's current balances.\\n *\\n * @param self Swap struct to read from and write to\\n * @param amounts how much of each token to withdraw\\n * @param maxBurnAmount the max LP token provider is willing to pay to\\n * remove liquidity. Useful as a front-running mitigation.\\n * @return actual amount of LP tokens burned in the withdrawal\\n */\\n function removeLiquidityImbalance(\\n Swap storage self,\\n uint256[] memory amounts,\\n uint256 maxBurnAmount\\n ) internal returns (uint256) {\\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\\n 0,\\n 0,\\n 0,\\n _getAPrecise(self),\\n self.lpToken,\\n 0,\\n self.balances,\\n self.tokenPrecisionMultipliers\\n );\\n v.totalSupply = v.lpToken.totalSupply();\\n\\n uint256 numTokens = self.pooledTokens.length;\\n uint256 numAmounts = amounts.length;\\n require(numAmounts == numTokens, \\\"mismatch pool tokens\\\");\\n\\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \\\">LP.balanceOf\\\");\\n\\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\\n uint256[] memory fees = new uint256[](numTokens);\\n {\\n uint256[] memory balances1 = new uint256[](numTokens);\\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\\n for (uint256 i; i < numTokens; ) {\\n require(v.balances[i] >= amounts[i], \\\"withdraw more than available\\\");\\n\\n unchecked {\\n balances1[i] = v.balances[i] - amounts[i];\\n ++i;\\n }\\n }\\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\\n\\n for (uint256 i; i < numTokens; ) {\\n {\\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\\n uint256 difference = idealBalance.difference(balances1[i]);\\n fees[i] = (feePerToken * difference) / FEE_DENOMINATOR;\\n }\\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\\n self.balances[i] = balances1[i] - adminFee;\\n self.adminFees[i] = self.adminFees[i] + adminFee;\\n balances1[i] = balances1[i] - fees[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\\n }\\n uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\\n require(tokenAmount != 0, \\\"!zero amount\\\");\\n tokenAmount = tokenAmount + 1;\\n\\n require(tokenAmount <= maxBurnAmount, \\\"tokenAmount > maxBurnAmount\\\");\\n\\n v.lpToken.burnFrom(msg.sender, tokenAmount);\\n\\n for (uint256 i; i < numTokens; ) {\\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\\n\\n return tokenAmount;\\n }\\n\\n /**\\n * @notice withdraw all admin fees to a given address\\n * @param self Swap struct to withdraw fees from\\n * @param to Address to send the fees to\\n */\\n function withdrawAdminFees(Swap storage self, address to) internal {\\n uint256 numTokens = self.pooledTokens.length;\\n for (uint256 i; i < numTokens; ) {\\n IERC20 token = self.pooledTokens[i];\\n uint256 balance = self.adminFees[i];\\n if (balance != 0) {\\n self.adminFees[i] = 0;\\n token.safeTransfer(to, balance);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Sets the admin fee\\n * @dev adminFee cannot be higher than 100% of the swap fee\\n * @param self Swap struct to update\\n * @param newAdminFee new admin fee to be applied on future transactions\\n */\\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\\n require(newAdminFee <= MAX_ADMIN_FEE, \\\"too high\\\");\\n self.adminFee = newAdminFee;\\n\\n emit NewAdminFee(self.key, newAdminFee);\\n }\\n\\n /**\\n * @notice update the swap fee\\n * @dev fee cannot be higher than 1% of each swap\\n * @param self Swap struct to update\\n * @param newSwapFee new swap fee to be applied on future transactions\\n */\\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\\n require(newSwapFee <= MAX_SWAP_FEE, \\\"too high\\\");\\n self.swapFee = newSwapFee;\\n\\n emit NewSwapFee(self.key, newSwapFee);\\n }\\n\\n /**\\n * @notice Check if this stableswap pool exists and is valid (i.e. has been\\n * initialized and tokens have been added).\\n * @return bool true if this stableswap pool is valid, false if not.\\n */\\n function exists(Swap storage self) internal view returns (bool) {\\n return self.pooledTokens.length != 0;\\n }\\n}\\n\",\"keccak256\":\"0x3da6aa3cd7cf97886db9958cbb174b8edaf7771aebce5da2a8d87e993a8301fa\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport {IOutbox} from \\\"./IOutbox.sol\\\";\\n\\n/**\\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\\n * allows an admin to call `setXAppConnectionManager` to update the underlying\\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\\n *\\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\\n * will interface with.\\n */\\ninterface IConnectorManager {\\n /**\\n * @notice Get the local inbox contract from the xAppConnectionManager\\n * @return The local inbox contract\\n * @dev The local inbox contract is a SpokeConnector with AMBs, and a\\n * Home contract with nomad\\n */\\n function home() external view returns (IOutbox);\\n\\n /**\\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\\n * @return True if _potentialReplica is an enrolled Replica\\n */\\n function isReplica(address _potentialReplica) external view returns (bool);\\n\\n /**\\n * @notice Get the local domain from the xAppConnectionManager\\n * @return The local domain\\n */\\n function localDomain() external view returns (uint32);\\n}\\n\",\"keccak256\":\"0xa2c9a88a7b76a89615fe199d8a78878e5deb8dd13b036a86b575d31966beab1a\",\"license\":\"MIT OR Apache-2.0\"},\"@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity 0.8.15;\\n\\n/**\\n * @notice Interface for all contracts sending messages originating on their\\n * current domain.\\n *\\n * @dev These are the Home.sol interface methods used by the `Router`\\n * and exposed via `home()` on the `XAppConnectionClient`\\n */\\ninterface IOutbox {\\n /**\\n * @notice Emitted when a new message is added to an outbound message merkle root\\n * @param leafIndex Index of message's leaf in merkle tree\\n * @param destinationAndNonce Destination and destination-specific\\n * nonce combined in single field ((destination << 32) & nonce)\\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\\n * @param committedRoot the latest notarized root submitted in the last signed Update\\n * @param message Raw bytes of message\\n */\\n event Dispatch(\\n bytes32 indexed messageHash,\\n uint256 indexed leafIndex,\\n uint64 indexed destinationAndNonce,\\n bytes32 committedRoot,\\n bytes message\\n );\\n\\n /**\\n * @notice Dispatch the message it to the destination domain & recipient\\n * @dev Format the message, insert its hash into Merkle tree,\\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\\n * @param _destinationDomain Domain of destination chain\\n * @param _recipientAddress Address of recipient on destination chain as bytes32\\n * @param _messageBody Raw bytes content of message\\n * @return bytes32 The leaf added to the tree\\n */\\n function dispatch(\\n uint32 _destinationDomain,\\n bytes32 _recipientAddress,\\n bytes memory _messageBody\\n ) external returns (bytes32);\\n}\\n\",\"keccak256\":\"0xe6a213bd3c9e0c4dcf0e982cdef2a6a613a49b7bca3d6ad662c179e509de6c2b\",\"license\":\"MIT OR Apache-2.0\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.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 IERC20Upgradeable {\\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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\\n function __ERC20Burnable_init() internal onlyInitializing {\\n }\\n\\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xea2c6f9d434127bf36b1e3e5ebaaf6d28a64dbaeea560508e570014e905a5ad2\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\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\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 > 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 >= 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 functionCall(target, data, \\\"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(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) 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(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) 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 >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // Look for revert reason and bubble it up if present\\n if (returndata.length > 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}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/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\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= 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 > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 > 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 >= 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 functionCall(target, data, \\\"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(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) 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(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) 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 >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // Look for revert reason and bubble it up if present\\n if (returndata.length > 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}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"solidity/contracts/bridges/BridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IBridgeReceiverAdapter.sol';\\n\\nabstract contract BridgeReceiverAdapter is IBridgeReceiverAdapter {\\n /// @inheritdoc IBridgeReceiverAdapter\\n IDataReceiver public immutable dataReceiver;\\n\\n constructor(IDataReceiver _dataReceiver) {\\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\\n dataReceiver = _dataReceiver;\\n }\\n\\n function _addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) internal {\\n dataReceiver.addObservations(_observationsData, _poolSalt, _poolNonce);\\n }\\n}\\n\",\"keccak256\":\"0x9242c7b33b40003d937f4facdc0aeb0e121ad4574c1191fe0d543eec0c3552b0\",\"license\":\"MIT\"},\"solidity/contracts/bridges/ConnextReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {BridgeReceiverAdapter} from './BridgeReceiverAdapter.sol';\\nimport {IConnext, IXReceiver, IConnextReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IConnextReceiverAdapter.sol';\\n\\ncontract ConnextReceiverAdapter is IConnextReceiverAdapter, BridgeReceiverAdapter {\\n /// @inheritdoc IConnextReceiverAdapter\\n IConnext public immutable connext;\\n\\n /// @inheritdoc IConnextReceiverAdapter\\n address public immutable source;\\n\\n /// @inheritdoc IConnextReceiverAdapter\\n uint32 public immutable originDomain;\\n\\n constructor(\\n IDataReceiver _dataReceiver,\\n IConnext _connext,\\n address _source,\\n uint32 _originDomain\\n ) BridgeReceiverAdapter(_dataReceiver) {\\n if (address(_connext) == address(0) || _source == address(0)) revert ZeroAddress();\\n connext = _connext;\\n source = _source;\\n originDomain = _originDomain;\\n }\\n\\n /// @inheritdoc IXReceiver\\n function xReceive(\\n bytes32, // _transferId\\n uint256, // _amount\\n address, // _asset\\n address _originSender,\\n uint32 _origin,\\n bytes memory _callData\\n ) external onlyExecutor(_originSender, _origin) returns (bytes memory) {\\n (IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, uint24 _poolNonce) = abi.decode(\\n _callData,\\n (IOracleSidechain.ObservationData[], bytes32, uint24)\\n );\\n\\n _addObservations(_observationsData, _poolSalt, _poolNonce);\\n }\\n\\n modifier onlyExecutor(address _originSender, uint32 _originDomain) {\\n if (msg.sender != address(connext) || _originSender != source || _originDomain != originDomain) revert UnauthorizedCaller();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x7895c6ee2da8eca15d2960a39bec9a7c0093bd33d094f0e0c751e96231951968\",\"license\":\"MIT\"},\"solidity/interfaces/IDataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleFactory} from './IOracleFactory.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\\n\\ninterface IDataReceiver is IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @notice Tracks already deployed oracles\\n /// @param _poolSalt The identifier of the oracle\\n /// @return _deployedOracle The address of the correspondant Oracle\\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\\n\\n /// @notice Tracks the whitelisting of bridge adapters\\n /// @param _adapter Address of the bridge adapter to consult\\n /// @return _isAllowed Whether a bridge adapter is whitelisted\\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a broadcast observation is succesfully processed\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _observationsData Array of tuples containing the dataset\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsAdded(\\n bytes32 indexed _poolSalt,\\n uint24 _poolNonce,\\n IOracleSidechain.ObservationData[] _observationsData,\\n address _receiverAdapter\\n );\\n\\n /// @notice Emitted when a new adapter whitelisting rule is set\\n /// @param _adapter Address of the adapter\\n /// @param _isAllowed New whitelisting status\\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\\n\\n // ERRORS\\n\\n /// @notice Thrown when the broadcast nonce is incorrect\\n error ObservationsNotWritable();\\n\\n /// @notice Thrown when a not-whitelisted adapter triggers an update\\n error UnallowedAdapter();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows whitelisted bridge adapters to push a broadcast\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _poolNonce Nonce of the observation broadcast\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external;\\n\\n /// @notice Allows governance to set an adapter whitelisted state\\n /// @param _receiverAdapter Address of the adapter\\n /// @param _isWhitelisted New whitelisting status\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\\n\\n /// @notice Allows governance to batch set adapters whitelisted state\\n /// @param _receiverAdapters Array of addresses of the adapter\\n /// @param _isWhitelisted Array of whitelisting status for each address\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\\n}\\n\",\"keccak256\":\"0x7970e1941b72624c5d92462a8648ffb95ee99e4132152cd720e13b45039df67c\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IDataReceiver} from './IDataReceiver.sol';\\n\\ninterface IOracleFactory is IGovernable {\\n // STRUCTS\\n\\n struct OracleParameters {\\n bytes32 poolSalt; // Identifier of the pool and oracle\\n uint24 poolNonce; // Initial nonce of the deployed pool\\n uint16 cardinality; // Initial cardinality of the deployed pool\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\\n //solhint-disable-next-line func-name-mixedcase\\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\\n\\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /// @return _poolSalt The id of both the oracle and the pool\\n /// @return _poolNonce The initial nonce of the pool data\\n /// @return _cardinality The size of the observations memory storage\\n function oracleParameters()\\n external\\n view\\n returns (\\n bytes32 _poolSalt,\\n uint24 _poolNonce,\\n uint16 _cardinality\\n );\\n\\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function initialCardinality() external view returns (uint16 _initialCardinality);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new oracle is deployed\\n /// @param _poolSalt The id of both the oracle and the pool\\n /// @param _oracle The address of the deployed oracle\\n /// @param _initialNonce The initial nonce of the pool data\\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\\n\\n /// @notice Emitted when a new DataReceiver is set\\n /// @param _dataReceiver The address of the new DataReceiver\\n event DataReceiverSet(IDataReceiver _dataReceiver);\\n\\n /// @notice Emitted when a new initial oracle cardinality is set\\n /// @param _initialCardinality The initial length of the observationCardinality array\\n event InitialCardinalitySet(uint16 _initialCardinality);\\n\\n // ERRORS\\n\\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\\n error OnlyDataReceiver();\\n\\n // FUNCTIONS\\n\\n /// @notice Deploys a new oracle given an inputted salt\\n /// @dev Requires that the salt has not been deployed before\\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\\n /// @return _oracle The address of the newly deployed oracle\\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\\n\\n /// @notice Allows governor to set a new allowed dataReceiver\\n /// @dev Will disallow the previous dataReceiver\\n /// @param _dataReceiver The address of the new allowed dataReceiver\\n function setDataReceiver(IDataReceiver _dataReceiver) external;\\n\\n /// @notice Allows governor to set a new initial cardinality for new oracles\\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function setInitialCardinality(uint16 _initialCardinality) external;\\n\\n /// @notice Overrides UniV3Factory getPool mapping\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _oracle The oracle address\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle);\\n\\n /// @notice Tracks the addresses of the oracle by poolSalt\\n /// @param _poolSalt Identifier of both the pool and the oracle\\n /// @return _oracle The address (if deployed) of the correspondant oracle\\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\\n\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _poolSalt Pool salt for inquired parameters\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (bytes32 _poolSalt);\\n}\\n\",\"keccak256\":\"0xc32bfc32a274923ce1a089acc024396e702ae354773f0ac0a683e43ded904954\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleFactory} from './IOracleFactory.sol';\\n\\ninterface IOracleSidechain {\\n // STRUCTS\\n\\n struct ObservationData {\\n uint32 blockTimestamp;\\n int24 tick;\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function factory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @return _token0 The mainnet address of the Token0 of the oracle\\n function token0() external view returns (address _token0);\\n\\n /// @return _token1 The mainnet address of the Token1 of the oracle\\n function token1() external view returns (address _token1);\\n\\n /// @return _fee The fee identifier of the pool\\n function fee() external view returns (uint24 _fee);\\n\\n /// @return _poolSalt The identifier of both the pool and the oracle\\n function poolSalt() external view returns (bytes32 _poolSalt);\\n\\n /// @return _poolNonce Last recorded nonce of the pool history\\n function poolNonce() external view returns (uint24 _poolNonce);\\n\\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\\n /// @return _tick Used to maintain compatibility with Uniswap V3\\n /// @return _observationIndex The index of the last oracle observation that was written,\\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\\n /// @return _unlocked Used to track if a pool information was already verified\\n function slot0()\\n external\\n view\\n returns (\\n uint160 _sqrtPriceX96,\\n int24 _tick,\\n uint16 _observationIndex,\\n uint16 _observationCardinality,\\n uint16 _observationCardinalityNext,\\n uint8 _feeProtocol,\\n bool _unlocked\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param _index The element of the observations array to fetch\\n /// @return _blockTimestamp The timestamp of the observation,\\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// @return _initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 _index)\\n external\\n view\\n returns (\\n uint32 _blockTimestamp,\\n int56 _tickCumulative,\\n uint160 _secondsPerLiquidityCumulativeX128,\\n bool _initialized\\n );\\n\\n // EVENTS\\n\\n /// @notice Emitted when the pool information is verified\\n /// @param _poolSalt Identifier of the pool and the oracle\\n /// @param _token0 The contract address of either token0 or token1\\n /// @param _token1 The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\\n\\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param _tick The log base 1.0001 of price of the pool after the swap\\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\\n\\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\\n\\n // ERRORS\\n\\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\\n error AI();\\n\\n /// @notice Thrown if the pool info does not correspond to the pool salt\\n error InvalidPool();\\n\\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\\n error OnlyDataReceiver();\\n\\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\\n error OnlyFactory();\\n\\n // FUNCTIONS\\n\\n /// @notice Permisionless method to verify token0, token1 and fee\\n /// @dev Before verified, token0 and token1 views will return address(0)\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external;\\n\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\\n\\n /// @notice Permisioned method to push a dataset to update\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolNonce Nonce of the observation broadcast\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\\n\\n /// @notice Permisioned method to increase the cardinalityNext value\\n /// @param _observationCardinalityNext The new next length of the observations array\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa90206e3de00ad866b7f4792ce29220ee0ca561d59629ba638a31c4d6fd3941b\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IBridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport {IDataReceiver} from '../IDataReceiver.sol';\\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\\n\\ninterface IBridgeReceiverAdapter is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @notice Gets the address of the DataReceiver contract\\n /// @return _dataReceiver Address of the DataReceiver contract\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /* NOTE: callback methods should be here declared */\\n}\\n\",\"keccak256\":\"0x49e5c9c6a28521933a3f2b01a529fbae9aac1edd71dbe904586a2f06148b1974\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IConnextReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from './IBridgeReceiverAdapter.sol';\\n\\ninterface IConnextReceiverAdapter is IXReceiver, IBridgeReceiverAdapter {\\n // STATE VARIABLES\\n\\n /// @notice Gets the ConnextHandler contract on this domain\\n /// @return _connext Address of the ConnextHandler contract\\n function connext() external view returns (IConnext _connext);\\n\\n /// @notice Gets the DAO that is expected as the xcaller\\n /// @return _originContract Address of the xcaller contract\\n function source() external view returns (address _originContract);\\n\\n /// @notice Gets the origin domain id\\n /// @return _originDomain The origin domain id\\n function originDomain() external view returns (uint32 _originDomain);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a caller is not authorized\\n error UnauthorizedCaller();\\n}\\n\",\"keccak256\":\"0x382097cdc88bb383c1aec1ec6ebddf9e6ba5b87b405650432e85616acd03e218\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x61010060405234801561001157600080fd5b506040516107e33803806107e3833981016040819052610030916100d3565b836001600160a01b0381166100585760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b039081166080528316158061007b57506001600160a01b038216155b156100995760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0392831660a052911660c05263ffffffff1660e0525061013b565b6001600160a01b03811681146100d057600080fd5b50565b600080600080608085870312156100e957600080fd5b84516100f4816100bb565b6020860151909450610105816100bb565b6040860151909350610116816100bb565b606086015190925063ffffffff8116811461013057600080fd5b939692955090935050565b60805160a05160c05160e05161065661018d6000396000818160a501526101c00152600081816061015261018301526000818160e10152610159015260008181610108015261025d01526106566000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806367e828bf1461005c578063cee85d7e146100a0578063de4b0548146100dc578063e804778814610103578063fd614f411461012a575b600080fd5b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c77f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610097565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b61013d61013836600461036e565b61014a565b6040516100979190610449565b60608383336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806101b857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b806101ef57507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1614155b1561020d57604051635c427cd960e01b815260040160405180910390fd5b60008060008680602001905181019061022691906104b1565b925092509250610237838383610246565b50505050509695505050505050565b60405163d34ad40960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d34ad40990610296908690869086906004016105b5565b600060405180830381600087803b1580156102b057600080fd5b505af11580156102c4573d6000803e3d6000fd5b50505050505050565b80356001600160a01b03811681146102e457600080fd5b919050565b63ffffffff811681146102fb57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610337576103376102fe565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610366576103666102fe565b604052919050565b60008060008060008060c0878903121561038757600080fd5b86359550602080880135955061039f604089016102cd565b94506103ad606089016102cd565b935060808801356103bd816102e9565b925060a088013567ffffffffffffffff808211156103da57600080fd5b818a0191508a601f8301126103ee57600080fd5b813581811115610400576104006102fe565b610412601f8201601f1916850161033d565b91508082528b8482850101111561042857600080fd5b80848401858401376000848284010152508093505050509295509295509295565b600060208083528351808285015260005b818110156104765785810183015185820160400152820161045a565b81811115610488576000604083870101525b50601f01601f1916929092016040019392505050565b805162ffffff811681146102e457600080fd5b6000806000606084860312156104c657600080fd5b835167ffffffffffffffff808211156104de57600080fd5b818601915086601f8301126104f257600080fd5b8151602082821115610506576105066102fe565b610514818360051b0161033d565b828152818101935060069290921b84018101918983111561053457600080fd5b938101935b82851015610592576040858b0312156105525760008081fd5b61055a610314565b8551610565816102e9565b815285830151600281900b811461057c5760008081fd5b8184015284526040949094019392810192610539565b80975050808801519550505050506105ac6040850161049e565b90509250925092565b606080825284519082018190526000906020906080840190828801845b82811015610602578151805163ffffffff16855285015160020b85850152604090930192908401906001016105d2565b505050908301949094525062ffffff9190911660409091015291905056fea2646970667358221220b50c64cc61a532dc4150407ac0d076306c79ec1e18aee6544e4176cb24c4008064736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c806367e828bf1461005c578063cee85d7e146100a0578063de4b0548146100dc578063e804778814610103578063fd614f411461012a575b600080fd5b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c77f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610097565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b61013d61013836600461036e565b61014a565b6040516100979190610449565b60608383336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806101b857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b806101ef57507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1614155b1561020d57604051635c427cd960e01b815260040160405180910390fd5b60008060008680602001905181019061022691906104b1565b925092509250610237838383610246565b50505050509695505050505050565b60405163d34ad40960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d34ad40990610296908690869086906004016105b5565b600060405180830381600087803b1580156102b057600080fd5b505af11580156102c4573d6000803e3d6000fd5b50505050505050565b80356001600160a01b03811681146102e457600080fd5b919050565b63ffffffff811681146102fb57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610337576103376102fe565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610366576103666102fe565b604052919050565b60008060008060008060c0878903121561038757600080fd5b86359550602080880135955061039f604089016102cd565b94506103ad606089016102cd565b935060808801356103bd816102e9565b925060a088013567ffffffffffffffff808211156103da57600080fd5b818a0191508a601f8301126103ee57600080fd5b813581811115610400576104006102fe565b610412601f8201601f1916850161033d565b91508082528b8482850101111561042857600080fd5b80848401858401376000848284010152508093505050509295509295509295565b600060208083528351808285015260005b818110156104765785810183015185820160400152820161045a565b81811115610488576000604083870101525b50601f01601f1916929092016040019392505050565b805162ffffff811681146102e457600080fd5b6000806000606084860312156104c657600080fd5b835167ffffffffffffffff808211156104de57600080fd5b818601915086601f8301126104f257600080fd5b8151602082821115610506576105066102fe565b610514818360051b0161033d565b828152818101935060069290921b84018101918983111561053457600080fd5b938101935b82851015610592576040858b0312156105525760008081fd5b61055a610314565b8551610565816102e9565b815285830151600281900b811461057c5760008081fd5b8184015284526040949094019392810192610539565b80975050808801519550505050506105ac6040850161049e565b90509250925092565b606080825284519082018190526000906020906080840190828801845b82811015610602578151805163ffffffff16855285015160020b85850152604090930192908401906001016105d2565b505050908301949094525062ffffff9190911660409091015291905056fea2646970667358221220b50c64cc61a532dc4150407ac0d076306c79ec1e18aee6544e4176cb24c4008064736f6c634300080f0033", + "numDeployments": 1, + "solcInputHash": "1ffcc3895a1a8980b9e58deee89219d1", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"},{\"internalType\":\"contract IConnext\",\"name\":\"_connext\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_source\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_originDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"connext\",\"outputs\":[{\"internalType\":\"contract IConnext\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dataReceiver\",\"outputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"originDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"source\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_originSender\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_callData\",\"type\":\"bytes\"}],\"name\":\"xReceive\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"connext\":{\"return\":\"Address of the ConnextHandler contract\",\"returns\":{\"_0\":\"Address of the ConnextHandler contract\"}},\"originDomain\":{\"return\":\"The origin domain id\",\"returns\":{\"_0\":\"The origin domain id\"}},\"source\":{\"return\":\"Address of the xcaller contract\",\"returns\":{\"_0\":\"Address of the xcaller contract\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"UnauthorizedCaller()\":[{\"notice\":\"Thrown if a caller is not authorized\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"kind\":\"user\",\"methods\":{\"connext()\":{\"notice\":\"Gets the ConnextHandler contract on this domain\"},\"dataReceiver()\":{\"notice\":\"Gets the address of the DataReceiver contract\"},\"originDomain()\":{\"notice\":\"Gets the origin domain id\"},\"source()\":{\"notice\":\"Gets the DAO that is expected as the xcaller\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/bridges/ConnextReceiverAdapter.sol\":\"ConnextReceiverAdapter\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {ERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title Liquidity Provider Token\\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\\n * It is used to represent user's shares when providing liquidity to swap contracts.\\n * @dev Only Swap contracts should initialize and own LPToken contracts.\\n */\\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\\n // ============ Upgrade Gap ============\\n\\n uint256[49] private __GAP; // gap for upgrade safety\\n\\n // ============ Storage ============\\n\\n /**\\n * @notice Used to enforce proper token dilution\\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\\n * See audit recommendations here:\\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\\n * and uniswap v2 implementation here:\\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\\n */\\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\\n\\n // ============ Initializer ============\\n\\n /**\\n * @notice Initializes this LPToken contract with the given name and symbol\\n * @dev The caller of this function will become the owner. A Swap contract should call this\\n * in its initializer function.\\n * @param name name of this token\\n * @param symbol symbol of this token\\n */\\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\\n __Context_init_unchained();\\n __ERC20_init_unchained(name, symbol);\\n __Ownable_init_unchained();\\n return true;\\n }\\n\\n // ============ External functions ============\\n\\n /**\\n * @notice Mints the given amount of LPToken to the recipient.\\n * @dev only owner can call this mint function\\n * @param recipient address of account to receive the tokens\\n * @param amount amount of tokens to mint\\n */\\n function mint(address recipient, uint256 amount) external onlyOwner {\\n require(amount != 0, \\\"LPToken: cannot mint 0\\\");\\n if (totalSupply() == 0) {\\n // NOTE: using the _mint function directly will error because it is going\\n // to the 0 address. fix by using the address(1) here instead\\n _mint(address(1), MINIMUM_LIQUIDITY);\\n }\\n _mint(recipient, amount);\\n }\\n\\n /**\\n * @notice Burns the given amount of LPToken from provided account\\n * @dev only owner can call this burn function\\n * @param account address of account from which to burn token\\n * @param amount amount of tokens to mint\\n */\\n function burnFrom(address account, uint256 amount) external onlyOwner {\\n require(amount != 0, \\\"LPToken: cannot burn 0\\\");\\n _burn(account, amount);\\n }\\n\\n // ============ Internal functions ============\\n\\n /**\\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\\n * This assumes the owner is set to a Swap contract's address.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20Upgradeable) {\\n super._beforeTokenTransfer(from, to, amount);\\n require(to != address(this), \\\"LPToken: cannot send to itself\\\");\\n }\\n}\\n\",\"keccak256\":\"0x1d3f871488111c70a6f9b09ad3baeb21ebc635c82aa2c6d627d07e09720e4126\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport {ExecuteArgs, TransferInfo, TokenId, DestinationTransferStatus} from \\\"../libraries/LibConnextStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {SwapUtils} from \\\"../libraries/SwapUtils.sol\\\";\\n\\nimport {IStableSwap} from \\\"./IStableSwap.sol\\\";\\n\\nimport {IDiamondCut} from \\\"./IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\ninterface IConnext is IDiamondLoupe, IDiamondCut {\\n // TokenFacet\\n function canonicalToAdopted(bytes32 _key) external view returns (address);\\n\\n function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\\n\\n function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\\n\\n function canonicalToRepresentation(bytes32 _key) external view returns (address);\\n\\n function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\\n\\n function representationToCanonical(address _adopted) external view returns (TokenId memory);\\n\\n function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\\n\\n function approvedAssets(bytes32 _key) external view returns (bool);\\n\\n function approvedAssets(TokenId calldata _canonical) external view returns (bool);\\n\\n function adoptedToLocalPools(bytes32 _key) external view returns (IStableSwap);\\n\\n function adoptedToLocalPools(TokenId calldata _canonical) external view returns (IStableSwap);\\n\\n function getTokenId(address _candidate) external view returns (TokenId memory);\\n\\n function setupAsset(\\n TokenId calldata _canonical,\\n uint8 _canonicalDecimals,\\n string memory _representationName,\\n string memory _representationSymbol,\\n address _adoptedAssetId,\\n address _stableSwapPool,\\n uint256 _cap\\n ) external returns (address);\\n\\n function setupAssetWithDeployedRepresentation(\\n TokenId calldata _canonical,\\n address _representation,\\n address _adoptedAssetId,\\n address _stableSwapPool,\\n uint256 _cap\\n ) external returns (address);\\n\\n function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\\n\\n function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\\n\\n function removeAssetId(\\n bytes32 _key,\\n address _adoptedAssetId,\\n address _representation\\n ) external;\\n\\n function removeAssetId(\\n TokenId calldata _canonical,\\n address _adoptedAssetId,\\n address _representation\\n ) external;\\n\\n function updateDetails(\\n TokenId calldata _canonical,\\n string memory _name,\\n string memory _symbol\\n ) external;\\n\\n // BaseConnextFacet\\n\\n // BridgeFacet\\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\\n\\n function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\\n\\n function remote(uint32 _domain) external view returns (address);\\n\\n function domain() external view returns (uint256);\\n\\n function nonce() external view returns (uint256);\\n\\n function approvedSequencers(address _sequencer) external view returns (bool);\\n\\n function xAppConnectionManager() external view returns (address);\\n\\n function addConnextion(uint32 _domain, address _connext) external;\\n\\n function addSequencer(address _sequencer) external;\\n\\n function removeSequencer(address _sequencer) external;\\n\\n function xcall(\\n uint32 _destination,\\n address _to,\\n address _asset,\\n address _delegate,\\n uint256 _amount,\\n uint256 _slippage,\\n bytes calldata _callData\\n ) external payable returns (bytes32);\\n\\n function xcallIntoLocal(\\n uint32 _destination,\\n address _to,\\n address _asset,\\n address _delegate,\\n uint256 _amount,\\n uint256 _slippage,\\n bytes calldata _callData\\n ) external payable returns (bytes32);\\n\\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\\n\\n function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\\n\\n function bumpTransfer(bytes32 _transferId) external payable;\\n\\n function setXAppConnectionManager(address _xAppConnectionManager) external;\\n\\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\\n\\n function enrollCustom(\\n uint32 _domain,\\n bytes32 _id,\\n address _custom\\n ) external;\\n\\n // InboxFacet\\n\\n function handle(\\n uint32 _origin,\\n uint32 _nonce,\\n bytes32 _sender,\\n bytes memory _message\\n ) external;\\n\\n // ProposedOwnableFacet\\n\\n function owner() external view returns (address);\\n\\n function routerWhitelistRemoved() external view returns (bool);\\n\\n function assetWhitelistRemoved() external view returns (bool);\\n\\n function proposed() external view returns (address);\\n\\n function proposedTimestamp() external view returns (uint256);\\n\\n function routerWhitelistTimestamp() external view returns (uint256);\\n\\n function assetWhitelistTimestamp() external view returns (uint256);\\n\\n function delay() external view returns (uint256);\\n\\n function proposeRouterWhitelistRemoval() external;\\n\\n function removeRouterWhitelist() external;\\n\\n function proposeAssetWhitelistRemoval() external;\\n\\n function removeAssetWhitelist() external;\\n\\n function renounced() external view returns (bool);\\n\\n function proposeNewOwner(address newlyProposed) external;\\n\\n function renounceOwnership() external;\\n\\n function acceptProposedOwner() external;\\n\\n function pause() external;\\n\\n function unpause() external;\\n\\n // RelayerFacet\\n function approvedRelayers(address _relayer) external view returns (bool);\\n\\n function relayerFeeVault() external view returns (address);\\n\\n function setRelayerFeeVault(address _relayerFeeVault) external;\\n\\n function addRelayer(address _relayer) external;\\n\\n function removeRelayer(address _relayer) external;\\n\\n // RoutersFacet\\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\\n\\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\\n\\n function getRouterApproval(address _router) external view returns (bool);\\n\\n function getRouterRecipient(address _router) external view returns (address);\\n\\n function getRouterOwner(address _router) external view returns (address);\\n\\n function getProposedRouterOwner(address _router) external view returns (address);\\n\\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\\n\\n function maxRoutersPerTransfer() external view returns (uint256);\\n\\n function routerBalances(address _router, address _asset) external view returns (uint256);\\n\\n function getRouterApprovalForPortal(address _router) external view returns (bool);\\n\\n function setupRouter(\\n address router,\\n address owner,\\n address recipient\\n ) external;\\n\\n function removeRouter(address router) external;\\n\\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\\n\\n function setLiquidityFeeNumerator(uint256 _numerator) external;\\n\\n function approveRouterForPortal(address _router) external;\\n\\n function unapproveRouterForPortal(address _router) external;\\n\\n function setRouterRecipient(address router, address recipient) external;\\n\\n function proposeRouterOwner(address router, address proposed) external;\\n\\n function acceptProposedRouterOwner(address router) external;\\n\\n function addRouterLiquidityFor(\\n uint256 _amount,\\n address _local,\\n address _router\\n ) external payable;\\n\\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\\n\\n function removeRouterLiquidityFor(\\n uint256 _amount,\\n address _local,\\n address payable _to,\\n address _router\\n ) external;\\n\\n function removeRouterLiquidity(\\n uint256 _amount,\\n address _local,\\n address payable _to\\n ) external;\\n\\n // PortalFacet\\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\\n\\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\\n\\n function aavePool() external view returns (address);\\n\\n function aavePortalFee() external view returns (uint256);\\n\\n function setAavePool(address _aavePool) external;\\n\\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\\n\\n function repayAavePortal(\\n TransferInfo calldata _params,\\n uint256 _backingAmount,\\n uint256 _feeAmount,\\n uint256 _maxIn\\n ) external;\\n\\n function repayAavePortalFor(\\n TransferInfo calldata _params,\\n uint256 _backingAmount,\\n uint256 _feeAmount\\n ) external;\\n\\n // StableSwapFacet\\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\\n\\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\\n\\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\\n\\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\\n\\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\\n\\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\\n\\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\\n\\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\\n\\n function calculateSwap(\\n bytes32 canonicalId,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx\\n ) external view returns (uint256);\\n\\n function calculateSwapTokenAmount(\\n bytes32 canonicalId,\\n uint256[] calldata amounts,\\n bool deposit\\n ) external view returns (uint256);\\n\\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\\n\\n function calculateRemoveSwapLiquidityOneToken(\\n bytes32 canonicalId,\\n uint256 tokenAmount,\\n uint8 tokenIndex\\n ) external view returns (uint256);\\n\\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\\n\\n function swap(\\n bytes32 canonicalId,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function swapExact(\\n bytes32 canonicalId,\\n uint256 amountIn,\\n address assetIn,\\n address assetOut,\\n uint256 minAmountOut,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function swapExactOut(\\n bytes32 canonicalId,\\n uint256 amountOut,\\n address assetIn,\\n address assetOut,\\n uint256 maxAmountIn,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function addSwapLiquidity(\\n bytes32 canonicalId,\\n uint256[] calldata amounts,\\n uint256 minToMint,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeSwapLiquidity(\\n bytes32 canonicalId,\\n uint256 amount,\\n uint256[] calldata minAmounts,\\n uint256 deadline\\n ) external returns (uint256[] memory);\\n\\n function removeSwapLiquidityOneToken(\\n bytes32 canonicalId,\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 minAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeSwapLiquidityImbalance(\\n bytes32 canonicalId,\\n uint256[] calldata amounts,\\n uint256 maxBurnAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n // SwapAdminFacet\\n\\n function initializeSwap(\\n bytes32 _canonicalId,\\n IERC20[] memory _pooledTokens,\\n uint8[] memory decimals,\\n string memory lpTokenName,\\n string memory lpTokenSymbol,\\n uint256 _a,\\n uint256 _fee,\\n uint256 _adminFee,\\n address lpTokenTargetAddress\\n ) external;\\n\\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\\n\\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\\n\\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\\n\\n function rampA(\\n bytes32 canonicalId,\\n uint256 futureA,\\n uint256 futureTime\\n ) external;\\n\\n function stopRampA(bytes32 canonicalId) external;\\n}\\n\",\"keccak256\":\"0xf4e97b6638cb0af7c41f69b151ec5c66e8d1532067674aecd71d8587a376be4a\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function proposeDiamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function rescindDiamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xd75a7bfdb3aeac3acebf8cf999330a0fc7bec65e9a68711bbb58f4554ef087b2\",\"license\":\"MIT\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xe6d71029d0a1846712477ccf17aa2124b82996c77b6e6486a208a68ea421f563\",\"license\":\"MIT\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IStableSwap {\\n /*** EVENTS ***/\\n\\n // events replicated from SwapUtils to make the ABI easier for dumb\\n // clients\\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\\n event AddLiquidity(\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\\n event RemoveLiquidityOne(\\n address indexed provider,\\n uint256 lpTokenAmount,\\n uint256 lpTokenSupply,\\n uint256 boughtId,\\n uint256 tokensBought\\n );\\n event RemoveLiquidityImbalance(\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event NewAdminFee(uint256 newAdminFee);\\n event NewSwapFee(uint256 newSwapFee);\\n event NewWithdrawFee(uint256 newWithdrawFee);\\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\\n event StopRampA(uint256 currentA, uint256 time);\\n\\n function swap(\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function swapExact(\\n uint256 amountIn,\\n address assetIn,\\n address assetOut,\\n uint256 minAmountOut,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function swapExactOut(\\n uint256 amountOut,\\n address assetIn,\\n address assetOut,\\n uint256 maxAmountIn,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function getA() external view returns (uint256);\\n\\n function getToken(uint8 index) external view returns (IERC20);\\n\\n function getTokenIndex(address tokenAddress) external view returns (uint8);\\n\\n function getTokenBalance(uint8 index) external view returns (uint256);\\n\\n function getVirtualPrice() external view returns (uint256);\\n\\n // min return calculation functions\\n function calculateSwap(\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx\\n ) external view returns (uint256);\\n\\n function calculateSwapOut(\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy\\n ) external view returns (uint256);\\n\\n function calculateSwapFromAddress(\\n address assetIn,\\n address assetOut,\\n uint256 amountIn\\n ) external view returns (uint256);\\n\\n function calculateSwapOutFromAddress(\\n address assetIn,\\n address assetOut,\\n uint256 amountOut\\n ) external view returns (uint256);\\n\\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\\n\\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\\n\\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\\n external\\n view\\n returns (uint256 availableTokenAmount);\\n\\n // state modifying functions\\n function initialize(\\n IERC20[] memory pooledTokens,\\n uint8[] memory decimals,\\n string memory lpTokenName,\\n string memory lpTokenSymbol,\\n uint256 a,\\n uint256 fee,\\n uint256 adminFee,\\n address lpTokenTargetAddress\\n ) external;\\n\\n function addLiquidity(\\n uint256[] calldata amounts,\\n uint256 minToMint,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeLiquidity(\\n uint256 amount,\\n uint256[] calldata minAmounts,\\n uint256 deadline\\n ) external returns (uint256[] memory);\\n\\n function removeLiquidityOneToken(\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 minAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeLiquidityImbalance(\\n uint256[] calldata amounts,\\n uint256 maxBurnAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n}\\n\",\"keccak256\":\"0xfbbb2cad0639658aa781212c69df10718250a6926d94a1a7508fc9927216abe8\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\ninterface IXReceiver {\\n function xReceive(\\n bytes32 _transferId,\\n uint256 _amount,\\n address _asset,\\n address _originSender,\\n uint32 _origin,\\n bytes memory _callData\\n ) external returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x75286f6ac1b1d5d7f4e508a478c0dad3a26d92675dabbf180d0b46d892618a1a\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport {SwapUtils} from \\\"./SwapUtils.sol\\\";\\n\\n/**\\n * @title AmplificationUtils library\\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\\n * This library assumes the struct is fully validated.\\n */\\nlibrary AmplificationUtils {\\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\\n event StopRampA(uint256 currentA, uint256 time);\\n\\n // Constant values used in ramping A calculations\\n uint256 public constant A_PRECISION = 100;\\n uint256 public constant MAX_A = 10**6;\\n uint256 private constant MAX_A_CHANGE = 2;\\n uint256 private constant MIN_RAMP_TIME = 14 days;\\n\\n /**\\n * @notice Return A, the amplification coefficient * n * (n - 1)\\n * @dev See the StableSwap paper for details\\n * @param self Swap struct to read from\\n * @return A parameter\\n */\\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\\n return _getAPrecise(self) / A_PRECISION;\\n }\\n\\n /**\\n * @notice Return A in its raw precision\\n * @dev See the StableSwap paper for details\\n * @param self Swap struct to read from\\n * @return A parameter in its raw precision form\\n */\\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\\n return _getAPrecise(self);\\n }\\n\\n /**\\n * @notice Return A in its raw precision\\n * @dev See the StableSwap paper for details\\n * @param self Swap struct to read from\\n * @return A parameter in its raw precision form\\n */\\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\\n uint256 t1 = self.futureATime; // time when ramp is finished\\n uint256 a1 = self.futureA; // final A value when ramp is finished\\n\\n if (block.timestamp < t1) {\\n uint256 t0 = self.initialATime; // time when ramp is started\\n uint256 a0 = self.initialA; // initial A value when ramp is started\\n if (a1 > a0) {\\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\\n return a0 + ((a1 - a0) * (block.timestamp - t0)) / (t1 - t0);\\n } else {\\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\\n return a0 - ((a0 - a1) * (block.timestamp - t0)) / (t1 - t0);\\n }\\n } else {\\n return a1;\\n }\\n }\\n\\n /**\\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\\n * Checks if the change is too rapid, and commits the new A value only when it falls under\\n * the limit range.\\n * @param self Swap struct to update\\n * @param futureA_ the new A to ramp towards\\n * @param futureTime_ timestamp when the new A should be reached\\n */\\n function rampA(\\n SwapUtils.Swap storage self,\\n uint256 futureA_,\\n uint256 futureTime_\\n ) internal {\\n require(block.timestamp >= self.initialATime + 1 days, \\\"Wait 1 day before starting ramp\\\");\\n require(futureTime_ >= block.timestamp + MIN_RAMP_TIME, \\\"Insufficient ramp time\\\");\\n require(futureA_ != 0 && futureA_ < MAX_A, \\\"futureA_ must be > 0 and < MAX_A\\\");\\n\\n uint256 initialAPrecise = _getAPrecise(self);\\n uint256 futureAPrecise = futureA_ * A_PRECISION;\\n\\n if (futureAPrecise < initialAPrecise) {\\n require(futureAPrecise * MAX_A_CHANGE >= initialAPrecise, \\\"futureA_ is too small\\\");\\n } else {\\n require(futureAPrecise <= initialAPrecise * MAX_A_CHANGE, \\\"futureA_ is too large\\\");\\n }\\n\\n self.initialA = initialAPrecise;\\n self.futureA = futureAPrecise;\\n self.initialATime = block.timestamp;\\n self.futureATime = futureTime_;\\n\\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\\n }\\n\\n /**\\n * @notice Stops ramping A immediately. Once this function is called, rampA()\\n * cannot be called for another 24 hours\\n * @param self Swap struct to update\\n */\\n function stopRampA(SwapUtils.Swap storage self) internal {\\n require(self.futureATime > block.timestamp, \\\"Ramp is already stopped\\\");\\n\\n uint256 currentA = _getAPrecise(self);\\n self.initialA = currentA;\\n self.futureA = currentA;\\n self.initialATime = block.timestamp;\\n self.futureATime = block.timestamp;\\n\\n emit StopRampA(currentA, block.timestamp);\\n }\\n}\\n\",\"keccak256\":\"0x7dca96b10fa307f469c142aaea0855d3c9ba45f79066eaeae1467ce113fc8d28\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {IStableSwap} from \\\"../interfaces/IStableSwap.sol\\\";\\nimport {IConnectorManager} from \\\"../../../messaging/interfaces/IConnectorManager.sol\\\";\\nimport {SwapUtils} from \\\"./SwapUtils.sol\\\";\\n\\n// ============= Enum =============\\n\\n/// @notice Enum representing address role\\n// Returns uint\\n// None - 0\\n// Router - 1\\n// Watcher - 2\\n// Admin - 3\\nenum Role {\\n None,\\n Router,\\n Watcher,\\n Admin\\n}\\n\\n/**\\n * @notice Enum representing status of destination transfer\\n * @dev Status is only assigned on the destination domain, will always be \\\"none\\\" for the\\n * origin domains\\n * @return uint - Index of value in enum\\n */\\nenum DestinationTransferStatus {\\n None, // 0\\n Reconciled, // 1\\n Executed, // 2\\n Completed // 3 - executed + reconciled\\n}\\n\\n// ============= Structs =============\\n\\nstruct TokenId {\\n uint32 domain;\\n bytes32 id;\\n}\\n\\n/**\\n * @notice These are the parameters that will remain constant between the\\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\\n * @property to - The account that receives funds, in the event of a crosschain call,\\n * will receive funds if the call fails.\\n *\\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\\n * @param canonicalDomain - The canonical domain of the asset you are bridging\\n * @param to - The address you are sending funds (and potentially data) to\\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\\n * a user takes 1% slippage, this is expressed as 1_000)\\n * @param originSender - The msg.sender of the xcall\\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\\n */\\nstruct TransferInfo {\\n uint32 originDomain;\\n uint32 destinationDomain;\\n uint32 canonicalDomain;\\n address to;\\n address delegate;\\n bool receiveLocal;\\n bytes callData;\\n uint256 slippage;\\n address originSender;\\n uint256 bridgedAmt;\\n uint256 normalizedIn;\\n uint256 nonce;\\n bytes32 canonicalId;\\n}\\n\\n/**\\n * @notice\\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\\n * @param routers - The routers who you are sending the funds on behalf of.\\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\\n * for the signed transfer ID.\\n * @param sequencer - The sequencer who assigned the router path to this transfer.\\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\\n * for the path that was signed.\\n */\\nstruct ExecuteArgs {\\n TransferInfo params;\\n address[] routers;\\n bytes[] routerSignatures;\\n address sequencer;\\n bytes sequencerSignature;\\n}\\n\\n/**\\n * @notice Contains RouterFacet related state\\n * @param approvedRouters - Mapping of whitelisted router addresses\\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\\n * (if configured) or the router itself\\n * @param routerOwners - Mapping of router owners\\n * If set, can update the routerRecipient\\n * @param proposedRouterOwners - Mapping of proposed router owners\\n * Must wait timeout to set the\\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\\n * When accepting a proposed owner, must wait for delay to elapse\\n */\\nstruct RouterPermissionsManagerInfo {\\n mapping(address => bool) approvedRouters;\\n mapping(address => bool) approvedForPortalRouters;\\n mapping(address => address) routerRecipients;\\n mapping(address => address) routerOwners;\\n mapping(address => address) proposedRouterOwners;\\n mapping(address => uint256) proposedRouterTimestamp;\\n}\\n\\nstruct AppStorage {\\n //\\n // 0\\n bool initialized;\\n //\\n // Connext\\n //\\n // 1\\n uint256 LIQUIDITY_FEE_NUMERATOR;\\n /**\\n * @notice The local address that is custodying relayer fees\\n */\\n // 2\\n address relayerFeeVault;\\n /**\\n * @notice Nonce for the contract, used to keep unique transfer ids.\\n * @dev Assigned at first interaction (xcall on origin domain).\\n */\\n // 3\\n uint256 nonce;\\n /**\\n * @notice The domain this contract exists on.\\n * @dev Must match the nomad domain, which is distinct from the \\\"chainId\\\".\\n */\\n // 4\\n uint32 domain;\\n /**\\n * @notice Mapping holding the AMMs for swapping in and out of local assets.\\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon).\\n * This mapping is keyed on the hash of the canonical id + domain for local asset.\\n */\\n // 6\\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\\n /**\\n * @notice Mapping of whitelisted assets on same domain as contract.\\n * @dev Mapping is keyed on the hash of the canonical id and domain\\n */\\n // 7\\n mapping(bytes32 => bool) approvedAssets;\\n /**\\n * @notice Mapping of liquidity caps of whitelisted assets. If 0, no cap is enforced.\\n * @dev Mapping is keyed on the hash of the canonical id and domain\\n */\\n // 7\\n mapping(bytes32 => uint256) caps;\\n /**\\n * @notice Mapping of adopted to canonical asset information.\\n * @dev If the adopted asset is the native asset, the keyed address will\\n * be the wrapped asset address.\\n */\\n // 8\\n mapping(address => TokenId) adoptedToCanonical;\\n /**\\n * @notice Mapping of representation to canonical asset information.\\n */\\n // 9\\n mapping(address => TokenId) representationToCanonical;\\n /**\\n * @notice Mapping of hash(canonicalId, canonicalDomain) to adopted asset on this domain.\\n * @dev If the adopted asset is the native asset, the stored address will be the\\n * wrapped asset address.\\n */\\n // 10\\n mapping(bytes32 => address) canonicalToAdopted;\\n /**\\n * @notice Mapping of canonical to representation asset information.\\n * @dev If the token is of local origin (meaning it was originanlly deployed on this chain),\\n * this MUST map to address(0).\\n */\\n // 11\\n mapping(bytes32 => address) canonicalToRepresentation;\\n /**\\n * @notice Mapping to track transfer status on destination domain\\n */\\n // 12\\n mapping(bytes32 => DestinationTransferStatus) transferStatus;\\n /**\\n * @notice Mapping holding router address that provided fast liquidity.\\n */\\n // 13\\n mapping(bytes32 => address[]) routedTransfers;\\n /**\\n * @notice Mapping of router to available balance of an asset.\\n * @dev Routers should always store liquidity that they can expect to receive via the bridge on\\n * this domain (the nomad local asset).\\n */\\n // 14\\n mapping(address => mapping(address => uint256)) routerBalances;\\n /**\\n * @notice Mapping of approved relayers\\n * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\\n */\\n // 15\\n mapping(address => bool) approvedRelayers;\\n /**\\n * @notice The max amount of routers a payment can be routed through.\\n */\\n // 18\\n uint256 maxRoutersPerTransfer;\\n /**\\n * @notice Stores a mapping of transfer id to slippage overrides.\\n */\\n // 20\\n mapping(bytes32 => uint256) slippage;\\n /**\\n * @notice Stores a mapping of remote routers keyed on domains.\\n * @dev Addresses are cast to bytes32.\\n * This mapping is required because the Connext now contains the BridgeRouter and must implement\\n * the remotes interface.\\n */\\n // 21\\n mapping(uint32 => bytes32) remotes;\\n //\\n // ProposedOwnable\\n //\\n // 22\\n address _proposed;\\n // 23\\n uint256 _proposedOwnershipTimestamp;\\n // 24\\n bool _routerWhitelistRemoved;\\n // 25\\n uint256 _routerWhitelistTimestamp;\\n // 26\\n bool _assetWhitelistRemoved;\\n // 27\\n uint256 _assetWhitelistTimestamp;\\n /**\\n * @notice Stores a mapping of address to Roles\\n * @dev returns uint representing the enum Role value\\n */\\n // 28\\n mapping(address => Role) roles;\\n //\\n // RouterFacet\\n //\\n // 29\\n RouterPermissionsManagerInfo routerPermissionInfo;\\n //\\n // ReentrancyGuard\\n //\\n // 30\\n uint256 _status;\\n //\\n // StableSwap\\n //\\n /**\\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\\n * Struct storing data responsible for automatic market maker functionalities. In order to\\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\\n */\\n // 31\\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\\n /**\\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\\n */\\n // 32\\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\\n /**\\n * @notice Stores whether or not bribing, AMMs, have been paused.\\n */\\n // 33\\n bool _paused;\\n //\\n // AavePortals\\n //\\n /**\\n * @notice Address of Aave Pool contract.\\n */\\n // 34\\n address aavePool;\\n /**\\n * @notice Fee percentage numerator for using Portal liquidity.\\n * @dev Assumes the same basis points as the liquidity fee.\\n */\\n // 35\\n uint256 aavePortalFeeNumerator;\\n /**\\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\\n */\\n // 36\\n mapping(bytes32 => uint256) portalDebt;\\n /**\\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\\n */\\n // 37\\n mapping(bytes32 => uint256) portalFeeDebt;\\n /**\\n * @notice Mapping of approved sequencers\\n * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\\n * for the fast liquidity route.\\n */\\n // 38\\n mapping(address => bool) approvedSequencers;\\n /**\\n * @notice Remote connection manager for xapp.\\n */\\n // 39\\n IConnectorManager xAppConnectionManager;\\n}\\n\\nlibrary LibConnextStorage {\\n function connextStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n}\\n\",\"keccak256\":\"0x24f998cc9edbb1f3f00c7148d18b7ca0d40eaaac7e3f7fa990ffe89bdee8ec32\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n // hash of proposed facets => acceptance time\\n mapping(bytes32 => uint256) acceptanceTimes;\\n // acceptance delay for upgrading facets\\n uint256 acceptanceDelay;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function acceptanceDelay() internal view returns (uint256) {\\n return diamondStorage().acceptanceDelay;\\n }\\n\\n function acceptanceTime(bytes32 _key) internal view returns (uint256) {\\n return diamondStorage().acceptanceTimes[_key];\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, \\\"LibDiamond: !contract owner\\\");\\n }\\n\\n event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\\n\\n function proposeDiamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 acceptance = block.timestamp + ds.acceptanceDelay;\\n ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\\n emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\\n }\\n\\n event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n function rescindDiamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\\n // period or befor the delay elpases\\n diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = 0;\\n emit DiamondCutRescinded(_diamondCut, _init, _calldata);\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n if (ds.facetAddresses.length != 0) {\\n uint256 time = ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\\n require(time != 0 && time <= block.timestamp, \\\"LibDiamond: delay not elapsed\\\");\\n } // Otherwise, this is the first instance of deployment and it can be set automatically\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length != 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(oldFacetAddress == address(0), \\\"LibDiamondCut: Can't add function that already exists\\\");\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length != 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(oldFacetAddress != _facetAddress, \\\"LibDiamondCut: Can't replace function with same function\\\");\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length != 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), \\\"LibDiamondCut: Remove facet address must be address(0)\\\");\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, \\\"LibDiamondCut: New facet has no code\\\");\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n require(_calldata.length == 0, \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\");\\n } else {\\n require(_calldata.length != 0, \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\");\\n if (_init != address(this)) {\\n enforceHasContractCode(_init, \\\"LibDiamondCut: _init address has no code\\\");\\n }\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length != 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize != 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x0ca55de8a7f4e2256b8b7a5e9ae6cca6d6ff850bbd9fd79542dfc4236871c6d8\",\"license\":\"MIT\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\n/**\\n * @title MathUtils library\\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\\n * differences between two uint256.\\n */\\nlibrary MathUtils {\\n /**\\n * @notice Compares a and b and returns true if the difference between a and b\\n * is less than 1 or equal to each other.\\n * @param a uint256 to compare with\\n * @param b uint256 to compare with\\n * @return True if the difference between a and b is less than 1 or equal,\\n * otherwise return false\\n */\\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\\n return (difference(a, b) <= 1);\\n }\\n\\n /**\\n * @notice Calculates absolute difference between a and b\\n * @param a uint256 to compare with\\n * @param b uint256 to compare with\\n * @return Difference between a and b\\n */\\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a > b) {\\n return a - b;\\n }\\n return b - a;\\n }\\n}\\n\",\"keccak256\":\"0xc0e55e78b6b5fec92fbf16f77f10103450f012394d995c8ace507f1abae29371\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {SafeERC20, IERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport {LPToken} from \\\"../helpers/LPToken.sol\\\";\\n\\nimport {AmplificationUtils} from \\\"./AmplificationUtils.sol\\\";\\nimport {MathUtils} from \\\"./MathUtils.sol\\\";\\n\\n/**\\n * @title SwapUtils library\\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\\n * Admin functions should be protected within contracts using this library.\\n */\\nlibrary SwapUtils {\\n using SafeERC20 for IERC20;\\n using MathUtils for uint256;\\n\\n /*** EVENTS ***/\\n\\n event TokenSwap(\\n bytes32 indexed key,\\n address indexed buyer,\\n uint256 tokensSold,\\n uint256 tokensBought,\\n uint128 soldId,\\n uint128 boughtId\\n );\\n event AddLiquidity(\\n bytes32 indexed key,\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\\n event RemoveLiquidityOne(\\n bytes32 indexed key,\\n address indexed provider,\\n uint256 lpTokenAmount,\\n uint256 lpTokenSupply,\\n uint256 boughtId,\\n uint256 tokensBought\\n );\\n event RemoveLiquidityImbalance(\\n bytes32 indexed key,\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\\n event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\\n\\n struct Swap {\\n // variables around the ramp management of A,\\n // the amplification coefficient * n * (n - 1)\\n // see https://www.curve.fi/stableswap-paper.pdf for details\\n bytes32 key;\\n uint256 initialA;\\n uint256 futureA;\\n uint256 initialATime;\\n uint256 futureATime;\\n // fee calculation\\n uint256 swapFee;\\n uint256 adminFee;\\n LPToken lpToken;\\n // contract references for all tokens being pooled\\n IERC20[] pooledTokens;\\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\\n uint256[] tokenPrecisionMultipliers;\\n // the pool balance of each token, in the token's precision\\n // the contract's actual token balance might differ\\n uint256[] balances;\\n // the admin fee balance of each token, in the token's precision\\n uint256[] adminFees;\\n }\\n\\n // Struct storing variables used in calculations in the\\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\\n struct CalculateWithdrawOneTokenDYInfo {\\n uint256 d0;\\n uint256 d1;\\n uint256 newY;\\n uint256 feePerToken;\\n uint256 preciseA;\\n }\\n\\n // Struct storing variables used in calculations in the\\n // {add,remove}Liquidity functions to avoid stack too deep errors\\n struct ManageLiquidityInfo {\\n uint256 d0;\\n uint256 d1;\\n uint256 d2;\\n uint256 preciseA;\\n LPToken lpToken;\\n uint256 totalSupply;\\n uint256[] balances;\\n uint256[] multipliers;\\n }\\n\\n // the precision all pools tokens will be converted to\\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\\n\\n // the denominator used to calculate admin and LP fees. For example, an\\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\\n uint256 internal constant FEE_DENOMINATOR = 1e10;\\n\\n // Max swap fee is 1% or 100bps of each swap\\n uint256 internal constant MAX_SWAP_FEE = 1e8;\\n\\n // Max adminFee is 100% of the swapFee\\n // adminFee does not add additional fee on top of swapFee\\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\\n // users but only on the earnings of LPs\\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\\n\\n // Constant value used as max loop limit\\n uint256 internal constant MAX_LOOP_LIMIT = 256;\\n\\n /*** VIEW & PURE FUNCTIONS ***/\\n\\n function _getAPrecise(Swap storage self) private view returns (uint256) {\\n return AmplificationUtils._getAPrecise(self);\\n }\\n\\n /**\\n * @notice Calculate the dy, the amount of selected token that user receives and\\n * the fee of withdrawing in one token\\n * @param tokenAmount the amount to withdraw in the pool's precision\\n * @param tokenIndex which token will be withdrawn\\n * @param self Swap struct to read from\\n * @return the amount of token user will receive\\n */\\n function calculateWithdrawOneToken(\\n Swap storage self,\\n uint256 tokenAmount,\\n uint8 tokenIndex\\n ) internal view returns (uint256) {\\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\\n self,\\n tokenAmount,\\n tokenIndex,\\n self.lpToken.totalSupply()\\n );\\n return availableTokenAmount;\\n }\\n\\n function _calculateWithdrawOneToken(\\n Swap storage self,\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 totalSupply\\n ) private view returns (uint256, uint256) {\\n uint256 dy;\\n uint256 newY;\\n uint256 currentY;\\n\\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\\n\\n // dy_0 (without fees)\\n // dy, dy_0 - dy\\n\\n uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\\n\\n return (dy, dySwapFee);\\n }\\n\\n /**\\n * @notice Calculate the dy of withdrawing in one token\\n * @param self Swap struct to read from\\n * @param tokenIndex which token will be withdrawn\\n * @param tokenAmount the amount to withdraw in the pools precision\\n * @return the d and the new y after withdrawing one token\\n */\\n function calculateWithdrawOneTokenDY(\\n Swap storage self,\\n uint8 tokenIndex,\\n uint256 tokenAmount,\\n uint256 totalSupply\\n )\\n internal\\n view\\n returns (\\n uint256,\\n uint256,\\n uint256\\n )\\n {\\n // Get the current D, then solve the stableswap invariant\\n // y_i for D - tokenAmount\\n uint256[] memory xp = _xp(self);\\n\\n require(tokenIndex < xp.length, \\\"index out of range\\\");\\n\\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\\n v.preciseA = _getAPrecise(self);\\n v.d0 = getD(xp, v.preciseA);\\n v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\\n\\n require(tokenAmount <= xp[tokenIndex], \\\"exceeds available\\\");\\n\\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\\n\\n uint256[] memory xpReduced = new uint256[](xp.length);\\n\\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\\n for (uint256 i; i < xp.length; ) {\\n uint256 xpi = xp[i];\\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\\n xpReduced[i] =\\n xpi -\\n ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\\n FEE_DENOMINATOR);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\\n dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\\n\\n return (dy, v.newY, xp[tokenIndex]);\\n }\\n\\n /**\\n * @notice Calculate the price of a token in the pool with given\\n * precision-adjusted balances and a particular D.\\n *\\n * @dev This is accomplished via solving the invariant iteratively.\\n * See the StableSwap paper and Curve.fi implementation for further details.\\n *\\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\\n * x_1**2 + b*x_1 = c\\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\\n *\\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\\n * @param tokenIndex Index of token we are calculating for.\\n * @param xp a precision-adjusted set of pool balances. Array should be\\n * the same cardinality as the pool.\\n * @param d the stableswap invariant\\n * @return the price of the token, in the same precision as in xp\\n */\\n function getYD(\\n uint256 a,\\n uint8 tokenIndex,\\n uint256[] memory xp,\\n uint256 d\\n ) internal pure returns (uint256) {\\n uint256 numTokens = xp.length;\\n require(tokenIndex < numTokens, \\\"Token not found\\\");\\n\\n uint256 c = d;\\n uint256 s;\\n uint256 nA = a * numTokens;\\n\\n for (uint256 i; i < numTokens; ) {\\n if (i != tokenIndex) {\\n s += xp[i];\\n c = (c * d) / (xp[i] * numTokens);\\n // If we were to protect the division loss we would have to keep the denominator separate\\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\\n // c = c * D * D * D * ... overflow!\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\\n\\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\\n uint256 yPrev;\\n uint256 y = d;\\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\\n yPrev = y;\\n y = ((y * y) + c) / ((y * 2) + b - d);\\n if (y.within1(yPrev)) {\\n return y;\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n revert(\\\"Approximation did not converge\\\");\\n }\\n\\n /**\\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\\n * as the pool.\\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\\n * See the StableSwap paper for details\\n * @return the invariant, at the precision of the pool\\n */\\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\\n uint256 numTokens = xp.length;\\n uint256 s;\\n for (uint256 i; i < numTokens; ) {\\n s += xp[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n if (s == 0) {\\n return 0;\\n }\\n\\n uint256 prevD;\\n uint256 d = s;\\n uint256 nA = a * numTokens;\\n\\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\\n uint256 dP = d;\\n for (uint256 j; j < numTokens; ) {\\n dP = (dP * d) / (xp[j] * numTokens);\\n // If we were to protect the division loss we would have to keep the denominator separate\\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\\n // dP = dP * D * D * D * ... overflow!\\n\\n unchecked {\\n ++j;\\n }\\n }\\n prevD = d;\\n d =\\n (((nA * s) / AmplificationUtils.A_PRECISION + dP * numTokens) * d) /\\n ((((nA - AmplificationUtils.A_PRECISION) * d) / AmplificationUtils.A_PRECISION + (numTokens + 1) * dP));\\n if (d.within1(prevD)) {\\n return d;\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\\n // function which does not rely on D.\\n revert(\\\"D does not converge\\\");\\n }\\n\\n /**\\n * @notice Given a set of balances and precision multipliers, return the\\n * precision-adjusted balances.\\n *\\n * @param balances an array of token balances, in their native precisions.\\n * These should generally correspond with pooled tokens.\\n *\\n * @param precisionMultipliers an array of multipliers, corresponding to\\n * the amounts in the balances array. When multiplied together they\\n * should yield amounts at the pool's precision.\\n *\\n * @return an array of amounts \\\"scaled\\\" to the pool's precision\\n */\\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\\n internal\\n pure\\n returns (uint256[] memory)\\n {\\n uint256 numTokens = balances.length;\\n require(numTokens == precisionMultipliers.length, \\\"mismatch multipliers\\\");\\n uint256[] memory xp = new uint256[](numTokens);\\n for (uint256 i; i < numTokens; ) {\\n xp[i] = balances[i] * precisionMultipliers[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n return xp;\\n }\\n\\n /**\\n * @notice Return the precision-adjusted balances of all tokens in the pool\\n * @param self Swap struct to read from\\n * @return the pool balances \\\"scaled\\\" to the pool's precision, allowing\\n * them to be more easily compared.\\n */\\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\\n return _xp(self.balances, self.tokenPrecisionMultipliers);\\n }\\n\\n /**\\n * @notice Get the virtual price, to help calculate profit\\n * @param self Swap struct to read from\\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\\n */\\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\\n uint256 d = getD(_xp(self), _getAPrecise(self));\\n LPToken lpToken = self.lpToken;\\n uint256 supply = lpToken.totalSupply();\\n if (supply != 0) {\\n return (d * (10**uint256(POOL_PRECISION_DECIMALS))) / supply;\\n }\\n return 0;\\n }\\n\\n /**\\n * @notice Calculate the new balances of the tokens given the indexes of the token\\n * that is swapped from (FROM) and the token that is swapped to (TO).\\n * This function is used as a helper function to calculate how much TO token\\n * the user should receive on swap.\\n *\\n * @param preciseA precise form of amplification coefficient\\n * @param tokenIndexFrom index of FROM token\\n * @param tokenIndexTo index of TO token\\n * @param x the new total amount of FROM token\\n * @param xp balances of the tokens in the pool\\n * @return the amount of TO token that should remain in the pool\\n */\\n function getY(\\n uint256 preciseA,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 x,\\n uint256[] memory xp\\n ) internal pure returns (uint256) {\\n uint256 numTokens = xp.length;\\n require(tokenIndexFrom != tokenIndexTo, \\\"compare token to itself\\\");\\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \\\"token not found\\\");\\n\\n uint256 d = getD(xp, preciseA);\\n uint256 c = d;\\n uint256 s;\\n uint256 nA = numTokens * preciseA;\\n\\n uint256 _x;\\n for (uint256 i; i < numTokens; ) {\\n if (i == tokenIndexFrom) {\\n _x = x;\\n } else if (i != tokenIndexTo) {\\n _x = xp[i];\\n } else {\\n unchecked {\\n ++i;\\n }\\n continue;\\n }\\n s += _x;\\n c = (c * d) / (_x * numTokens);\\n // If we were to protect the division loss we would have to keep the denominator separate\\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\\n // c = c * D * D * D * ... overflow!\\n\\n unchecked {\\n ++i;\\n }\\n }\\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\\n uint256 yPrev;\\n uint256 y = d;\\n\\n // iterative approximation\\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\\n yPrev = y;\\n y = ((y * y) + c) / ((y * 2) + b - d);\\n if (y.within1(yPrev)) {\\n return y;\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n revert(\\\"Approximation did not converge\\\");\\n }\\n\\n /**\\n * @notice Externally calculates a swap between two tokens.\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @return dy the number of tokens the user will get\\n */\\n function calculateSwap(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx\\n ) internal view returns (uint256 dy) {\\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\\n }\\n\\n /**\\n * @notice Externally calculates a swap between two tokens.\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dy the number of tokens to buy.\\n * @return dx the number of tokens the user have to transfer + fee\\n */\\n function calculateSwapInv(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy\\n ) internal view returns (uint256 dx) {\\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\\n }\\n\\n /**\\n * @notice Internally calculates a swap between two tokens.\\n *\\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\\n * using the token contracts.\\n *\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\\n * @return dyFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\\n */\\n function _calculateSwap(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256[] memory balances\\n ) internal view returns (uint256 dy, uint256 dyFee) {\\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\\n uint256[] memory xp = _xp(balances, multipliers);\\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \\\"index out of range\\\");\\n uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\\n dy = xp[tokenIndexTo] - y - 1;\\n dyFee = (dy * self.swapFee) / FEE_DENOMINATOR;\\n dy = (dy - dyFee) / multipliers[tokenIndexTo];\\n }\\n\\n /**\\n * @notice Internally calculates a swap between two tokens.\\n *\\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\\n * using the token contracts.\\n *\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\\n * @return dxFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\\n */\\n function _calculateSwapInv(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy,\\n uint256[] memory balances\\n ) internal view returns (uint256 dx, uint256 dxFee) {\\n require(tokenIndexFrom != tokenIndexTo, \\\"compare token to itself\\\");\\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\\n uint256[] memory xp = _xp(balances, multipliers);\\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \\\"index out of range\\\");\\n\\n uint256 a = _getAPrecise(self);\\n uint256 d0 = getD(xp, a);\\n\\n xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\\n dx = x - xp[tokenIndexFrom] + 1;\\n dxFee = (dx * self.swapFee) / FEE_DENOMINATOR;\\n dx = (dx + dxFee) / multipliers[tokenIndexFrom];\\n }\\n\\n /**\\n * @notice A simple method to calculate amount of each underlying\\n * tokens that is returned upon burning given amount of\\n * LP tokens\\n *\\n * @param amount the amount of LP tokens that would to be burned on\\n * withdrawal\\n * @return array of amounts of tokens user will receive\\n */\\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\\n }\\n\\n function _calculateRemoveLiquidity(\\n uint256[] memory balances,\\n uint256 amount,\\n uint256 totalSupply\\n ) internal pure returns (uint256[] memory) {\\n require(amount <= totalSupply, \\\"exceed total supply\\\");\\n\\n uint256 numBalances = balances.length;\\n uint256[] memory amounts = new uint256[](numBalances);\\n\\n for (uint256 i; i < numBalances; ) {\\n amounts[i] = (balances[i] * amount) / totalSupply;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n return amounts;\\n }\\n\\n /**\\n * @notice A simple method to calculate prices from deposits or\\n * withdrawals, excluding fees but including slippage. This is\\n * helpful as an input into the various \\\"min\\\" parameters on calls\\n * to fight front-running\\n *\\n * @dev This shouldn't be used outside frontends for user estimates.\\n *\\n * @param self Swap struct to read from\\n * @param amounts an array of token amounts to deposit or withdrawal,\\n * corresponding to pooledTokens. The amount should be in each\\n * pooled token's native precision. If a token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @param deposit whether this is a deposit or a withdrawal\\n * @return if deposit was true, total amount of lp token that will be minted and if\\n * deposit was false, total amount of lp token that will be burned\\n */\\n function calculateTokenAmount(\\n Swap storage self,\\n uint256[] calldata amounts,\\n bool deposit\\n ) internal view returns (uint256) {\\n uint256 a = _getAPrecise(self);\\n uint256[] memory balances = self.balances;\\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\\n\\n uint256 numBalances = balances.length;\\n uint256 d0 = getD(_xp(balances, multipliers), a);\\n for (uint256 i; i < numBalances; ) {\\n if (deposit) {\\n balances[i] = balances[i] + amounts[i];\\n } else {\\n balances[i] = balances[i] - amounts[i];\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n uint256 d1 = getD(_xp(balances, multipliers), a);\\n uint256 totalSupply = self.lpToken.totalSupply();\\n\\n if (deposit) {\\n return ((d1 - d0) * totalSupply) / d0;\\n } else {\\n return ((d0 - d1) * totalSupply) / d0;\\n }\\n }\\n\\n /**\\n * @notice return accumulated amount of admin fees of the token with given index\\n * @param self Swap struct to read from\\n * @param index Index of the pooled token\\n * @return admin balance in the token's precision\\n */\\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\\n require(index < self.pooledTokens.length, \\\"index out of range\\\");\\n return self.adminFees[index];\\n }\\n\\n /**\\n * @notice internal helper function to calculate fee per token multiplier used in\\n * swap fee calculations\\n * @param swapFee swap fee for the tokens\\n * @param numTokens number of tokens pooled\\n */\\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\\n return (swapFee * numTokens) / ((numTokens - 1) * 4);\\n }\\n\\n /*** STATE MODIFYING FUNCTIONS ***/\\n\\n /**\\n * @notice swap two tokens in the pool\\n * @param self Swap struct to read from and write to\\n * @param tokenIndexFrom the token the user wants to sell\\n * @param tokenIndexTo the token the user wants to buy\\n * @param dx the amount of tokens the user wants to sell\\n * @param minDy the min amount the user would like to receive, or revert.\\n * @return amount of token user received on swap\\n */\\n function swap(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy\\n ) internal returns (uint256) {\\n {\\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\\n require(dx <= tokenFrom.balanceOf(msg.sender), \\\"swap more than you own\\\");\\n // Transfer tokens first to see if a fee was charged on transfer\\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\\n\\n // Use the actual transferred amount for AMM math\\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \\\"no fee token support\\\");\\n }\\n\\n uint256 dy;\\n uint256 dyFee;\\n uint256[] memory balances = self.balances;\\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\\n require(dy >= minDy, \\\"dy < minDy\\\");\\n\\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\\n if (dyAdminFee != 0) {\\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\\n }\\n\\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dy;\\n }\\n\\n /**\\n * @notice swap two tokens in the pool\\n * @param self Swap struct to read from and write to\\n * @param tokenIndexFrom the token the user wants to sell\\n * @param tokenIndexTo the token the user wants to buy\\n * @param dy the amount of tokens the user wants to buy\\n * @param maxDx the max amount the user would like to send.\\n * @return amount of token user have to transfer on swap\\n */\\n function swapOut(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy,\\n uint256 maxDx\\n ) internal returns (uint256) {\\n require(dy <= self.balances[tokenIndexTo], \\\">pool balance\\\");\\n\\n uint256 dx;\\n uint256 dxFee;\\n uint256[] memory balances = self.balances;\\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\\n require(dx <= maxDx, \\\"dx > maxDx\\\");\\n\\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\\n if (dxAdminFee != 0) {\\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\\n }\\n\\n {\\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\\n require(dx <= tokenFrom.balanceOf(msg.sender), \\\"more than you own\\\");\\n // Transfer tokens first to see if a fee was charged on transfer\\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\\n\\n // Use the actual transferred amount for AMM math\\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \\\"not support fee token\\\");\\n }\\n\\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dx;\\n }\\n\\n /**\\n * @notice swap two tokens in the pool internally\\n * @param self Swap struct to read from and write to\\n * @param tokenIndexFrom the token the user wants to sell\\n * @param tokenIndexTo the token the user wants to buy\\n * @param dx the amount of tokens the user wants to sell\\n * @param minDy the min amount the user would like to receive, or revert.\\n * @return amount of token user received on swap\\n */\\n function swapInternal(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy\\n ) internal returns (uint256) {\\n require(dx <= self.balances[tokenIndexFrom], \\\"more than pool balance\\\");\\n\\n uint256 dy;\\n uint256 dyFee;\\n uint256[] memory balances = self.balances;\\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\\n require(dy >= minDy, \\\"dy < minDy\\\");\\n\\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\\n\\n if (dyAdminFee != 0) {\\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\\n }\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dy;\\n }\\n\\n /**\\n * @notice Should get exact amount out of AMM for asset put in\\n */\\n function swapInternalOut(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy,\\n uint256 maxDx\\n ) internal returns (uint256) {\\n require(dy <= self.balances[tokenIndexTo], \\\"more than pool balance\\\");\\n\\n uint256 dx;\\n uint256 dxFee;\\n uint256[] memory balances = self.balances;\\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\\n require(dx <= maxDx, \\\"dx > maxDx\\\");\\n\\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\\n\\n if (dxAdminFee != 0) {\\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\\n }\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dx;\\n }\\n\\n /**\\n * @notice Add liquidity to the pool\\n * @param self Swap struct to read from and write to\\n * @param amounts the amounts of each token to add, in their native precision\\n * @param minToMint the minimum LP tokens adding this amount of liquidity\\n * should mint, otherwise revert. Handy for front-running mitigation\\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\\n * @return amount of LP token user received\\n */\\n function addLiquidity(\\n Swap storage self,\\n uint256[] memory amounts,\\n uint256 minToMint\\n ) internal returns (uint256) {\\n uint256 numTokens = self.pooledTokens.length;\\n require(amounts.length == numTokens, \\\"mismatch pooled tokens\\\");\\n\\n // current state\\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\\n 0,\\n 0,\\n 0,\\n _getAPrecise(self),\\n self.lpToken,\\n 0,\\n self.balances,\\n self.tokenPrecisionMultipliers\\n );\\n v.totalSupply = v.lpToken.totalSupply();\\n if (v.totalSupply != 0) {\\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\\n }\\n\\n uint256[] memory newBalances = new uint256[](numTokens);\\n\\n for (uint256 i; i < numTokens; ) {\\n require(v.totalSupply != 0 || amounts[i] != 0, \\\"!supply all tokens\\\");\\n\\n // Transfer tokens first to see if a fee was charged on transfer\\n if (amounts[i] != 0) {\\n IERC20 token = self.pooledTokens[i];\\n uint256 beforeBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), amounts[i]);\\n\\n // Update the amounts[] with actual transfer amount\\n amounts[i] = token.balanceOf(address(this)) - beforeBalance;\\n }\\n\\n newBalances[i] = v.balances[i] + amounts[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // invariant after change\\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\\n require(v.d1 > v.d0, \\\"D should increase\\\");\\n\\n // updated to reflect fees and calculate the user's LP tokens\\n v.d2 = v.d1;\\n uint256[] memory fees = new uint256[](numTokens);\\n\\n if (v.totalSupply != 0) {\\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\\n for (uint256 i; i < numTokens; ) {\\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\\n fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / FEE_DENOMINATOR;\\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\\n self.balances[i] = newBalances[i] - adminFee;\\n self.adminFees[i] = self.adminFees[i] + adminFee;\\n newBalances[i] = newBalances[i] - fees[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\\n } else {\\n // the initial depositor doesn't pay fees\\n self.balances = newBalances;\\n }\\n\\n uint256 toMint;\\n if (v.totalSupply == 0) {\\n toMint = v.d1;\\n } else {\\n toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\\n }\\n\\n require(toMint >= minToMint, \\\"mint < min\\\");\\n\\n // mint the user's LP tokens\\n v.lpToken.mint(msg.sender, toMint);\\n\\n emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\\n\\n return toMint;\\n }\\n\\n /**\\n * @notice Burn LP tokens to remove liquidity from the pool.\\n * @dev Liquidity can always be removed, even when the pool is paused.\\n * @param self Swap struct to read from and write to\\n * @param amount the amount of LP tokens to burn\\n * @param minAmounts the minimum amounts of each token in the pool\\n * acceptable for this burn. Useful as a front-running mitigation\\n * @return amounts of tokens the user received\\n */\\n function removeLiquidity(\\n Swap storage self,\\n uint256 amount,\\n uint256[] calldata minAmounts\\n ) internal returns (uint256[] memory) {\\n LPToken lpToken = self.lpToken;\\n require(amount <= lpToken.balanceOf(msg.sender), \\\">LP.balanceOf\\\");\\n uint256 numTokens = self.pooledTokens.length;\\n require(minAmounts.length == numTokens, \\\"mismatch poolTokens\\\");\\n\\n uint256[] memory balances = self.balances;\\n uint256 totalSupply = lpToken.totalSupply();\\n\\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\\n\\n uint256 numAmounts = amounts.length;\\n for (uint256 i; i < numAmounts; ) {\\n require(amounts[i] >= minAmounts[i], \\\"amounts[i] < minAmounts[i]\\\");\\n self.balances[i] = balances[i] - amounts[i];\\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n lpToken.burnFrom(msg.sender, amount);\\n\\n emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\\n\\n return amounts;\\n }\\n\\n /**\\n * @notice Remove liquidity from the pool all in one token.\\n * @param self Swap struct to read from and write to\\n * @param tokenAmount the amount of the lp tokens to burn\\n * @param tokenIndex the index of the token you want to receive\\n * @param minAmount the minimum amount to withdraw, otherwise revert\\n * @return amount chosen token that user received\\n */\\n function removeLiquidityOneToken(\\n Swap storage self,\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 minAmount\\n ) internal returns (uint256) {\\n LPToken lpToken = self.lpToken;\\n\\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \\\">LP.balanceOf\\\");\\n uint256 numTokens = self.pooledTokens.length;\\n require(tokenIndex < numTokens, \\\"not found\\\");\\n\\n uint256 totalSupply = lpToken.totalSupply();\\n\\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\\n\\n require(dy >= minAmount, \\\"dy < minAmount\\\");\\n\\n uint256 adminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR;\\n self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\\n if (adminFee != 0) {\\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\\n }\\n lpToken.burnFrom(msg.sender, tokenAmount);\\n self.pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\\n\\n emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\\n\\n return dy;\\n }\\n\\n /**\\n * @notice Remove liquidity from the pool, weighted differently than the\\n * pool's current balances.\\n *\\n * @param self Swap struct to read from and write to\\n * @param amounts how much of each token to withdraw\\n * @param maxBurnAmount the max LP token provider is willing to pay to\\n * remove liquidity. Useful as a front-running mitigation.\\n * @return actual amount of LP tokens burned in the withdrawal\\n */\\n function removeLiquidityImbalance(\\n Swap storage self,\\n uint256[] memory amounts,\\n uint256 maxBurnAmount\\n ) internal returns (uint256) {\\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\\n 0,\\n 0,\\n 0,\\n _getAPrecise(self),\\n self.lpToken,\\n 0,\\n self.balances,\\n self.tokenPrecisionMultipliers\\n );\\n v.totalSupply = v.lpToken.totalSupply();\\n\\n uint256 numTokens = self.pooledTokens.length;\\n uint256 numAmounts = amounts.length;\\n require(numAmounts == numTokens, \\\"mismatch pool tokens\\\");\\n\\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \\\">LP.balanceOf\\\");\\n\\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\\n uint256[] memory fees = new uint256[](numTokens);\\n {\\n uint256[] memory balances1 = new uint256[](numTokens);\\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\\n for (uint256 i; i < numTokens; ) {\\n require(v.balances[i] >= amounts[i], \\\"withdraw more than available\\\");\\n\\n unchecked {\\n balances1[i] = v.balances[i] - amounts[i];\\n ++i;\\n }\\n }\\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\\n\\n for (uint256 i; i < numTokens; ) {\\n {\\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\\n uint256 difference = idealBalance.difference(balances1[i]);\\n fees[i] = (feePerToken * difference) / FEE_DENOMINATOR;\\n }\\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\\n self.balances[i] = balances1[i] - adminFee;\\n self.adminFees[i] = self.adminFees[i] + adminFee;\\n balances1[i] = balances1[i] - fees[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\\n }\\n uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\\n require(tokenAmount != 0, \\\"!zero amount\\\");\\n tokenAmount = tokenAmount + 1;\\n\\n require(tokenAmount <= maxBurnAmount, \\\"tokenAmount > maxBurnAmount\\\");\\n\\n v.lpToken.burnFrom(msg.sender, tokenAmount);\\n\\n for (uint256 i; i < numTokens; ) {\\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\\n\\n return tokenAmount;\\n }\\n\\n /**\\n * @notice withdraw all admin fees to a given address\\n * @param self Swap struct to withdraw fees from\\n * @param to Address to send the fees to\\n */\\n function withdrawAdminFees(Swap storage self, address to) internal {\\n uint256 numTokens = self.pooledTokens.length;\\n for (uint256 i; i < numTokens; ) {\\n IERC20 token = self.pooledTokens[i];\\n uint256 balance = self.adminFees[i];\\n if (balance != 0) {\\n self.adminFees[i] = 0;\\n token.safeTransfer(to, balance);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Sets the admin fee\\n * @dev adminFee cannot be higher than 100% of the swap fee\\n * @param self Swap struct to update\\n * @param newAdminFee new admin fee to be applied on future transactions\\n */\\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\\n require(newAdminFee <= MAX_ADMIN_FEE, \\\"too high\\\");\\n self.adminFee = newAdminFee;\\n\\n emit NewAdminFee(self.key, newAdminFee);\\n }\\n\\n /**\\n * @notice update the swap fee\\n * @dev fee cannot be higher than 1% of each swap\\n * @param self Swap struct to update\\n * @param newSwapFee new swap fee to be applied on future transactions\\n */\\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\\n require(newSwapFee <= MAX_SWAP_FEE, \\\"too high\\\");\\n self.swapFee = newSwapFee;\\n\\n emit NewSwapFee(self.key, newSwapFee);\\n }\\n\\n /**\\n * @notice Check if this stableswap pool exists and is valid (i.e. has been\\n * initialized and tokens have been added).\\n * @return bool true if this stableswap pool is valid, false if not.\\n */\\n function exists(Swap storage self) internal view returns (bool) {\\n return self.pooledTokens.length != 0;\\n }\\n}\\n\",\"keccak256\":\"0x3da6aa3cd7cf97886db9958cbb174b8edaf7771aebce5da2a8d87e993a8301fa\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport {IOutbox} from \\\"./IOutbox.sol\\\";\\n\\n/**\\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\\n * allows an admin to call `setXAppConnectionManager` to update the underlying\\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\\n *\\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\\n * will interface with.\\n */\\ninterface IConnectorManager {\\n /**\\n * @notice Get the local inbox contract from the xAppConnectionManager\\n * @return The local inbox contract\\n * @dev The local inbox contract is a SpokeConnector with AMBs, and a\\n * Home contract with nomad\\n */\\n function home() external view returns (IOutbox);\\n\\n /**\\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\\n * @return True if _potentialReplica is an enrolled Replica\\n */\\n function isReplica(address _potentialReplica) external view returns (bool);\\n\\n /**\\n * @notice Get the local domain from the xAppConnectionManager\\n * @return The local domain\\n */\\n function localDomain() external view returns (uint32);\\n}\\n\",\"keccak256\":\"0xa2c9a88a7b76a89615fe199d8a78878e5deb8dd13b036a86b575d31966beab1a\",\"license\":\"MIT OR Apache-2.0\"},\"@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity 0.8.15;\\n\\n/**\\n * @notice Interface for all contracts sending messages originating on their\\n * current domain.\\n *\\n * @dev These are the Home.sol interface methods used by the `Router`\\n * and exposed via `home()` on the `XAppConnectionClient`\\n */\\ninterface IOutbox {\\n /**\\n * @notice Emitted when a new message is added to an outbound message merkle root\\n * @param leafIndex Index of message's leaf in merkle tree\\n * @param destinationAndNonce Destination and destination-specific\\n * nonce combined in single field ((destination << 32) & nonce)\\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\\n * @param committedRoot the latest notarized root submitted in the last signed Update\\n * @param message Raw bytes of message\\n */\\n event Dispatch(\\n bytes32 indexed messageHash,\\n uint256 indexed leafIndex,\\n uint64 indexed destinationAndNonce,\\n bytes32 committedRoot,\\n bytes message\\n );\\n\\n /**\\n * @notice Dispatch the message it to the destination domain & recipient\\n * @dev Format the message, insert its hash into Merkle tree,\\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\\n * @param _destinationDomain Domain of destination chain\\n * @param _recipientAddress Address of recipient on destination chain as bytes32\\n * @param _messageBody Raw bytes content of message\\n * @return bytes32 The leaf added to the tree\\n */\\n function dispatch(\\n uint32 _destinationDomain,\\n bytes32 _recipientAddress,\\n bytes memory _messageBody\\n ) external returns (bytes32);\\n}\\n\",\"keccak256\":\"0xe6a213bd3c9e0c4dcf0e982cdef2a6a613a49b7bca3d6ad662c179e509de6c2b\",\"license\":\"MIT OR Apache-2.0\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.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 IERC20Upgradeable {\\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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\\n function __ERC20Burnable_init() internal onlyInitializing {\\n }\\n\\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xea2c6f9d434127bf36b1e3e5ebaaf6d28a64dbaeea560508e570014e905a5ad2\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\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\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 > 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 >= 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 functionCall(target, data, \\\"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(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) 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(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) 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 >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // Look for revert reason and bubble it up if present\\n if (returndata.length > 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}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/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\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= 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 > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 > 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 >= 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 functionCall(target, data, \\\"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(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) 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(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) 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 >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // Look for revert reason and bubble it up if present\\n if (returndata.length > 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}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"solidity/contracts/bridges/BridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IBridgeReceiverAdapter.sol';\\n\\nabstract contract BridgeReceiverAdapter is IBridgeReceiverAdapter {\\n /// @inheritdoc IBridgeReceiverAdapter\\n IDataReceiver public immutable dataReceiver;\\n\\n constructor(IDataReceiver _dataReceiver) {\\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\\n dataReceiver = _dataReceiver;\\n }\\n\\n function _addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) internal {\\n dataReceiver.addObservations(_observationsData, _poolSalt, _poolNonce);\\n }\\n}\\n\",\"keccak256\":\"0x9242c7b33b40003d937f4facdc0aeb0e121ad4574c1191fe0d543eec0c3552b0\",\"license\":\"MIT\"},\"solidity/contracts/bridges/ConnextReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {BridgeReceiverAdapter} from './BridgeReceiverAdapter.sol';\\nimport {IConnext, IXReceiver, IConnextReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IConnextReceiverAdapter.sol';\\n\\ncontract ConnextReceiverAdapter is IConnextReceiverAdapter, BridgeReceiverAdapter {\\n /// @inheritdoc IConnextReceiverAdapter\\n IConnext public immutable connext;\\n\\n /// @inheritdoc IConnextReceiverAdapter\\n address public immutable source;\\n\\n /// @inheritdoc IConnextReceiverAdapter\\n uint32 public immutable originDomain;\\n\\n constructor(\\n IDataReceiver _dataReceiver,\\n IConnext _connext,\\n address _source,\\n uint32 _originDomain\\n ) BridgeReceiverAdapter(_dataReceiver) {\\n if (address(_connext) == address(0) || _source == address(0)) revert ZeroAddress();\\n connext = _connext;\\n source = _source;\\n originDomain = _originDomain;\\n }\\n\\n /// @inheritdoc IXReceiver\\n function xReceive(\\n bytes32, // _transferId\\n uint256, // _amount\\n address, // _asset\\n address _originSender,\\n uint32 _origin,\\n bytes memory _callData\\n ) external onlyExecutor(_originSender, _origin) returns (bytes memory) {\\n (IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, uint24 _poolNonce) = abi.decode(\\n _callData,\\n (IOracleSidechain.ObservationData[], bytes32, uint24)\\n );\\n\\n _addObservations(_observationsData, _poolSalt, _poolNonce);\\n }\\n\\n modifier onlyExecutor(address _originSender, uint32 _originDomain) {\\n if (msg.sender != address(connext) || _originSender != source || _originDomain != originDomain) revert UnauthorizedCaller();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x7895c6ee2da8eca15d2960a39bec9a7c0093bd33d094f0e0c751e96231951968\",\"license\":\"MIT\"},\"solidity/interfaces/IDataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleFactory} from './IOracleFactory.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\\n\\ninterface IDataReceiver is IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @notice Tracks already deployed oracles\\n /// @param _poolSalt The identifier of the oracle\\n /// @return _deployedOracle The address of the correspondant Oracle\\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\\n\\n /// @notice Tracks the whitelisting of bridge adapters\\n /// @param _adapter Address of the bridge adapter to consult\\n /// @return _isAllowed Whether a bridge adapter is whitelisted\\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a broadcast observation is succesfully processed\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsAdded(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a broadcast observation is cached for later processing\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsCached(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a new adapter whitelisting rule is set\\n /// @param _adapter Address of the adapter\\n /// @param _isAllowed New whitelisting status\\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\\n\\n // ERRORS\\n\\n /// @notice Thrown when the broadcast nonce is incorrect\\n error ObservationsNotWritable();\\n\\n /// @notice Thrown when a not-whitelisted adapter triggers an update\\n error UnallowedAdapter();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows whitelisted bridge adapters to push a broadcast\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _poolNonce Nonce of the observation broadcast\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external;\\n\\n /// @notice Allows any address to attempt to insert cached observations\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _maxObservations Maximum number of observations to process\\n /// @dev Use _maxObservations = 0 to process all possible cached observations\\n function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external;\\n\\n /// @notice Allows governance to set an adapter whitelisted state\\n /// @param _receiverAdapter Address of the adapter\\n /// @param _isWhitelisted New whitelisting status\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\\n\\n /// @notice Allows governance to batch set adapters whitelisted state\\n /// @param _receiverAdapters Array of addresses of the adapter\\n /// @param _isWhitelisted Array of whitelisting status for each address\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\\n}\\n\",\"keccak256\":\"0xd07e75380d5086ea78909bc5c80aadc110903004f50c006b0281cc090f273291\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IDataReceiver} from './IDataReceiver.sol';\\n\\ninterface IOracleFactory is IGovernable {\\n // STRUCTS\\n\\n struct OracleParameters {\\n bytes32 poolSalt; // Identifier of the pool and oracle\\n uint24 poolNonce; // Initial nonce of the deployed pool\\n uint16 cardinality; // Initial cardinality of the deployed pool\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\\n //solhint-disable-next-line func-name-mixedcase\\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\\n\\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /// @return _poolSalt The id of both the oracle and the pool\\n /// @return _poolNonce The initial nonce of the pool data\\n /// @return _cardinality The size of the observations memory storage\\n function oracleParameters()\\n external\\n view\\n returns (\\n bytes32 _poolSalt,\\n uint24 _poolNonce,\\n uint16 _cardinality\\n );\\n\\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function initialCardinality() external view returns (uint16 _initialCardinality);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new oracle is deployed\\n /// @param _poolSalt The id of both the oracle and the pool\\n /// @param _oracle The address of the deployed oracle\\n /// @param _initialNonce The initial nonce of the pool data\\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\\n\\n /// @notice Emitted when a new DataReceiver is set\\n /// @param _dataReceiver The address of the new DataReceiver\\n event DataReceiverSet(IDataReceiver _dataReceiver);\\n\\n /// @notice Emitted when a new initial oracle cardinality is set\\n /// @param _initialCardinality The initial length of the observationCardinality array\\n event InitialCardinalitySet(uint16 _initialCardinality);\\n\\n // ERRORS\\n\\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\\n error OnlyDataReceiver();\\n\\n // FUNCTIONS\\n\\n /// @notice Deploys a new oracle given an inputted salt\\n /// @dev Requires that the salt has not been deployed before\\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\\n /// @return _oracle The address of the newly deployed oracle\\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\\n\\n /// @notice Allows governor to set a new allowed dataReceiver\\n /// @dev Will disallow the previous dataReceiver\\n /// @param _dataReceiver The address of the new allowed dataReceiver\\n function setDataReceiver(IDataReceiver _dataReceiver) external;\\n\\n /// @notice Allows governor to set a new initial cardinality for new oracles\\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function setInitialCardinality(uint16 _initialCardinality) external;\\n\\n /// @notice Overrides UniV3Factory getPool mapping\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _oracle The oracle address\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle);\\n\\n /// @notice Tracks the addresses of the oracle by poolSalt\\n /// @param _poolSalt Identifier of both the pool and the oracle\\n /// @return _oracle The address (if deployed) of the correspondant oracle\\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\\n\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _poolSalt Pool salt for inquired parameters\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (bytes32 _poolSalt);\\n}\\n\",\"keccak256\":\"0xc32bfc32a274923ce1a089acc024396e702ae354773f0ac0a683e43ded904954\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleFactory} from './IOracleFactory.sol';\\n\\ninterface IOracleSidechain {\\n // STRUCTS\\n\\n struct ObservationData {\\n uint32 blockTimestamp;\\n int24 tick;\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function factory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @return _token0 The mainnet address of the Token0 of the oracle\\n function token0() external view returns (address _token0);\\n\\n /// @return _token1 The mainnet address of the Token1 of the oracle\\n function token1() external view returns (address _token1);\\n\\n /// @return _fee The fee identifier of the pool\\n function fee() external view returns (uint24 _fee);\\n\\n /// @return _poolSalt The identifier of both the pool and the oracle\\n function poolSalt() external view returns (bytes32 _poolSalt);\\n\\n /// @return _poolNonce Last recorded nonce of the pool history\\n function poolNonce() external view returns (uint24 _poolNonce);\\n\\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\\n /// @return _tick Used to maintain compatibility with Uniswap V3\\n /// @return _observationIndex The index of the last oracle observation that was written,\\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\\n /// @return _unlocked Used to track if a pool information was already verified\\n function slot0()\\n external\\n view\\n returns (\\n uint160 _sqrtPriceX96,\\n int24 _tick,\\n uint16 _observationIndex,\\n uint16 _observationCardinality,\\n uint16 _observationCardinalityNext,\\n uint8 _feeProtocol,\\n bool _unlocked\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param _index The element of the observations array to fetch\\n /// @return _blockTimestamp The timestamp of the observation,\\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// @return _initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 _index)\\n external\\n view\\n returns (\\n uint32 _blockTimestamp,\\n int56 _tickCumulative,\\n uint160 _secondsPerLiquidityCumulativeX128,\\n bool _initialized\\n );\\n\\n // EVENTS\\n\\n /// @notice Emitted when the pool information is verified\\n /// @param _poolSalt Identifier of the pool and the oracle\\n /// @param _token0 The contract address of either token0 or token1\\n /// @param _token1 The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\\n\\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param _tick The log base 1.0001 of price of the pool after the swap\\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\\n\\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\\n\\n // ERRORS\\n\\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\\n error AI();\\n\\n /// @notice Thrown if the pool info does not correspond to the pool salt\\n error InvalidPool();\\n\\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\\n error OnlyDataReceiver();\\n\\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\\n error OnlyFactory();\\n\\n // FUNCTIONS\\n\\n /// @notice Permisionless method to verify token0, token1 and fee\\n /// @dev Before verified, token0 and token1 views will return address(0)\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external;\\n\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\\n\\n /// @notice Permisioned method to push a dataset to update\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolNonce Nonce of the observation broadcast\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\\n\\n /// @notice Permisioned method to increase the cardinalityNext value\\n /// @param _observationCardinalityNext The new next length of the observations array\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa90206e3de00ad866b7f4792ce29220ee0ca561d59629ba638a31c4d6fd3941b\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IBridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport {IDataReceiver} from '../IDataReceiver.sol';\\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\\n\\ninterface IBridgeReceiverAdapter is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @notice Gets the address of the DataReceiver contract\\n /// @return _dataReceiver Address of the DataReceiver contract\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /* NOTE: callback methods should be here declared */\\n}\\n\",\"keccak256\":\"0x49e5c9c6a28521933a3f2b01a529fbae9aac1edd71dbe904586a2f06148b1974\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IConnextReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from './IBridgeReceiverAdapter.sol';\\n\\ninterface IConnextReceiverAdapter is IXReceiver, IBridgeReceiverAdapter {\\n // STATE VARIABLES\\n\\n /// @notice Gets the ConnextHandler contract on this domain\\n /// @return _connext Address of the ConnextHandler contract\\n function connext() external view returns (IConnext _connext);\\n\\n /// @notice Gets the DAO that is expected as the xcaller\\n /// @return _originContract Address of the xcaller contract\\n function source() external view returns (address _originContract);\\n\\n /// @notice Gets the origin domain id\\n /// @return _originDomain The origin domain id\\n function originDomain() external view returns (uint32 _originDomain);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a caller is not authorized\\n error UnauthorizedCaller();\\n}\\n\",\"keccak256\":\"0x382097cdc88bb383c1aec1ec6ebddf9e6ba5b87b405650432e85616acd03e218\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b506040516107e33803806107e3833981016040819052610030916100d3565b836001600160a01b0381166100585760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b039081166080528316158061007b57506001600160a01b038216155b156100995760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0392831660a052911660c05263ffffffff1660e0525061013b565b6001600160a01b03811681146100d057600080fd5b50565b600080600080608085870312156100e957600080fd5b84516100f4816100bb565b6020860151909450610105816100bb565b6040860151909350610116816100bb565b606086015190925063ffffffff8116811461013057600080fd5b939692955090935050565b60805160a05160c05160e05161065661018d6000396000818160a501526101c00152600081816061015261018301526000818160e10152610159015260008181610108015261025d01526106566000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806367e828bf1461005c578063cee85d7e146100a0578063de4b0548146100dc578063e804778814610103578063fd614f411461012a575b600080fd5b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c77f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610097565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b61013d61013836600461036e565b61014a565b6040516100979190610449565b60608383336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806101b857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b806101ef57507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1614155b1561020d57604051635c427cd960e01b815260040160405180910390fd5b60008060008680602001905181019061022691906104b1565b925092509250610237838383610246565b50505050509695505050505050565b60405163d34ad40960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d34ad40990610296908690869086906004016105b5565b600060405180830381600087803b1580156102b057600080fd5b505af11580156102c4573d6000803e3d6000fd5b50505050505050565b80356001600160a01b03811681146102e457600080fd5b919050565b63ffffffff811681146102fb57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610337576103376102fe565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610366576103666102fe565b604052919050565b60008060008060008060c0878903121561038757600080fd5b86359550602080880135955061039f604089016102cd565b94506103ad606089016102cd565b935060808801356103bd816102e9565b925060a088013567ffffffffffffffff808211156103da57600080fd5b818a0191508a601f8301126103ee57600080fd5b813581811115610400576104006102fe565b610412601f8201601f1916850161033d565b91508082528b8482850101111561042857600080fd5b80848401858401376000848284010152508093505050509295509295509295565b600060208083528351808285015260005b818110156104765785810183015185820160400152820161045a565b81811115610488576000604083870101525b50601f01601f1916929092016040019392505050565b805162ffffff811681146102e457600080fd5b6000806000606084860312156104c657600080fd5b835167ffffffffffffffff808211156104de57600080fd5b818601915086601f8301126104f257600080fd5b8151602082821115610506576105066102fe565b610514818360051b0161033d565b828152818101935060069290921b84018101918983111561053457600080fd5b938101935b82851015610592576040858b0312156105525760008081fd5b61055a610314565b8551610565816102e9565b815285830151600281900b811461057c5760008081fd5b8184015284526040949094019392810192610539565b80975050808801519550505050506105ac6040850161049e565b90509250925092565b606080825284519082018190526000906020906080840190828801845b82811015610602578151805163ffffffff16855285015160020b85850152604090930192908401906001016105d2565b505050908301949094525062ffffff9190911660409091015291905056fea26469706673582212202c12c0bf792175159d5e1c1f0caa4f166cc61f5519e6f66b2bb8f2fa8cad462564736f6c634300080f0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c806367e828bf1461005c578063cee85d7e146100a0578063de4b0548146100dc578063e804778814610103578063fd614f411461012a575b600080fd5b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c77f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610097565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b61013d61013836600461036e565b61014a565b6040516100979190610449565b60608383336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806101b857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b806101ef57507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1614155b1561020d57604051635c427cd960e01b815260040160405180910390fd5b60008060008680602001905181019061022691906104b1565b925092509250610237838383610246565b50505050509695505050505050565b60405163d34ad40960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d34ad40990610296908690869086906004016105b5565b600060405180830381600087803b1580156102b057600080fd5b505af11580156102c4573d6000803e3d6000fd5b50505050505050565b80356001600160a01b03811681146102e457600080fd5b919050565b63ffffffff811681146102fb57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610337576103376102fe565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610366576103666102fe565b604052919050565b60008060008060008060c0878903121561038757600080fd5b86359550602080880135955061039f604089016102cd565b94506103ad606089016102cd565b935060808801356103bd816102e9565b925060a088013567ffffffffffffffff808211156103da57600080fd5b818a0191508a601f8301126103ee57600080fd5b813581811115610400576104006102fe565b610412601f8201601f1916850161033d565b91508082528b8482850101111561042857600080fd5b80848401858401376000848284010152508093505050509295509295509295565b600060208083528351808285015260005b818110156104765785810183015185820160400152820161045a565b81811115610488576000604083870101525b50601f01601f1916929092016040019392505050565b805162ffffff811681146102e457600080fd5b6000806000606084860312156104c657600080fd5b835167ffffffffffffffff808211156104de57600080fd5b818601915086601f8301126104f257600080fd5b8151602082821115610506576105066102fe565b610514818360051b0161033d565b828152818101935060069290921b84018101918983111561053457600080fd5b938101935b82851015610592576040858b0312156105525760008081fd5b61055a610314565b8551610565816102e9565b815285830151600281900b811461057c5760008081fd5b8184015284526040949094019392810192610539565b80975050808801519550505050506105ac6040850161049e565b90509250925092565b606080825284519082018190526000906020906080840190828801845b82811015610602578151805163ffffffff16855285015160020b85850152604090930192908401906001016105d2565b505050908301949094525062ffffff9190911660409091015291905056fea26469706673582212202c12c0bf792175159d5e1c1f0caa4f166cc61f5519e6f66b2bb8f2fa8cad462564736f6c634300080f0033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/optimism/DataReceiver.json b/deployments/optimism/DataReceiver.json index 5019e61..461b0a3 100644 --- a/deployments/optimism/DataReceiver.json +++ b/deployments/optimism/DataReceiver.json @@ -1,5 +1,5 @@ { - "address": "0x5b9315CE1304DF3B2A83B2074cbF849D160642Ab", + "address": "0x4E0CeF6426eb70b5708845825A5375688808891d", "abi": [ { "inputs": [ @@ -97,22 +97,29 @@ "type": "uint24" }, { - "components": [ - { - "internalType": "uint32", - "name": "blockTimestamp", - "type": "uint32" - }, - { - "internalType": "int24", - "name": "tick", - "type": "int24" - } - ], "indexed": false, - "internalType": "struct IOracleSidechain.ObservationData[]", - "name": "_observationsData", - "type": "tuple[]" + "internalType": "address", + "name": "_receiverAdapter", + "type": "address" + } + ], + "name": "ObservationsAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint24", + "name": "_poolNonce", + "type": "uint24" }, { "indexed": false, @@ -121,7 +128,7 @@ "type": "address" } ], - "name": "ObservationsAdded", + "name": "ObservationsCached", "type": "event" }, { @@ -269,6 +276,24 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_maxObservations", + "type": "uint256" + } + ], + "name": "syncObservations", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -325,31 +350,31 @@ "type": "function" } ], - "transactionHash": "0x9eaa47969360283dd25e99e4f079796a756b154c891e248b2e9d7bf527f0c2d4", + "transactionHash": "0x39ae68e7ecc1db923f6710fa2df888a8a67bc4cdc323cedd0e527d32b401df94", "receipt": { "to": null, - "from": "0xb7157Be5c36aE31344e13F49bb4d55066DbB6aC4", - "contractAddress": "0x5b9315CE1304DF3B2A83B2074cbF849D160642Ab", - "transactionIndex": 0, - "gasUsed": "697499", + "from": "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "contractAddress": "0x4E0CeF6426eb70b5708845825A5375688808891d", + "transactionIndex": 13, + "gasUsed": "1025842", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf032d6fc0f414f772c786bf6d3db949b4555ba89479d374e6f8444c6c9fdd486", - "transactionHash": "0x9eaa47969360283dd25e99e4f079796a756b154c891e248b2e9d7bf527f0c2d4", + "blockHash": "0x0f184f23afee06b5b2907eab97d9ddeaf28e1007fb5528c01df68038afa2045d", + "transactionHash": "0x39ae68e7ecc1db923f6710fa2df888a8a67bc4cdc323cedd0e527d32b401df94", "logs": [], - "blockNumber": 72611793, - "cumulativeGasUsed": "697499", + "blockNumber": 124330027, + "cumulativeGasUsed": "6426575", "status": 1, "byzantium": true }, "args": [ - "0xb7157Be5c36aE31344e13F49bb4d55066DbB6aC4", - "0x1ce81290Eb4c10cC9Fa71256799665423e87b628" + "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "0x0BcD059c1546359b45f2606Ed6E08e1F5ef4f4Bf" ], - "numDeployments": 2, - "solcInputHash": "1a064550c306047de745b0aa850ace2a", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract IOracleFactory\",\"name\":\"_oracleFactory\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ObservationsNotWritable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnallowedAdapter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IBridgeReceiverAdapter\",\"name\":\"_adapter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isAllowed\",\"type\":\"bool\"}],\"name\":\"AdapterWhitelisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"_poolNonce\",\"type\":\"uint24\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockTimestamp\",\"type\":\"uint32\"},{\"internalType\":\"int24\",\"name\":\"tick\",\"type\":\"int24\"}],\"indexed\":false,\"internalType\":\"struct IOracleSidechain.ObservationData[]\",\"name\":\"_observationsData\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_receiverAdapter\",\"type\":\"address\"}],\"name\":\"ObservationsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockTimestamp\",\"type\":\"uint32\"},{\"internalType\":\"int24\",\"name\":\"tick\",\"type\":\"int24\"}],\"internalType\":\"struct IOracleSidechain.ObservationData[]\",\"name\":\"_observationsData\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"_poolNonce\",\"type\":\"uint24\"}],\"name\":\"addObservations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deployedOracles\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleFactory\",\"outputs\":[{\"internalType\":\"contract IOracleFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"setPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBridgeReceiverAdapter\",\"name\":\"_receiverAdapter\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_isWhitelisted\",\"type\":\"bool\"}],\"name\":\"whitelistAdapter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBridgeReceiverAdapter[]\",\"name\":\"_receiverAdapters\",\"type\":\"address[]\"},{\"internalType\":\"bool[]\",\"name\":\"_isWhitelisted\",\"type\":\"bool[]\"}],\"name\":\"whitelistAdapters\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBridgeReceiverAdapter\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"whitelistedAdapters\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addObservations((uint32,int24)[],bytes32,uint24)\":{\"params\":{\"_observationsData\":\"Array of tuples containing the dataset\",\"_poolNonce\":\"Nonce of the observation broadcast\",\"_poolSalt\":\"Identifier of the pool to fetch\"}},\"setPendingGovernor(address)\":{\"params\":{\"_pendingGovernor\":\"Address of the proposed new governor\"}},\"whitelistAdapter(address,bool)\":{\"params\":{\"_isWhitelisted\":\"New whitelisting status\",\"_receiverAdapter\":\"Address of the adapter\"}},\"whitelistAdapters(address[],bool[])\":{\"params\":{\"_isWhitelisted\":\"Array of whitelisting status for each address\",\"_receiverAdapters\":\"Array of addresses of the adapter\"}}},\"stateVariables\":{\"deployedOracles\":{\"params\":{\"_poolSalt\":\"The identifier of the oracle\"},\"return\":\"The address of the correspondant Oracle\",\"returns\":{\"_0\":\"The address of the correspondant Oracle\"}},\"oracleFactory\":{\"return\":\"The address of the OracleFactory\",\"returns\":{\"_0\":\"The address of the OracleFactory\"}},\"whitelistedAdapters\":{\"params\":{\"_adapter\":\"Address of the bridge adapter to consult\"},\"return\":\"Whether a bridge adapter is whitelisted\",\"returns\":{\"_0\":\"Whether a bridge adapter is whitelisted\"}}},\"title\":\"The DataReceiver contract\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"ObservationsNotWritable()\":[{\"notice\":\"Thrown when the broadcast nonce is incorrect\"}],\"OnlyGovernor()\":[{\"notice\":\"Thrown if a non-governor user tries to call a OnlyGovernor function\"}],\"OnlyPendingGovernor()\":[{\"notice\":\"Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\"}],\"UnallowedAdapter()\":[{\"notice\":\"Thrown when a not-whitelisted adapter triggers an update\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"events\":{\"AdapterWhitelisted(address,bool)\":{\"notice\":\"Emitted when a new adapter whitelisting rule is set\"},\"ObservationsAdded(bytes32,uint24,(uint32,int24)[],address)\":{\"notice\":\"Emitted when a broadcast observation is succesfully processed\"},\"PendingGovernorAccepted(address)\":{\"notice\":\"Emitted when a new governor is set\"},\"PendingGovernorSet(address,address)\":{\"notice\":\"Emitted when a new pending governor is set\"}},\"kind\":\"user\",\"methods\":{\"acceptPendingGovernor()\":{\"notice\":\"Allows a proposed governor to accept the governance\"},\"addObservations((uint32,int24)[],bytes32,uint24)\":{\"notice\":\"Allows whitelisted bridge adapters to push a broadcast\"},\"deployedOracles(bytes32)\":{\"notice\":\"Tracks already deployed oracles\"},\"setPendingGovernor(address)\":{\"notice\":\"Allows a governor to propose a new governor\"},\"whitelistAdapter(address,bool)\":{\"notice\":\"Allows governance to set an adapter whitelisted state\"},\"whitelistAdapters(address[],bool[])\":{\"notice\":\"Allows governance to batch set adapters whitelisted state\"},\"whitelistedAdapters(address)\":{\"notice\":\"Tracks the whitelisting of bridge adapters\"}},\"notice\":\"Handles reception of broadcast data and delivers it to correspondant oracle\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/DataReceiver.sol\":\"DataReceiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '../interfaces/IGovernable.sol';\\n\\n/// @title Governable contract\\n/// @notice Manages the governor role\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public governor;\\n\\n /// @inheritdoc IGovernable\\n address public pendingGovernor;\\n\\n constructor(address _governor) {\\n if (_governor == address(0)) revert ZeroAddress();\\n governor = _governor;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\\n _setPendingGovernor(_pendingGovernor);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptPendingGovernor() external onlyPendingGovernor {\\n _acceptPendingGovernor();\\n }\\n\\n function _setPendingGovernor(address _pendingGovernor) internal {\\n if (_pendingGovernor == address(0)) revert ZeroAddress();\\n pendingGovernor = _pendingGovernor;\\n emit PendingGovernorSet(governor, _pendingGovernor);\\n }\\n\\n function _acceptPendingGovernor() internal {\\n governor = pendingGovernor;\\n delete pendingGovernor;\\n emit PendingGovernorAccepted(governor);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governor\\n modifier onlyGovernor() {\\n if (msg.sender != governor) revert OnlyGovernor();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernor\\n modifier onlyPendingGovernor() {\\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x3f11408cfcb015a99dc417e075c8ebc39b796fc2adc3e81b036487e4486881b3\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@uniswap/v3-core/contracts/libraries/Oracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.0;\\n\\n/// @title Oracle\\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\\n/// @dev Instances of stored oracle data, \\\"observations\\\", are collected in the oracle array\\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\\n/// Observations are overwritten when the full length of the oracle array is populated.\\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\\nlibrary Oracle {\\n error I();\\n error OLD();\\n\\n struct Observation {\\n // the block timestamp of the observation\\n uint32 blockTimestamp;\\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\\n int56 tickCumulative;\\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\\n uint160 secondsPerLiquidityCumulativeX128;\\n // whether or not the observation is initialized\\n bool initialized;\\n }\\n\\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\\n /// @param last The specified observation to be transformed\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @return Observation The newly populated observation\\n function transform(\\n Observation memory last,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity\\n ) private pure returns (Observation memory) {\\n unchecked {\\n uint32 delta = blockTimestamp - last.blockTimestamp;\\n return\\n Observation({\\n blockTimestamp: blockTimestamp,\\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\\n initialized: true\\n });\\n }\\n }\\n\\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\\n /// @param self The stored oracle array\\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\\n /// @return cardinality The number of populated elements in the oracle array\\n /// @return cardinalityNext The new length of the oracle array, independent of population\\n function initialize(Observation[65535] storage self, uint32 time)\\n internal\\n returns (uint16 cardinality, uint16 cardinalityNext)\\n {\\n self[0] = Observation({\\n blockTimestamp: time,\\n tickCumulative: 0,\\n secondsPerLiquidityCumulativeX128: 0,\\n initialized: true\\n });\\n return (1, 1);\\n }\\n\\n /// @notice Writes an oracle observation to the array\\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\\n /// @param self The stored oracle array\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @param cardinalityNext The new length of the oracle array, independent of population\\n /// @return indexUpdated The new index of the most recently written element in the oracle array\\n /// @return cardinalityUpdated The new cardinality of the oracle array\\n function write(\\n Observation[65535] storage self,\\n uint16 index,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity,\\n uint16 cardinality,\\n uint16 cardinalityNext\\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\\n unchecked {\\n Observation memory last = self[index];\\n\\n // early return if we've already written an observation this block\\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\\n\\n // if the conditions are right, we can bump the cardinality\\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\\n cardinalityUpdated = cardinalityNext;\\n } else {\\n cardinalityUpdated = cardinality;\\n }\\n\\n indexUpdated = (index + 1) % cardinalityUpdated;\\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\\n }\\n }\\n\\n /// @notice Prepares the oracle array to store up to `next` observations\\n /// @param self The stored oracle array\\n /// @param current The current next cardinality of the oracle array\\n /// @param next The proposed next cardinality which will be populated in the oracle array\\n /// @return next The next cardinality which will be populated in the oracle array\\n function grow(\\n Observation[65535] storage self,\\n uint16 current,\\n uint16 next\\n ) internal returns (uint16) {\\n unchecked {\\n if (current <= 0) revert I();\\n // no-op if the passed next value isn't greater than the current next value\\n if (next <= current) return current;\\n // store in each slot to prevent fresh SSTOREs in swaps\\n // this data will not be used because the initialized boolean is still false\\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\\n return next;\\n }\\n }\\n\\n /// @notice comparator for 32-bit timestamps\\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\\n /// @param time A timestamp truncated to 32 bits\\n /// @param a A comparison timestamp from which to determine the relative position of `time`\\n /// @param b From which to determine the relative position of `time`\\n /// @return Whether `a` is chronologically <= `b`\\n function lte(\\n uint32 time,\\n uint32 a,\\n uint32 b\\n ) private pure returns (bool) {\\n unchecked {\\n // if there hasn't been overflow, no need to adjust\\n if (a <= time && b <= time) return a <= b;\\n\\n uint256 aAdjusted = a > time ? a : a + 2**32;\\n uint256 bAdjusted = b > time ? b : b + 2**32;\\n\\n return aAdjusted <= bAdjusted;\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\\n /// The result may be the same observation, or adjacent observations.\\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation recorded before, or at, the target\\n /// @return atOrAfter The observation recorded at, or after, the target\\n function binarySearch(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n uint16 index,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n uint256 l = (index + 1) % cardinality; // oldest observation\\n uint256 r = l + cardinality - 1; // newest observation\\n uint256 i;\\n while (true) {\\n i = (l + r) / 2;\\n\\n beforeOrAt = self[i % cardinality];\\n\\n // we've landed on an uninitialized tick, keep searching higher (more recently)\\n if (!beforeOrAt.initialized) {\\n l = i + 1;\\n continue;\\n }\\n\\n atOrAfter = self[(i + 1) % cardinality];\\n\\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\\n\\n // check if we've found the answer!\\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\\n\\n if (!targetAtOrAfter) r = i - 1;\\n else l = i + 1;\\n }\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\\n /// @dev Assumes there is at least 1 initialized observation.\\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param tick The active tick at the time of the returned or simulated observation\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The total pool liquidity at the time of the call\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\\n function getSurroundingObservations(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n // optimistically set before to the newest observation\\n beforeOrAt = self[index];\\n\\n // if the target is chronologically at or after the newest observation, we can early return\\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\\n if (beforeOrAt.blockTimestamp == target) {\\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\\n return (beforeOrAt, atOrAfter);\\n } else {\\n // otherwise, we need to transform\\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\\n }\\n }\\n\\n // now, set before to the oldest observation\\n beforeOrAt = self[(index + 1) % cardinality];\\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\\n\\n // ensure that the target is chronologically at or after the oldest observation\\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\\n\\n // if we've reached this point, we have to binary search\\n return binarySearch(self, time, target, index, cardinality);\\n }\\n }\\n\\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\\n /// at exactly the timestamp between the two observations.\\n /// @param self The stored oracle array\\n /// @param time The current block timestamp\\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\\n function observeSingle(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 secondsAgo,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\\n unchecked {\\n if (secondsAgo == 0) {\\n Observation memory last = self[index];\\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\\n }\\n\\n uint32 target = time - secondsAgo;\\n\\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\\n self,\\n time,\\n target,\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n\\n if (target == beforeOrAt.blockTimestamp) {\\n // we're at the left boundary\\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\\n } else if (target == atOrAfter.blockTimestamp) {\\n // we're at the right boundary\\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\\n } else {\\n // we're in the middle\\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\\n return (\\n beforeOrAt.tickCumulative +\\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\\n int56(uint56(targetDelta)),\\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\\n uint160(\\n (uint256(\\n atOrAfter.secondsPerLiquidityCumulativeX128 -\\n beforeOrAt.secondsPerLiquidityCumulativeX128\\n ) * targetDelta) / observationTimeDelta\\n )\\n );\\n }\\n }\\n }\\n\\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\\n /// @dev Reverts if `secondsAgos` > oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\\n function observe(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32[] memory secondsAgos,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\\n unchecked {\\n if (cardinality <= 0) revert I();\\n\\n tickCumulatives = new int56[](secondsAgos.length);\\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\\n for (uint256 i = 0; i < secondsAgos.length; i++) {\\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\\n self,\\n time,\\n secondsAgos[i],\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa25b18af947c36b9add9e229c361beb6aba176fb435d7a24e6dc723cbc187442\",\"license\":\"BUSL-1.1\"},\"@uniswap/v3-core/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity ^0.8.0;\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n error T();\\n error R();\\n\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n unchecked {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n if (absTick > uint256(int256(MAX_TICK))) revert T();\\n\\n uint256 ratio = absTick & 0x1 != 0\\n ? 0xfffcb933bd6fad37aa2d162d1a594001\\n : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\\n /// ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n unchecked {\\n // second inequality must be < because the price can never reach the price at the max tick\\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5c57de03a91cc2ec8939865dbbcb0197bb6c353b711075eefd8e0fca5e102129\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/DataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\\nimport {OracleSidechain} from './OracleSidechain.sol';\\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\\n\\n/// @title The DataReceiver contract\\n/// @notice Handles reception of broadcast data and delivers it to correspondant oracle\\ncontract DataReceiver is IDataReceiver, Governable {\\n /// @inheritdoc IDataReceiver\\n IOracleFactory public immutable oracleFactory;\\n\\n /// @inheritdoc IDataReceiver\\n mapping(bytes32 => IOracleSidechain) public deployedOracles;\\n\\n /// @inheritdoc IDataReceiver\\n mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters;\\n\\n constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) {\\n if (address(_oracleFactory) == address(0)) revert ZeroAddress();\\n oracleFactory = _oracleFactory;\\n }\\n\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external onlyWhitelistedAdapters {\\n _addObservations(_observationsData, _poolSalt, _poolNonce);\\n }\\n\\n function _addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) internal {\\n // Read, store or deploy oracle given poolSalt\\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\\n if (address(_oracle) == address(0)) {\\n _oracle = oracleFactory.getPool(_poolSalt);\\n if (address(_oracle) == address(0)) {\\n _oracle = oracleFactory.deployOracle(_poolSalt, _poolNonce);\\n }\\n deployedOracles[_poolSalt] = _oracle;\\n }\\n // Try to write observations data into oracle\\n if (_oracle.write(_observationsData, _poolNonce)) {\\n emit ObservationsAdded(_poolSalt, _poolNonce, _observationsData, msg.sender);\\n } else {\\n revert ObservationsNotWritable();\\n }\\n }\\n\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor {\\n _whitelistAdapter(_receiverAdapter, _isWhitelisted);\\n }\\n\\n /// @inheritdoc IDataReceiver\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\\n uint256 _receiverAdapterLength = _receiverAdapters.length;\\n if (_receiverAdapterLength != _isWhitelisted.length) revert LengthMismatch();\\n unchecked {\\n for (uint256 _i; _i < _receiverAdapterLength; ++_i) {\\n _whitelistAdapter(_receiverAdapters[_i], _isWhitelisted[_i]);\\n }\\n }\\n }\\n\\n function _whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) internal {\\n whitelistedAdapters[_receiverAdapter] = _isWhitelisted;\\n emit AdapterWhitelisted(_receiverAdapter, _isWhitelisted);\\n }\\n\\n modifier onlyWhitelistedAdapters() {\\n if (!whitelistedAdapters[IBridgeReceiverAdapter(msg.sender)]) revert UnallowedAdapter();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xb8b6deddeca8c17fa187a6de137e806fa8f1fed59d2d99b100ef3cc7aa9b77b3\",\"license\":\"MIT\"},\"solidity/contracts/OracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\\n\\n/// @title The SidechainOracle contract\\n/// @notice Computes and stores on-chain price data from Mainnet\\ncontract OracleSidechain is IOracleSidechain {\\n using Oracle for Oracle.Observation[65535];\\n\\n /// @inheritdoc IOracleSidechain\\n IOracleFactory public immutable factory;\\n\\n struct Slot0 {\\n // the current price\\n uint160 sqrtPriceX96;\\n // the current tick\\n int24 tick;\\n // the most-recently updated index of the observations array\\n uint16 observationIndex;\\n // the current maximum number of observations that are being stored\\n uint16 observationCardinality;\\n // the next maximum number of observations to store, triggered in observations.write\\n uint16 observationCardinalityNext;\\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\\n // represented as an integer denominator (1/x)%\\n uint8 feeProtocol;\\n // whether the pool is locked\\n bool unlocked;\\n }\\n /// @inheritdoc IOracleSidechain\\n Slot0 public slot0;\\n\\n /// @inheritdoc IOracleSidechain\\n Oracle.Observation[65535] public observations;\\n\\n /// @inheritdoc IOracleSidechain\\n bytes32 public immutable poolSalt;\\n\\n uint24 public poolNonce;\\n /// @inheritdoc IOracleSidechain\\n address public token0;\\n /// @inheritdoc IOracleSidechain\\n address public token1;\\n /// @inheritdoc IOracleSidechain\\n uint24 public fee;\\n\\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\\n function _getBlockTimestamp() internal view virtual returns (uint32) {\\n return uint32(block.timestamp); // truncation is desired\\n }\\n\\n constructor() {\\n factory = IOracleFactory(msg.sender);\\n uint16 _cardinality;\\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\\n\\n slot0 = Slot0({\\n sqrtPriceX96: 0,\\n tick: 0,\\n observationIndex: _cardinality - 1,\\n observationCardinality: _cardinality,\\n observationCardinalityNext: _cardinality,\\n feeProtocol: 0,\\n unlocked: true\\n });\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external {\\n if (!slot0.unlocked) revert AI();\\n\\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\\n\\n token0 = _token0;\\n token1 = _token1;\\n fee = _fee;\\n slot0.unlocked = false;\\n\\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\\n {\\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\\n if (_poolNonce != poolNonce++) return false;\\n\\n uint256 _observationsDataLength = _observationsData.length;\\n for (uint256 _i; _i < _observationsDataLength; ) {\\n _write(_observationsData[_i]);\\n unchecked {\\n ++_i;\\n }\\n }\\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\\n\\n // emits UniV3 Swap event topic with minimal data\\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\\n return true;\\n }\\n\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\\n if (_observationCardinalityNext <= _observationCardinalityNextOld) revert AI();\\n slot0.observationCardinalityNext = _observationCardinalityNext;\\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\\n }\\n\\n function _write(ObservationData memory _observationData) private {\\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\\n slot0.observationIndex,\\n _observationData.blockTimestamp,\\n slot0.tick,\\n 0,\\n slot0.observationCardinality,\\n slot0.observationCardinalityNext\\n );\\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\\n slot0.tick = _observationData.tick;\\n }\\n\\n modifier onlyDataReceiver() {\\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\\n _;\\n }\\n\\n modifier onlyFactory() {\\n if (msg.sender != address(factory)) revert OnlyFactory();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x99aecf265a572613e65c6d10fe5d42637f7619b6f8039d9e61169ce97c36e92a\",\"license\":\"MIT\"},\"solidity/interfaces/IDataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleFactory} from './IOracleFactory.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\\n\\ninterface IDataReceiver is IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @notice Tracks already deployed oracles\\n /// @param _poolSalt The identifier of the oracle\\n /// @return _deployedOracle The address of the correspondant Oracle\\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\\n\\n /// @notice Tracks the whitelisting of bridge adapters\\n /// @param _adapter Address of the bridge adapter to consult\\n /// @return _isAllowed Whether a bridge adapter is whitelisted\\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a broadcast observation is succesfully processed\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _observationsData Array of tuples containing the dataset\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsAdded(\\n bytes32 indexed _poolSalt,\\n uint24 _poolNonce,\\n IOracleSidechain.ObservationData[] _observationsData,\\n address _receiverAdapter\\n );\\n\\n /// @notice Emitted when a new adapter whitelisting rule is set\\n /// @param _adapter Address of the adapter\\n /// @param _isAllowed New whitelisting status\\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\\n\\n // ERRORS\\n\\n /// @notice Thrown when the broadcast nonce is incorrect\\n error ObservationsNotWritable();\\n\\n /// @notice Thrown when a not-whitelisted adapter triggers an update\\n error UnallowedAdapter();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows whitelisted bridge adapters to push a broadcast\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _poolNonce Nonce of the observation broadcast\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external;\\n\\n /// @notice Allows governance to set an adapter whitelisted state\\n /// @param _receiverAdapter Address of the adapter\\n /// @param _isWhitelisted New whitelisting status\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\\n\\n /// @notice Allows governance to batch set adapters whitelisted state\\n /// @param _receiverAdapters Array of addresses of the adapter\\n /// @param _isWhitelisted Array of whitelisting status for each address\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\\n}\\n\",\"keccak256\":\"0x7970e1941b72624c5d92462a8648ffb95ee99e4132152cd720e13b45039df67c\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IDataReceiver} from './IDataReceiver.sol';\\n\\ninterface IOracleFactory is IGovernable {\\n // STRUCTS\\n\\n struct OracleParameters {\\n bytes32 poolSalt; // Identifier of the pool and oracle\\n uint24 poolNonce; // Initial nonce of the deployed pool\\n uint16 cardinality; // Initial cardinality of the deployed pool\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\\n //solhint-disable-next-line func-name-mixedcase\\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\\n\\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /// @return _poolSalt The id of both the oracle and the pool\\n /// @return _poolNonce The initial nonce of the pool data\\n /// @return _cardinality The size of the observations memory storage\\n function oracleParameters()\\n external\\n view\\n returns (\\n bytes32 _poolSalt,\\n uint24 _poolNonce,\\n uint16 _cardinality\\n );\\n\\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function initialCardinality() external view returns (uint16 _initialCardinality);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new oracle is deployed\\n /// @param _poolSalt The id of both the oracle and the pool\\n /// @param _oracle The address of the deployed oracle\\n /// @param _initialNonce The initial nonce of the pool data\\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\\n\\n /// @notice Emitted when a new DataReceiver is set\\n /// @param _dataReceiver The address of the new DataReceiver\\n event DataReceiverSet(IDataReceiver _dataReceiver);\\n\\n /// @notice Emitted when a new initial oracle cardinality is set\\n /// @param _initialCardinality The initial length of the observationCardinality array\\n event InitialCardinalitySet(uint16 _initialCardinality);\\n\\n // ERRORS\\n\\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\\n error OnlyDataReceiver();\\n\\n // FUNCTIONS\\n\\n /// @notice Deploys a new oracle given an inputted salt\\n /// @dev Requires that the salt has not been deployed before\\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\\n /// @return _oracle The address of the newly deployed oracle\\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\\n\\n /// @notice Allows governor to set a new allowed dataReceiver\\n /// @dev Will disallow the previous dataReceiver\\n /// @param _dataReceiver The address of the new allowed dataReceiver\\n function setDataReceiver(IDataReceiver _dataReceiver) external;\\n\\n /// @notice Allows governor to set a new initial cardinality for new oracles\\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function setInitialCardinality(uint16 _initialCardinality) external;\\n\\n /// @notice Overrides UniV3Factory getPool mapping\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _oracle The oracle address\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle);\\n\\n /// @notice Tracks the addresses of the oracle by poolSalt\\n /// @param _poolSalt Identifier of both the pool and the oracle\\n /// @return _oracle The address (if deployed) of the correspondant oracle\\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\\n\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _poolSalt Pool salt for inquired parameters\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (bytes32 _poolSalt);\\n}\\n\",\"keccak256\":\"0xc32bfc32a274923ce1a089acc024396e702ae354773f0ac0a683e43ded904954\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleFactory} from './IOracleFactory.sol';\\n\\ninterface IOracleSidechain {\\n // STRUCTS\\n\\n struct ObservationData {\\n uint32 blockTimestamp;\\n int24 tick;\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function factory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @return _token0 The mainnet address of the Token0 of the oracle\\n function token0() external view returns (address _token0);\\n\\n /// @return _token1 The mainnet address of the Token1 of the oracle\\n function token1() external view returns (address _token1);\\n\\n /// @return _fee The fee identifier of the pool\\n function fee() external view returns (uint24 _fee);\\n\\n /// @return _poolSalt The identifier of both the pool and the oracle\\n function poolSalt() external view returns (bytes32 _poolSalt);\\n\\n /// @return _poolNonce Last recorded nonce of the pool history\\n function poolNonce() external view returns (uint24 _poolNonce);\\n\\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\\n /// @return _tick Used to maintain compatibility with Uniswap V3\\n /// @return _observationIndex The index of the last oracle observation that was written,\\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\\n /// @return _unlocked Used to track if a pool information was already verified\\n function slot0()\\n external\\n view\\n returns (\\n uint160 _sqrtPriceX96,\\n int24 _tick,\\n uint16 _observationIndex,\\n uint16 _observationCardinality,\\n uint16 _observationCardinalityNext,\\n uint8 _feeProtocol,\\n bool _unlocked\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param _index The element of the observations array to fetch\\n /// @return _blockTimestamp The timestamp of the observation,\\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// @return _initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 _index)\\n external\\n view\\n returns (\\n uint32 _blockTimestamp,\\n int56 _tickCumulative,\\n uint160 _secondsPerLiquidityCumulativeX128,\\n bool _initialized\\n );\\n\\n // EVENTS\\n\\n /// @notice Emitted when the pool information is verified\\n /// @param _poolSalt Identifier of the pool and the oracle\\n /// @param _token0 The contract address of either token0 or token1\\n /// @param _token1 The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\\n\\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param _tick The log base 1.0001 of price of the pool after the swap\\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\\n\\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\\n\\n // ERRORS\\n\\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\\n error AI();\\n\\n /// @notice Thrown if the pool info does not correspond to the pool salt\\n error InvalidPool();\\n\\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\\n error OnlyDataReceiver();\\n\\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\\n error OnlyFactory();\\n\\n // FUNCTIONS\\n\\n /// @notice Permisionless method to verify token0, token1 and fee\\n /// @dev Before verified, token0 and token1 views will return address(0)\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external;\\n\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\\n\\n /// @notice Permisioned method to push a dataset to update\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolNonce Nonce of the observation broadcast\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\\n\\n /// @notice Permisioned method to increase the cardinalityNext value\\n /// @param _observationCardinalityNext The new next length of the observations array\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa90206e3de00ad866b7f4792ce29220ee0ca561d59629ba638a31c4d6fd3941b\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IBridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport {IDataReceiver} from '../IDataReceiver.sol';\\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\\n\\ninterface IBridgeReceiverAdapter is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @notice Gets the address of the DataReceiver contract\\n /// @return _dataReceiver Address of the DataReceiver contract\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /* NOTE: callback methods should be here declared */\\n}\\n\",\"keccak256\":\"0x49e5c9c6a28521933a3f2b01a529fbae9aac1edd71dbe904586a2f06148b1974\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a060405234801561001057600080fd5b50604051610c4e380380610c4e83398101604081905261002f916100bc565b816001600160a01b0381166100575760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0392831617905581166100925760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052506100f6565b6001600160a01b03811681146100b957600080fd5b50565b600080604083850312156100cf57600080fd5b82516100da816100a4565b60208401519092506100eb816100a4565b809150509250929050565b608051610b2f61011f600039600081816101640152818161045801526104fc0152610b2f6000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063b893cce211610066578063b893cce21461012c578063c7f7fb901461015f578063d34ad40914610186578063e3056a3414610199578063f235757f146101ac57600080fd5b80630c340a24146100a35780630ddb5dd2146100d357806313f6986d146100e85780636607baca146100f0578063954e863e14610119575b600080fd5b6000546100b6906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e66100e1366004610747565b6101bf565b005b6100e661027f565b6100b66100fe3660046107b3565b6002602052600090815260409020546001600160a01b031681565b6100e66101273660046107ef565b6102b4565b61014f61013a366004610828565b60036020526000908152604090205460ff1681565b60405190151581526020016100ca565b6100b67f000000000000000000000000000000000000000000000000000000000000000081565b6100e66101943660046108d4565b6102ed565b6001546100b6906001600160a01b031681565b6100e66101ba366004610828565b61032d565b6000546001600160a01b031633146101ea5760405163070545c960e51b815260040160405180910390fd5b8281811461020e576040516001621398b960e31b0319815260040160405180910390fd5b60005b818110156102775761026f86868381811061022e5761022e6109e0565b90506020020160208101906102439190610828565b858584818110610255576102556109e0565b905060200201602081019061026a91906109f6565b610364565b600101610211565b505050505050565b6001546001600160a01b031633146102aa57604051639ba0305d60e01b815260040160405180910390fd5b6102b26103c7565b565b6000546001600160a01b031633146102df5760405163070545c960e51b815260040160405180910390fd5b6102e98282610364565b5050565b3360009081526003602052604090205460ff1661031d576040516360ece74160e01b815260040160405180910390fd5b610328838383610425565b505050565b6000546001600160a01b031633146103585760405163070545c960e51b815260040160405180910390fd5b61036181610672565b50565b6001600160a01b038216600081815260036020908152604091829020805460ff19168515159081179091558251938452908301527f3cece36ac6216147f57b10bb30975f82b18b8b290a7925c322277e684afcce4a910160405180910390a15050565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000828152600260205260409020546001600160a01b03168061059c5760405163f6c0092760e01b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f6c0092790602401602060405180830381865afa1580156104a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104cb9190610a13565b90506001600160a01b03811661057457604051632e60fe9b60e11b81526004810184905262ffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635cc1fd36906044016020604051808303816000875af115801561054d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105719190610a13565b90505b600083815260026020526040902080546001600160a01b0319166001600160a01b0383161790555b6040516308f944b560e21b81526001600160a01b038216906323e512d4906105ca9087908690600401610a7f565b6020604051808303816000875af11580156105e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060d9190610aa6565b1561065357827fb3f205f9831d2225c91718a340701f53f3e0d675a56498add8fbc5a96fabf60d83863360405161064693929190610ac3565b60405180910390a261066c565b604051630a96dcbd60e11b815260040160405180910390fd5b50505050565b6001600160a01b0381166106995760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910160405180910390a150565b60008083601f84011261070d57600080fd5b50813567ffffffffffffffff81111561072557600080fd5b6020830191508360208260051b850101111561074057600080fd5b9250929050565b6000806000806040858703121561075d57600080fd5b843567ffffffffffffffff8082111561077557600080fd5b610781888389016106fb565b9096509450602087013591508082111561079a57600080fd5b506107a7878288016106fb565b95989497509550505050565b6000602082840312156107c557600080fd5b5035919050565b6001600160a01b038116811461036157600080fd5b801515811461036157600080fd5b6000806040838503121561080257600080fd5b823561080d816107cc565b9150602083013561081d816107e1565b809150509250929050565b60006020828403121561083a57600080fd5b8135610845816107cc565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156108855761088561084c565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156108b4576108b461084c565b604052919050565b803562ffffff811681146108cf57600080fd5b919050565b6000806000606084860312156108e957600080fd5b833567ffffffffffffffff8082111561090157600080fd5b818601915086601f83011261091557600080fd5b81356020828211156109295761092961084c565b610937818360051b0161088b565b828152818101935060069290921b84018101918983111561095757600080fd5b938101935b828510156109bf576040858b0312156109755760008081fd5b61097d610862565b853563ffffffff811681146109925760008081fd5b815285830135600281900b81146109a95760008081fd5b818401528452604094909401939281019261095c565b965087013594506109d79250506040860190506108bc565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610a0857600080fd5b8135610845816107e1565b600060208284031215610a2557600080fd5b8151610845816107cc565b600081518084526020808501945080840160005b83811015610a74578151805163ffffffff16885283015160020b8388015260409096019590820190600101610a44565b509495945050505050565b604081526000610a926040830185610a30565b905062ffffff831660208301529392505050565b600060208284031215610ab857600080fd5b8151610845816107e1565b62ffffff84168152606060208201526000610ae16060830185610a30565b905060018060a01b038316604083015294935050505056fea2646970667358221220beece712f14fafde45f4267286e648a0cb7569869dc101c34c08f14ac7600f8764736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063b893cce211610066578063b893cce21461012c578063c7f7fb901461015f578063d34ad40914610186578063e3056a3414610199578063f235757f146101ac57600080fd5b80630c340a24146100a35780630ddb5dd2146100d357806313f6986d146100e85780636607baca146100f0578063954e863e14610119575b600080fd5b6000546100b6906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e66100e1366004610747565b6101bf565b005b6100e661027f565b6100b66100fe3660046107b3565b6002602052600090815260409020546001600160a01b031681565b6100e66101273660046107ef565b6102b4565b61014f61013a366004610828565b60036020526000908152604090205460ff1681565b60405190151581526020016100ca565b6100b67f000000000000000000000000000000000000000000000000000000000000000081565b6100e66101943660046108d4565b6102ed565b6001546100b6906001600160a01b031681565b6100e66101ba366004610828565b61032d565b6000546001600160a01b031633146101ea5760405163070545c960e51b815260040160405180910390fd5b8281811461020e576040516001621398b960e31b0319815260040160405180910390fd5b60005b818110156102775761026f86868381811061022e5761022e6109e0565b90506020020160208101906102439190610828565b858584818110610255576102556109e0565b905060200201602081019061026a91906109f6565b610364565b600101610211565b505050505050565b6001546001600160a01b031633146102aa57604051639ba0305d60e01b815260040160405180910390fd5b6102b26103c7565b565b6000546001600160a01b031633146102df5760405163070545c960e51b815260040160405180910390fd5b6102e98282610364565b5050565b3360009081526003602052604090205460ff1661031d576040516360ece74160e01b815260040160405180910390fd5b610328838383610425565b505050565b6000546001600160a01b031633146103585760405163070545c960e51b815260040160405180910390fd5b61036181610672565b50565b6001600160a01b038216600081815260036020908152604091829020805460ff19168515159081179091558251938452908301527f3cece36ac6216147f57b10bb30975f82b18b8b290a7925c322277e684afcce4a910160405180910390a15050565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000828152600260205260409020546001600160a01b03168061059c5760405163f6c0092760e01b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f6c0092790602401602060405180830381865afa1580156104a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104cb9190610a13565b90506001600160a01b03811661057457604051632e60fe9b60e11b81526004810184905262ffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635cc1fd36906044016020604051808303816000875af115801561054d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105719190610a13565b90505b600083815260026020526040902080546001600160a01b0319166001600160a01b0383161790555b6040516308f944b560e21b81526001600160a01b038216906323e512d4906105ca9087908690600401610a7f565b6020604051808303816000875af11580156105e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060d9190610aa6565b1561065357827fb3f205f9831d2225c91718a340701f53f3e0d675a56498add8fbc5a96fabf60d83863360405161064693929190610ac3565b60405180910390a261066c565b604051630a96dcbd60e11b815260040160405180910390fd5b50505050565b6001600160a01b0381166106995760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910160405180910390a150565b60008083601f84011261070d57600080fd5b50813567ffffffffffffffff81111561072557600080fd5b6020830191508360208260051b850101111561074057600080fd5b9250929050565b6000806000806040858703121561075d57600080fd5b843567ffffffffffffffff8082111561077557600080fd5b610781888389016106fb565b9096509450602087013591508082111561079a57600080fd5b506107a7878288016106fb565b95989497509550505050565b6000602082840312156107c557600080fd5b5035919050565b6001600160a01b038116811461036157600080fd5b801515811461036157600080fd5b6000806040838503121561080257600080fd5b823561080d816107cc565b9150602083013561081d816107e1565b809150509250929050565b60006020828403121561083a57600080fd5b8135610845816107cc565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156108855761088561084c565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156108b4576108b461084c565b604052919050565b803562ffffff811681146108cf57600080fd5b919050565b6000806000606084860312156108e957600080fd5b833567ffffffffffffffff8082111561090157600080fd5b818601915086601f83011261091557600080fd5b81356020828211156109295761092961084c565b610937818360051b0161088b565b828152818101935060069290921b84018101918983111561095757600080fd5b938101935b828510156109bf576040858b0312156109755760008081fd5b61097d610862565b853563ffffffff811681146109925760008081fd5b815285830135600281900b81146109a95760008081fd5b818401528452604094909401939281019261095c565b965087013594506109d79250506040860190506108bc565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610a0857600080fd5b8135610845816107e1565b600060208284031215610a2557600080fd5b8151610845816107cc565b600081518084526020808501945080840160005b83811015610a74578151805163ffffffff16885283015160020b8388015260409096019590820190600101610a44565b509495945050505050565b604081526000610a926040830185610a30565b905062ffffff831660208301529392505050565b600060208284031215610ab857600080fd5b8151610845816107e1565b62ffffff84168152606060208201526000610ae16060830185610a30565b905060018060a01b038316604083015294935050505056fea2646970667358221220beece712f14fafde45f4267286e648a0cb7569869dc101c34c08f14ac7600f8764736f6c634300080f0033", + "numDeployments": 1, + "solcInputHash": "1ffcc3895a1a8980b9e58deee89219d1", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract IOracleFactory\",\"name\":\"_oracleFactory\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ObservationsNotWritable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnallowedAdapter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IBridgeReceiverAdapter\",\"name\":\"_adapter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isAllowed\",\"type\":\"bool\"}],\"name\":\"AdapterWhitelisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"_poolNonce\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_receiverAdapter\",\"type\":\"address\"}],\"name\":\"ObservationsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"_poolNonce\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_receiverAdapter\",\"type\":\"address\"}],\"name\":\"ObservationsCached\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockTimestamp\",\"type\":\"uint32\"},{\"internalType\":\"int24\",\"name\":\"tick\",\"type\":\"int24\"}],\"internalType\":\"struct IOracleSidechain.ObservationData[]\",\"name\":\"_observationsData\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"_poolNonce\",\"type\":\"uint24\"}],\"name\":\"addObservations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deployedOracles\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleFactory\",\"outputs\":[{\"internalType\":\"contract IOracleFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"setPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_maxObservations\",\"type\":\"uint256\"}],\"name\":\"syncObservations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBridgeReceiverAdapter\",\"name\":\"_receiverAdapter\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_isWhitelisted\",\"type\":\"bool\"}],\"name\":\"whitelistAdapter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBridgeReceiverAdapter[]\",\"name\":\"_receiverAdapters\",\"type\":\"address[]\"},{\"internalType\":\"bool[]\",\"name\":\"_isWhitelisted\",\"type\":\"bool[]\"}],\"name\":\"whitelistAdapters\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBridgeReceiverAdapter\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"whitelistedAdapters\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addObservations((uint32,int24)[],bytes32,uint24)\":{\"params\":{\"_observationsData\":\"Array of tuples containing the dataset\",\"_poolNonce\":\"Nonce of the observation broadcast\",\"_poolSalt\":\"Identifier of the pool to fetch\"}},\"setPendingGovernor(address)\":{\"params\":{\"_pendingGovernor\":\"Address of the proposed new governor\"}},\"syncObservations(bytes32,uint256)\":{\"details\":\"Use _maxObservations = 0 to process all possible cached observations\",\"params\":{\"_maxObservations\":\"Maximum number of observations to process\",\"_poolSalt\":\"Identifier of the pool to fetch\"}},\"whitelistAdapter(address,bool)\":{\"params\":{\"_isWhitelisted\":\"New whitelisting status\",\"_receiverAdapter\":\"Address of the adapter\"}},\"whitelistAdapters(address[],bool[])\":{\"params\":{\"_isWhitelisted\":\"Array of whitelisting status for each address\",\"_receiverAdapters\":\"Array of addresses of the adapter\"}}},\"stateVariables\":{\"deployedOracles\":{\"params\":{\"_poolSalt\":\"The identifier of the oracle\"},\"return\":\"The address of the correspondant Oracle\",\"returns\":{\"_0\":\"The address of the correspondant Oracle\"}},\"oracleFactory\":{\"return\":\"The address of the OracleFactory\",\"returns\":{\"_0\":\"The address of the OracleFactory\"}},\"whitelistedAdapters\":{\"params\":{\"_adapter\":\"Address of the bridge adapter to consult\"},\"return\":\"Whether a bridge adapter is whitelisted\",\"returns\":{\"_0\":\"Whether a bridge adapter is whitelisted\"}}},\"title\":\"The DataReceiver contract\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"ObservationsNotWritable()\":[{\"notice\":\"Thrown when the broadcast nonce is incorrect\"}],\"OnlyGovernor()\":[{\"notice\":\"Thrown if a non-governor user tries to call a OnlyGovernor function\"}],\"OnlyPendingGovernor()\":[{\"notice\":\"Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\"}],\"UnallowedAdapter()\":[{\"notice\":\"Thrown when a not-whitelisted adapter triggers an update\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"events\":{\"AdapterWhitelisted(address,bool)\":{\"notice\":\"Emitted when a new adapter whitelisting rule is set\"},\"ObservationsAdded(bytes32,uint24,address)\":{\"notice\":\"Emitted when a broadcast observation is succesfully processed\"},\"ObservationsCached(bytes32,uint24,address)\":{\"notice\":\"Emitted when a broadcast observation is cached for later processing\"},\"PendingGovernorAccepted(address)\":{\"notice\":\"Emitted when a new governor is set\"},\"PendingGovernorSet(address,address)\":{\"notice\":\"Emitted when a new pending governor is set\"}},\"kind\":\"user\",\"methods\":{\"acceptPendingGovernor()\":{\"notice\":\"Allows a proposed governor to accept the governance\"},\"addObservations((uint32,int24)[],bytes32,uint24)\":{\"notice\":\"Allows whitelisted bridge adapters to push a broadcast\"},\"deployedOracles(bytes32)\":{\"notice\":\"Tracks already deployed oracles\"},\"setPendingGovernor(address)\":{\"notice\":\"Allows a governor to propose a new governor\"},\"syncObservations(bytes32,uint256)\":{\"notice\":\"Allows any address to attempt to insert cached observations\"},\"whitelistAdapter(address,bool)\":{\"notice\":\"Allows governance to set an adapter whitelisted state\"},\"whitelistAdapters(address[],bool[])\":{\"notice\":\"Allows governance to batch set adapters whitelisted state\"},\"whitelistedAdapters(address)\":{\"notice\":\"Tracks the whitelisting of bridge adapters\"}},\"notice\":\"Handles reception of broadcast data and delivers it to correspondant oracle\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/DataReceiver.sol\":\"DataReceiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '../interfaces/IGovernable.sol';\\n\\n/// @title Governable contract\\n/// @notice Manages the governor role\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public governor;\\n\\n /// @inheritdoc IGovernable\\n address public pendingGovernor;\\n\\n constructor(address _governor) {\\n if (_governor == address(0)) revert ZeroAddress();\\n governor = _governor;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\\n _setPendingGovernor(_pendingGovernor);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptPendingGovernor() external onlyPendingGovernor {\\n _acceptPendingGovernor();\\n }\\n\\n function _setPendingGovernor(address _pendingGovernor) internal {\\n if (_pendingGovernor == address(0)) revert ZeroAddress();\\n pendingGovernor = _pendingGovernor;\\n emit PendingGovernorSet(governor, _pendingGovernor);\\n }\\n\\n function _acceptPendingGovernor() internal {\\n governor = pendingGovernor;\\n delete pendingGovernor;\\n emit PendingGovernorAccepted(governor);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governor\\n modifier onlyGovernor() {\\n if (msg.sender != governor) revert OnlyGovernor();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernor\\n modifier onlyPendingGovernor() {\\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x3f11408cfcb015a99dc417e075c8ebc39b796fc2adc3e81b036487e4486881b3\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@uniswap/v3-core/contracts/libraries/Oracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.0;\\n\\n/// @title Oracle\\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\\n/// @dev Instances of stored oracle data, \\\"observations\\\", are collected in the oracle array\\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\\n/// Observations are overwritten when the full length of the oracle array is populated.\\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\\nlibrary Oracle {\\n error I();\\n error OLD();\\n\\n struct Observation {\\n // the block timestamp of the observation\\n uint32 blockTimestamp;\\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\\n int56 tickCumulative;\\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\\n uint160 secondsPerLiquidityCumulativeX128;\\n // whether or not the observation is initialized\\n bool initialized;\\n }\\n\\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\\n /// @param last The specified observation to be transformed\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @return Observation The newly populated observation\\n function transform(\\n Observation memory last,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity\\n ) private pure returns (Observation memory) {\\n unchecked {\\n uint32 delta = blockTimestamp - last.blockTimestamp;\\n return\\n Observation({\\n blockTimestamp: blockTimestamp,\\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\\n initialized: true\\n });\\n }\\n }\\n\\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\\n /// @param self The stored oracle array\\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\\n /// @return cardinality The number of populated elements in the oracle array\\n /// @return cardinalityNext The new length of the oracle array, independent of population\\n function initialize(Observation[65535] storage self, uint32 time)\\n internal\\n returns (uint16 cardinality, uint16 cardinalityNext)\\n {\\n self[0] = Observation({\\n blockTimestamp: time,\\n tickCumulative: 0,\\n secondsPerLiquidityCumulativeX128: 0,\\n initialized: true\\n });\\n return (1, 1);\\n }\\n\\n /// @notice Writes an oracle observation to the array\\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\\n /// @param self The stored oracle array\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @param cardinalityNext The new length of the oracle array, independent of population\\n /// @return indexUpdated The new index of the most recently written element in the oracle array\\n /// @return cardinalityUpdated The new cardinality of the oracle array\\n function write(\\n Observation[65535] storage self,\\n uint16 index,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity,\\n uint16 cardinality,\\n uint16 cardinalityNext\\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\\n unchecked {\\n Observation memory last = self[index];\\n\\n // early return if we've already written an observation this block\\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\\n\\n // if the conditions are right, we can bump the cardinality\\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\\n cardinalityUpdated = cardinalityNext;\\n } else {\\n cardinalityUpdated = cardinality;\\n }\\n\\n indexUpdated = (index + 1) % cardinalityUpdated;\\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\\n }\\n }\\n\\n /// @notice Prepares the oracle array to store up to `next` observations\\n /// @param self The stored oracle array\\n /// @param current The current next cardinality of the oracle array\\n /// @param next The proposed next cardinality which will be populated in the oracle array\\n /// @return next The next cardinality which will be populated in the oracle array\\n function grow(\\n Observation[65535] storage self,\\n uint16 current,\\n uint16 next\\n ) internal returns (uint16) {\\n unchecked {\\n if (current <= 0) revert I();\\n // no-op if the passed next value isn't greater than the current next value\\n if (next <= current) return current;\\n // store in each slot to prevent fresh SSTOREs in swaps\\n // this data will not be used because the initialized boolean is still false\\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\\n return next;\\n }\\n }\\n\\n /// @notice comparator for 32-bit timestamps\\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\\n /// @param time A timestamp truncated to 32 bits\\n /// @param a A comparison timestamp from which to determine the relative position of `time`\\n /// @param b From which to determine the relative position of `time`\\n /// @return Whether `a` is chronologically <= `b`\\n function lte(\\n uint32 time,\\n uint32 a,\\n uint32 b\\n ) private pure returns (bool) {\\n unchecked {\\n // if there hasn't been overflow, no need to adjust\\n if (a <= time && b <= time) return a <= b;\\n\\n uint256 aAdjusted = a > time ? a : a + 2**32;\\n uint256 bAdjusted = b > time ? b : b + 2**32;\\n\\n return aAdjusted <= bAdjusted;\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\\n /// The result may be the same observation, or adjacent observations.\\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation recorded before, or at, the target\\n /// @return atOrAfter The observation recorded at, or after, the target\\n function binarySearch(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n uint16 index,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n uint256 l = (index + 1) % cardinality; // oldest observation\\n uint256 r = l + cardinality - 1; // newest observation\\n uint256 i;\\n while (true) {\\n i = (l + r) / 2;\\n\\n beforeOrAt = self[i % cardinality];\\n\\n // we've landed on an uninitialized tick, keep searching higher (more recently)\\n if (!beforeOrAt.initialized) {\\n l = i + 1;\\n continue;\\n }\\n\\n atOrAfter = self[(i + 1) % cardinality];\\n\\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\\n\\n // check if we've found the answer!\\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\\n\\n if (!targetAtOrAfter) r = i - 1;\\n else l = i + 1;\\n }\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\\n /// @dev Assumes there is at least 1 initialized observation.\\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param tick The active tick at the time of the returned or simulated observation\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The total pool liquidity at the time of the call\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\\n function getSurroundingObservations(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n // optimistically set before to the newest observation\\n beforeOrAt = self[index];\\n\\n // if the target is chronologically at or after the newest observation, we can early return\\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\\n if (beforeOrAt.blockTimestamp == target) {\\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\\n return (beforeOrAt, atOrAfter);\\n } else {\\n // otherwise, we need to transform\\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\\n }\\n }\\n\\n // now, set before to the oldest observation\\n beforeOrAt = self[(index + 1) % cardinality];\\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\\n\\n // ensure that the target is chronologically at or after the oldest observation\\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\\n\\n // if we've reached this point, we have to binary search\\n return binarySearch(self, time, target, index, cardinality);\\n }\\n }\\n\\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\\n /// at exactly the timestamp between the two observations.\\n /// @param self The stored oracle array\\n /// @param time The current block timestamp\\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\\n function observeSingle(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 secondsAgo,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\\n unchecked {\\n if (secondsAgo == 0) {\\n Observation memory last = self[index];\\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\\n }\\n\\n uint32 target = time - secondsAgo;\\n\\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\\n self,\\n time,\\n target,\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n\\n if (target == beforeOrAt.blockTimestamp) {\\n // we're at the left boundary\\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\\n } else if (target == atOrAfter.blockTimestamp) {\\n // we're at the right boundary\\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\\n } else {\\n // we're in the middle\\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\\n return (\\n beforeOrAt.tickCumulative +\\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\\n int56(uint56(targetDelta)),\\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\\n uint160(\\n (uint256(\\n atOrAfter.secondsPerLiquidityCumulativeX128 -\\n beforeOrAt.secondsPerLiquidityCumulativeX128\\n ) * targetDelta) / observationTimeDelta\\n )\\n );\\n }\\n }\\n }\\n\\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\\n /// @dev Reverts if `secondsAgos` > oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\\n function observe(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32[] memory secondsAgos,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\\n unchecked {\\n if (cardinality <= 0) revert I();\\n\\n tickCumulatives = new int56[](secondsAgos.length);\\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\\n for (uint256 i = 0; i < secondsAgos.length; i++) {\\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\\n self,\\n time,\\n secondsAgos[i],\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa25b18af947c36b9add9e229c361beb6aba176fb435d7a24e6dc723cbc187442\",\"license\":\"BUSL-1.1\"},\"@uniswap/v3-core/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity ^0.8.0;\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n error T();\\n error R();\\n\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n unchecked {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n if (absTick > uint256(int256(MAX_TICK))) revert T();\\n\\n uint256 ratio = absTick & 0x1 != 0\\n ? 0xfffcb933bd6fad37aa2d162d1a594001\\n : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\\n /// ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n unchecked {\\n // second inequality must be < because the price can never reach the price at the max tick\\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5c57de03a91cc2ec8939865dbbcb0197bb6c353b711075eefd8e0fca5e102129\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/DataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\\nimport {OracleSidechain} from './OracleSidechain.sol';\\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\\n\\n/// @title The DataReceiver contract\\n/// @notice Handles reception of broadcast data and delivers it to correspondant oracle\\ncontract DataReceiver is IDataReceiver, Governable {\\n /// @inheritdoc IDataReceiver\\n IOracleFactory public immutable oracleFactory;\\n\\n /// @inheritdoc IDataReceiver\\n mapping(bytes32 => IOracleSidechain) public deployedOracles;\\n\\n /// @inheritdoc IDataReceiver\\n mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters;\\n\\n mapping(bytes32 => mapping(uint24 => IOracleSidechain.ObservationData[])) internal _cachedObservations;\\n\\n constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) {\\n if (address(_oracleFactory) == address(0)) revert ZeroAddress();\\n oracleFactory = _oracleFactory;\\n }\\n\\n /// @inheritdoc IDataReceiver\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external onlyWhitelistedAdapters {\\n _addObservations(_observationsData, _poolSalt, _poolNonce);\\n }\\n\\n function _addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) internal {\\n // Read, store or deploy oracle given poolSalt\\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\\n if (address(_oracle) == address(0)) {\\n _oracle = oracleFactory.getPool(_poolSalt);\\n if (address(_oracle) == address(0)) {\\n _oracle = oracleFactory.deployOracle(_poolSalt, _poolNonce);\\n }\\n deployedOracles[_poolSalt] = _oracle;\\n }\\n // Try to write observations data into oracle\\n if (_oracle.write(_observationsData, _poolNonce)) {\\n emit ObservationsAdded(_poolSalt, _poolNonce, msg.sender);\\n } else {\\n // Query pool's current nonce\\n uint24 _currentNonce = _oracle.poolNonce();\\n // Discard old observations (already written in the oracle)\\n // NOTE: if _currentNonce == _poolNonce it shouldn't reach this else block\\n if (_currentNonce > _poolNonce) revert ObservationsNotWritable();\\n\\n IOracleSidechain.ObservationData[] storage _cachedObservationsData = _cachedObservations[_poolSalt][_poolNonce];\\n // Store not-added observations to cachedObservations mapping\\n if (_cachedObservationsData.length == 0) {\\n // NOTE: memory to storage is not supported\\n for (uint256 _i; _i < _observationsData.length; ++_i) {\\n _cachedObservationsData.push(_observationsData[_i]);\\n }\\n emit ObservationsCached(_poolSalt, _poolNonce, msg.sender);\\n }\\n while (_currentNonce <= _poolNonce) {\\n // Try backfilling pending observations (from current to {sent|first empty} nonce)\\n _observationsData = _cachedObservations[_poolSalt][_currentNonce];\\n // If the struct is not empty, write it into the oracle\\n if (_observationsData.length > 0) {\\n // Since observation nonce == oracle nonce, we can safely write the observations\\n _oracle.write(_observationsData, _currentNonce);\\n emit ObservationsAdded(_poolSalt, _currentNonce, msg.sender);\\n // Clear out the written observations\\n delete _cachedObservations[_poolSalt][_currentNonce];\\n _currentNonce++;\\n } else {\\n // When an empty nonce is found, break the loop\\n break;\\n }\\n }\\n }\\n }\\n\\n /// @inheritdoc IDataReceiver\\n function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external {\\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\\n if (address(_oracle) == address(0)) revert ZeroAddress();\\n IOracleSidechain.ObservationData[] memory _cachedObservationsData;\\n uint24 _currentNonce = _oracle.poolNonce();\\n uint256 _i;\\n while (_maxObservations == 0 || _i < _maxObservations) {\\n _cachedObservationsData = _cachedObservations[_poolSalt][_currentNonce];\\n if (_cachedObservationsData.length > 0) {\\n _oracle.write(_cachedObservationsData, _currentNonce);\\n emit ObservationsAdded(_poolSalt, _currentNonce, msg.sender);\\n delete _cachedObservations[_poolSalt][_currentNonce];\\n _currentNonce++;\\n _i++;\\n } else {\\n break;\\n }\\n }\\n if (_i == 0) revert ObservationsNotWritable();\\n }\\n\\n /// @inheritdoc IDataReceiver\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor {\\n _whitelistAdapter(_receiverAdapter, _isWhitelisted);\\n }\\n\\n /// @inheritdoc IDataReceiver\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\\n uint256 _receiverAdapterLength = _receiverAdapters.length;\\n if (_receiverAdapterLength != _isWhitelisted.length) revert LengthMismatch();\\n unchecked {\\n for (uint256 _i; _i < _receiverAdapterLength; ++_i) {\\n _whitelistAdapter(_receiverAdapters[_i], _isWhitelisted[_i]);\\n }\\n }\\n }\\n\\n function _whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) internal {\\n whitelistedAdapters[_receiverAdapter] = _isWhitelisted;\\n emit AdapterWhitelisted(_receiverAdapter, _isWhitelisted);\\n }\\n\\n modifier onlyWhitelistedAdapters() {\\n if (!whitelistedAdapters[IBridgeReceiverAdapter(msg.sender)]) revert UnallowedAdapter();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5dc12e8bff1c84e0edf0dab64a72f71e57a213308b6c578c5210e2e3d1922c43\",\"license\":\"MIT\"},\"solidity/contracts/OracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\\n\\n/// @title The SidechainOracle contract\\n/// @notice Computes and stores on-chain price data from Mainnet\\ncontract OracleSidechain is IOracleSidechain {\\n using Oracle for Oracle.Observation[65535];\\n\\n /// @inheritdoc IOracleSidechain\\n IOracleFactory public immutable factory;\\n\\n struct Slot0 {\\n // the current price\\n uint160 sqrtPriceX96;\\n // the current tick\\n int24 tick;\\n // the most-recently updated index of the observations array\\n uint16 observationIndex;\\n // the current maximum number of observations that are being stored\\n uint16 observationCardinality;\\n // the next maximum number of observations to store, triggered in observations.write\\n uint16 observationCardinalityNext;\\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\\n // represented as an integer denominator (1/x)%\\n uint8 feeProtocol;\\n // whether the pool is locked\\n bool unlocked;\\n }\\n /// @inheritdoc IOracleSidechain\\n Slot0 public slot0;\\n\\n /// @inheritdoc IOracleSidechain\\n Oracle.Observation[65535] public observations;\\n\\n /// @inheritdoc IOracleSidechain\\n bytes32 public immutable poolSalt;\\n\\n uint24 public poolNonce;\\n /// @inheritdoc IOracleSidechain\\n address public token0;\\n /// @inheritdoc IOracleSidechain\\n address public token1;\\n /// @inheritdoc IOracleSidechain\\n uint24 public fee;\\n\\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\\n function _getBlockTimestamp() internal view virtual returns (uint32) {\\n return uint32(block.timestamp); // truncation is desired\\n }\\n\\n constructor() {\\n factory = IOracleFactory(msg.sender);\\n uint16 _cardinality;\\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\\n\\n slot0 = Slot0({\\n sqrtPriceX96: 0,\\n tick: 0,\\n observationIndex: _cardinality - 1,\\n observationCardinality: _cardinality,\\n observationCardinalityNext: _cardinality,\\n feeProtocol: 0,\\n unlocked: true\\n });\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external {\\n if (!slot0.unlocked) revert AI();\\n\\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\\n\\n token0 = _token0;\\n token1 = _token1;\\n fee = _fee;\\n slot0.unlocked = false;\\n\\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\\n {\\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\\n if (_poolNonce != poolNonce) return false;\\n poolNonce++;\\n\\n uint256 _observationsDataLength = _observationsData.length;\\n for (uint256 _i; _i < _observationsDataLength; ) {\\n _write(_observationsData[_i]);\\n unchecked {\\n ++_i;\\n }\\n }\\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\\n\\n // emits UniV3 Swap event topic with minimal data\\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\\n return true;\\n }\\n\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\\n if (_observationCardinalityNext <= _observationCardinalityNextOld) revert AI();\\n slot0.observationCardinalityNext = _observationCardinalityNext;\\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\\n }\\n\\n function _write(ObservationData memory _observationData) private {\\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\\n slot0.observationIndex,\\n _observationData.blockTimestamp,\\n slot0.tick,\\n 0,\\n slot0.observationCardinality,\\n slot0.observationCardinalityNext\\n );\\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\\n slot0.tick = _observationData.tick;\\n }\\n\\n modifier onlyDataReceiver() {\\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\\n _;\\n }\\n\\n modifier onlyFactory() {\\n if (msg.sender != address(factory)) revert OnlyFactory();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x1b830dc6ad7405f2d533e1aa8eb079853edcdf301b396ac6b1d3c41573b62787\",\"license\":\"MIT\"},\"solidity/interfaces/IDataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleFactory} from './IOracleFactory.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\\n\\ninterface IDataReceiver is IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @notice Tracks already deployed oracles\\n /// @param _poolSalt The identifier of the oracle\\n /// @return _deployedOracle The address of the correspondant Oracle\\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\\n\\n /// @notice Tracks the whitelisting of bridge adapters\\n /// @param _adapter Address of the bridge adapter to consult\\n /// @return _isAllowed Whether a bridge adapter is whitelisted\\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a broadcast observation is succesfully processed\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsAdded(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a broadcast observation is cached for later processing\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsCached(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a new adapter whitelisting rule is set\\n /// @param _adapter Address of the adapter\\n /// @param _isAllowed New whitelisting status\\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\\n\\n // ERRORS\\n\\n /// @notice Thrown when the broadcast nonce is incorrect\\n error ObservationsNotWritable();\\n\\n /// @notice Thrown when a not-whitelisted adapter triggers an update\\n error UnallowedAdapter();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows whitelisted bridge adapters to push a broadcast\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _poolNonce Nonce of the observation broadcast\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external;\\n\\n /// @notice Allows any address to attempt to insert cached observations\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _maxObservations Maximum number of observations to process\\n /// @dev Use _maxObservations = 0 to process all possible cached observations\\n function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external;\\n\\n /// @notice Allows governance to set an adapter whitelisted state\\n /// @param _receiverAdapter Address of the adapter\\n /// @param _isWhitelisted New whitelisting status\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\\n\\n /// @notice Allows governance to batch set adapters whitelisted state\\n /// @param _receiverAdapters Array of addresses of the adapter\\n /// @param _isWhitelisted Array of whitelisting status for each address\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\\n}\\n\",\"keccak256\":\"0xd07e75380d5086ea78909bc5c80aadc110903004f50c006b0281cc090f273291\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IDataReceiver} from './IDataReceiver.sol';\\n\\ninterface IOracleFactory is IGovernable {\\n // STRUCTS\\n\\n struct OracleParameters {\\n bytes32 poolSalt; // Identifier of the pool and oracle\\n uint24 poolNonce; // Initial nonce of the deployed pool\\n uint16 cardinality; // Initial cardinality of the deployed pool\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\\n //solhint-disable-next-line func-name-mixedcase\\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\\n\\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /// @return _poolSalt The id of both the oracle and the pool\\n /// @return _poolNonce The initial nonce of the pool data\\n /// @return _cardinality The size of the observations memory storage\\n function oracleParameters()\\n external\\n view\\n returns (\\n bytes32 _poolSalt,\\n uint24 _poolNonce,\\n uint16 _cardinality\\n );\\n\\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function initialCardinality() external view returns (uint16 _initialCardinality);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new oracle is deployed\\n /// @param _poolSalt The id of both the oracle and the pool\\n /// @param _oracle The address of the deployed oracle\\n /// @param _initialNonce The initial nonce of the pool data\\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\\n\\n /// @notice Emitted when a new DataReceiver is set\\n /// @param _dataReceiver The address of the new DataReceiver\\n event DataReceiverSet(IDataReceiver _dataReceiver);\\n\\n /// @notice Emitted when a new initial oracle cardinality is set\\n /// @param _initialCardinality The initial length of the observationCardinality array\\n event InitialCardinalitySet(uint16 _initialCardinality);\\n\\n // ERRORS\\n\\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\\n error OnlyDataReceiver();\\n\\n // FUNCTIONS\\n\\n /// @notice Deploys a new oracle given an inputted salt\\n /// @dev Requires that the salt has not been deployed before\\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\\n /// @return _oracle The address of the newly deployed oracle\\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\\n\\n /// @notice Allows governor to set a new allowed dataReceiver\\n /// @dev Will disallow the previous dataReceiver\\n /// @param _dataReceiver The address of the new allowed dataReceiver\\n function setDataReceiver(IDataReceiver _dataReceiver) external;\\n\\n /// @notice Allows governor to set a new initial cardinality for new oracles\\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function setInitialCardinality(uint16 _initialCardinality) external;\\n\\n /// @notice Overrides UniV3Factory getPool mapping\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _oracle The oracle address\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle);\\n\\n /// @notice Tracks the addresses of the oracle by poolSalt\\n /// @param _poolSalt Identifier of both the pool and the oracle\\n /// @return _oracle The address (if deployed) of the correspondant oracle\\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\\n\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _poolSalt Pool salt for inquired parameters\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (bytes32 _poolSalt);\\n}\\n\",\"keccak256\":\"0xc32bfc32a274923ce1a089acc024396e702ae354773f0ac0a683e43ded904954\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleFactory} from './IOracleFactory.sol';\\n\\ninterface IOracleSidechain {\\n // STRUCTS\\n\\n struct ObservationData {\\n uint32 blockTimestamp;\\n int24 tick;\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function factory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @return _token0 The mainnet address of the Token0 of the oracle\\n function token0() external view returns (address _token0);\\n\\n /// @return _token1 The mainnet address of the Token1 of the oracle\\n function token1() external view returns (address _token1);\\n\\n /// @return _fee The fee identifier of the pool\\n function fee() external view returns (uint24 _fee);\\n\\n /// @return _poolSalt The identifier of both the pool and the oracle\\n function poolSalt() external view returns (bytes32 _poolSalt);\\n\\n /// @return _poolNonce Last recorded nonce of the pool history\\n function poolNonce() external view returns (uint24 _poolNonce);\\n\\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\\n /// @return _tick Used to maintain compatibility with Uniswap V3\\n /// @return _observationIndex The index of the last oracle observation that was written,\\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\\n /// @return _unlocked Used to track if a pool information was already verified\\n function slot0()\\n external\\n view\\n returns (\\n uint160 _sqrtPriceX96,\\n int24 _tick,\\n uint16 _observationIndex,\\n uint16 _observationCardinality,\\n uint16 _observationCardinalityNext,\\n uint8 _feeProtocol,\\n bool _unlocked\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param _index The element of the observations array to fetch\\n /// @return _blockTimestamp The timestamp of the observation,\\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// @return _initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 _index)\\n external\\n view\\n returns (\\n uint32 _blockTimestamp,\\n int56 _tickCumulative,\\n uint160 _secondsPerLiquidityCumulativeX128,\\n bool _initialized\\n );\\n\\n // EVENTS\\n\\n /// @notice Emitted when the pool information is verified\\n /// @param _poolSalt Identifier of the pool and the oracle\\n /// @param _token0 The contract address of either token0 or token1\\n /// @param _token1 The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\\n\\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param _tick The log base 1.0001 of price of the pool after the swap\\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\\n\\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\\n\\n // ERRORS\\n\\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\\n error AI();\\n\\n /// @notice Thrown if the pool info does not correspond to the pool salt\\n error InvalidPool();\\n\\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\\n error OnlyDataReceiver();\\n\\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\\n error OnlyFactory();\\n\\n // FUNCTIONS\\n\\n /// @notice Permisionless method to verify token0, token1 and fee\\n /// @dev Before verified, token0 and token1 views will return address(0)\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external;\\n\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\\n\\n /// @notice Permisioned method to push a dataset to update\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolNonce Nonce of the observation broadcast\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\\n\\n /// @notice Permisioned method to increase the cardinalityNext value\\n /// @param _observationCardinalityNext The new next length of the observations array\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa90206e3de00ad866b7f4792ce29220ee0ca561d59629ba638a31c4d6fd3941b\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IBridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport {IDataReceiver} from '../IDataReceiver.sol';\\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\\n\\ninterface IBridgeReceiverAdapter is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @notice Gets the address of the DataReceiver contract\\n /// @return _dataReceiver Address of the DataReceiver contract\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /* NOTE: callback methods should be here declared */\\n}\\n\",\"keccak256\":\"0x49e5c9c6a28521933a3f2b01a529fbae9aac1edd71dbe904586a2f06148b1974\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060405161123e38038061123e83398101604081905261002f916100bc565b816001600160a01b0381166100575760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0392831617905581166100925760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052506100f6565b6001600160a01b03811681146100b957600080fd5b50565b600080604083850312156100cf57600080fd5b82516100da816100a4565b60208401519092506100eb816100a4565b809150509250929050565b60805161111f61011f60003960008181610182015281816106ce0152610772015261111f6000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063a853456211610071578063a853456214610137578063b893cce21461014a578063c7f7fb901461017d578063d34ad409146101a4578063e3056a34146101b7578063f235757f146101ca57600080fd5b80630c340a24146100ae5780630ddb5dd2146100de57806313f6986d146100f35780636607baca146100fb578063954e863e14610124575b600080fd5b6000546100c1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100f16100ec366004610ce5565b6101dd565b005b6100f161029d565b6100c1610109366004610d51565b6002602052600090815260409020546001600160a01b031681565b6100f1610132366004610d8d565b6102d2565b6100f1610145366004610dc6565b61030b565b61016d610158366004610de8565b60036020526000908152604090205460ff1681565b60405190151581526020016100d5565b6100c17f000000000000000000000000000000000000000000000000000000000000000081565b6100f16101b2366004610e9d565b610563565b6001546100c1906001600160a01b031681565b6100f16101d8366004610de8565b6105a3565b6000546001600160a01b031633146102085760405163070545c960e51b815260040160405180910390fd5b8281811461022c576040516001621398b960e31b0319815260040160405180910390fd5b60005b818110156102955761028d86868381811061024c5761024c610fa9565b90506020020160208101906102619190610de8565b85858481811061027357610273610fa9565b90506020020160208101906102889190610fbf565b6105da565b60010161022f565b505050505050565b6001546001600160a01b031633146102c857604051639ba0305d60e01b815260040160405180910390fd5b6102d061063d565b565b6000546001600160a01b031633146102fd5760405163070545c960e51b815260040160405180910390fd5b61030782826105da565b5050565b6000828152600260205260409020546001600160a01b0316806103415760405163d92e233d60e01b815260040160405180910390fd5b60606000826001600160a01b0316639fdbd4d76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610fdc565b905060005b8415806103b857508481105b1561054257600086815260046020908152604080832062ffffff86168452825280832080548251818502810185019093528083529193909284015b8282101561043a576000848152602090819020604080518082019091529084015463ffffffff81168252640100000000900460020b818301528252600190920191016103f3565b505050509250600083511115610542576040516308f944b560e21b81526001600160a01b038516906323e512d4906104789086908690600401610ff9565b6020604051808303816000875af1158015610497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bb919061105e565b506040805162ffffff8416815233602082015287917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2600086815260046020908152604080832062ffffff86168452909152812061052291610c5d565b8161052c81611091565b925050808061053a906110b3565b9150506103ac565b8060000361029557604051630a96dcbd60e11b815260040160405180910390fd5b3360009081526003602052604090205460ff16610593576040516360ece74160e01b815260040160405180910390fd5b61059e83838361069b565b505050565b6000546001600160a01b031633146105ce5760405163070545c960e51b815260040160405180910390fd5b6105d781610bd4565b50565b6001600160a01b038216600081815260036020908152604091829020805460ff19168515159081179091558251938452908301527f3cece36ac6216147f57b10bb30975f82b18b8b290a7925c322277e684afcce4a910160405180910390a15050565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000828152600260205260409020546001600160a01b0316806108125760405163f6c0092760e01b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f6c0092790602401602060405180830381865afa15801561071d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074191906110cc565b90506001600160a01b0381166107ea57604051632e60fe9b60e11b81526004810184905262ffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635cc1fd36906044016020604051808303816000875af11580156107c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e791906110cc565b90505b600083815260026020526040902080546001600160a01b0319166001600160a01b0383161790555b6040516308f944b560e21b81526001600160a01b038216906323e512d4906108409087908690600401610ff9565b6020604051808303816000875af115801561085f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610883919061105e565b156108cc576040805162ffffff8416815233602082015284917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2610bce565b6000816001600160a01b0316639fdbd4d76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109309190610fdc565b90508262ffffff168162ffffff16111561095d57604051630a96dcbd60e11b815260040160405180910390fd5b600084815260046020908152604080832062ffffff8716845290915281208054909103610a465760005b8651811015610a0557818782815181106109a3576109a3610fa9565b6020908102919091018101518254600181018455600093845292829020815193018054919092015162ffffff166401000000000266ffffffffffffff1990911663ffffffff909316929092179190911790556109fe816110b3565b9050610987565b506040805162ffffff8616815233602082015286917fca8a146eac241d31b0d3d0650d8747b21a7d1f1a21c55abdbb7209740d742dd1910160405180910390a25b8362ffffff168262ffffff161161029557600085815260046020908152604080832062ffffff86168452825280832080548251818502810185019093528083529193909284015b82821015610ad4576000848152602090819020604080518082019091529084015463ffffffff81168252640100000000900460020b81830152825260019092019101610a8d565b505050509550600086511115610295576040516308f944b560e21b81526001600160a01b038416906323e512d490610b129089908690600401610ff9565b6020604051808303816000875af1158015610b31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b55919061105e565b506040805162ffffff8416815233602082015286917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2600085815260046020908152604080832062ffffff861684529091528120610bbc91610c5d565b81610bc681611091565b925050610a46565b50505050565b6001600160a01b038116610bfb5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910160405180910390a150565b50805460008255906000526020600020908101906105d791905b80821115610c9557805466ffffffffffffff19168155600101610c77565b5090565b60008083601f840112610cab57600080fd5b50813567ffffffffffffffff811115610cc357600080fd5b6020830191508360208260051b8501011115610cde57600080fd5b9250929050565b60008060008060408587031215610cfb57600080fd5b843567ffffffffffffffff80821115610d1357600080fd5b610d1f88838901610c99565b90965094506020870135915080821115610d3857600080fd5b50610d4587828801610c99565b95989497509550505050565b600060208284031215610d6357600080fd5b5035919050565b6001600160a01b03811681146105d757600080fd5b80151581146105d757600080fd5b60008060408385031215610da057600080fd5b8235610dab81610d6a565b91506020830135610dbb81610d7f565b809150509250929050565b60008060408385031215610dd957600080fd5b50508035926020909101359150565b600060208284031215610dfa57600080fd5b8135610e0581610d6a565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610e4557610e45610e0c565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e7457610e74610e0c565b604052919050565b62ffffff811681146105d757600080fd5b8035610e9881610e7c565b919050565b600080600060608486031215610eb257600080fd5b833567ffffffffffffffff80821115610eca57600080fd5b818601915086601f830112610ede57600080fd5b8135602082821115610ef257610ef2610e0c565b610f00818360051b01610e4b565b828152818101935060069290921b840181019189831115610f2057600080fd5b938101935b82851015610f88576040858b031215610f3e5760008081fd5b610f46610e22565b853563ffffffff81168114610f5b5760008081fd5b815285830135600281900b8114610f725760008081fd5b8184015284526040949094019392810192610f25565b96508701359450610fa0925050604086019050610e8d565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610fd157600080fd5b8135610e0581610d7f565b600060208284031215610fee57600080fd5b8151610e0581610e7c565b60408082528351828201819052600091906020906060850190828801855b82811015611045578151805163ffffffff16855285015160020b858501529285019290840190600101611017565b50505062ffffff95909516930192909252509092915050565b60006020828403121561107057600080fd5b8151610e0581610d7f565b634e487b7160e01b600052601160045260246000fd5b600062ffffff8083168181036110a9576110a961107b565b6001019392505050565b6000600182016110c5576110c561107b565b5060010190565b6000602082840312156110de57600080fd5b8151610e0581610d6a56fea2646970667358221220feefa69a3de86bbaf7ecd4017a75d5900e14dae7c288b4dcb2f4bcea3c8fdb5264736f6c634300080f0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c8063a853456211610071578063a853456214610137578063b893cce21461014a578063c7f7fb901461017d578063d34ad409146101a4578063e3056a34146101b7578063f235757f146101ca57600080fd5b80630c340a24146100ae5780630ddb5dd2146100de57806313f6986d146100f35780636607baca146100fb578063954e863e14610124575b600080fd5b6000546100c1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100f16100ec366004610ce5565b6101dd565b005b6100f161029d565b6100c1610109366004610d51565b6002602052600090815260409020546001600160a01b031681565b6100f1610132366004610d8d565b6102d2565b6100f1610145366004610dc6565b61030b565b61016d610158366004610de8565b60036020526000908152604090205460ff1681565b60405190151581526020016100d5565b6100c17f000000000000000000000000000000000000000000000000000000000000000081565b6100f16101b2366004610e9d565b610563565b6001546100c1906001600160a01b031681565b6100f16101d8366004610de8565b6105a3565b6000546001600160a01b031633146102085760405163070545c960e51b815260040160405180910390fd5b8281811461022c576040516001621398b960e31b0319815260040160405180910390fd5b60005b818110156102955761028d86868381811061024c5761024c610fa9565b90506020020160208101906102619190610de8565b85858481811061027357610273610fa9565b90506020020160208101906102889190610fbf565b6105da565b60010161022f565b505050505050565b6001546001600160a01b031633146102c857604051639ba0305d60e01b815260040160405180910390fd5b6102d061063d565b565b6000546001600160a01b031633146102fd5760405163070545c960e51b815260040160405180910390fd5b61030782826105da565b5050565b6000828152600260205260409020546001600160a01b0316806103415760405163d92e233d60e01b815260040160405180910390fd5b60606000826001600160a01b0316639fdbd4d76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610fdc565b905060005b8415806103b857508481105b1561054257600086815260046020908152604080832062ffffff86168452825280832080548251818502810185019093528083529193909284015b8282101561043a576000848152602090819020604080518082019091529084015463ffffffff81168252640100000000900460020b818301528252600190920191016103f3565b505050509250600083511115610542576040516308f944b560e21b81526001600160a01b038516906323e512d4906104789086908690600401610ff9565b6020604051808303816000875af1158015610497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bb919061105e565b506040805162ffffff8416815233602082015287917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2600086815260046020908152604080832062ffffff86168452909152812061052291610c5d565b8161052c81611091565b925050808061053a906110b3565b9150506103ac565b8060000361029557604051630a96dcbd60e11b815260040160405180910390fd5b3360009081526003602052604090205460ff16610593576040516360ece74160e01b815260040160405180910390fd5b61059e83838361069b565b505050565b6000546001600160a01b031633146105ce5760405163070545c960e51b815260040160405180910390fd5b6105d781610bd4565b50565b6001600160a01b038216600081815260036020908152604091829020805460ff19168515159081179091558251938452908301527f3cece36ac6216147f57b10bb30975f82b18b8b290a7925c322277e684afcce4a910160405180910390a15050565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000828152600260205260409020546001600160a01b0316806108125760405163f6c0092760e01b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f6c0092790602401602060405180830381865afa15801561071d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074191906110cc565b90506001600160a01b0381166107ea57604051632e60fe9b60e11b81526004810184905262ffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635cc1fd36906044016020604051808303816000875af11580156107c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e791906110cc565b90505b600083815260026020526040902080546001600160a01b0319166001600160a01b0383161790555b6040516308f944b560e21b81526001600160a01b038216906323e512d4906108409087908690600401610ff9565b6020604051808303816000875af115801561085f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610883919061105e565b156108cc576040805162ffffff8416815233602082015284917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2610bce565b6000816001600160a01b0316639fdbd4d76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109309190610fdc565b90508262ffffff168162ffffff16111561095d57604051630a96dcbd60e11b815260040160405180910390fd5b600084815260046020908152604080832062ffffff8716845290915281208054909103610a465760005b8651811015610a0557818782815181106109a3576109a3610fa9565b6020908102919091018101518254600181018455600093845292829020815193018054919092015162ffffff166401000000000266ffffffffffffff1990911663ffffffff909316929092179190911790556109fe816110b3565b9050610987565b506040805162ffffff8616815233602082015286917fca8a146eac241d31b0d3d0650d8747b21a7d1f1a21c55abdbb7209740d742dd1910160405180910390a25b8362ffffff168262ffffff161161029557600085815260046020908152604080832062ffffff86168452825280832080548251818502810185019093528083529193909284015b82821015610ad4576000848152602090819020604080518082019091529084015463ffffffff81168252640100000000900460020b81830152825260019092019101610a8d565b505050509550600086511115610295576040516308f944b560e21b81526001600160a01b038416906323e512d490610b129089908690600401610ff9565b6020604051808303816000875af1158015610b31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b55919061105e565b506040805162ffffff8416815233602082015286917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2600085815260046020908152604080832062ffffff861684529091528120610bbc91610c5d565b81610bc681611091565b925050610a46565b50505050565b6001600160a01b038116610bfb5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910160405180910390a150565b50805460008255906000526020600020908101906105d791905b80821115610c9557805466ffffffffffffff19168155600101610c77565b5090565b60008083601f840112610cab57600080fd5b50813567ffffffffffffffff811115610cc357600080fd5b6020830191508360208260051b8501011115610cde57600080fd5b9250929050565b60008060008060408587031215610cfb57600080fd5b843567ffffffffffffffff80821115610d1357600080fd5b610d1f88838901610c99565b90965094506020870135915080821115610d3857600080fd5b50610d4587828801610c99565b95989497509550505050565b600060208284031215610d6357600080fd5b5035919050565b6001600160a01b03811681146105d757600080fd5b80151581146105d757600080fd5b60008060408385031215610da057600080fd5b8235610dab81610d6a565b91506020830135610dbb81610d7f565b809150509250929050565b60008060408385031215610dd957600080fd5b50508035926020909101359150565b600060208284031215610dfa57600080fd5b8135610e0581610d6a565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610e4557610e45610e0c565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e7457610e74610e0c565b604052919050565b62ffffff811681146105d757600080fd5b8035610e9881610e7c565b919050565b600080600060608486031215610eb257600080fd5b833567ffffffffffffffff80821115610eca57600080fd5b818601915086601f830112610ede57600080fd5b8135602082821115610ef257610ef2610e0c565b610f00818360051b01610e4b565b828152818101935060069290921b840181019189831115610f2057600080fd5b938101935b82851015610f88576040858b031215610f3e5760008081fd5b610f46610e22565b853563ffffffff81168114610f5b5760008081fd5b815285830135600281900b8114610f725760008081fd5b8184015284526040949094019392810192610f25565b96508701359450610fa0925050604086019050610e8d565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610fd157600080fd5b8135610e0581610d7f565b600060208284031215610fee57600080fd5b8151610e0581610e7c565b60408082528351828201819052600091906020906060850190828801855b82811015611045578151805163ffffffff16855285015160020b858501529285019290840190600101611017565b50505062ffffff95909516930192909252509092915050565b60006020828403121561107057600080fd5b8151610e0581610d7f565b634e487b7160e01b600052601160045260246000fd5b600062ffffff8083168181036110a9576110a961107b565b6001019392505050565b6000600182016110c5576110c561107b565b5060010190565b6000602082840312156110de57600080fd5b8151610e0581610d6a56fea2646970667358221220feefa69a3de86bbaf7ecd4017a75d5900e14dae7c288b4dcb2f4bcea3c8fdb5264736f6c634300080f0033", "devdoc": { "kind": "dev", "methods": { @@ -365,6 +390,13 @@ "_pendingGovernor": "Address of the proposed new governor" } }, + "syncObservations(bytes32,uint256)": { + "details": "Use _maxObservations = 0 to process all possible cached observations", + "params": { + "_maxObservations": "Maximum number of observations to process", + "_poolSalt": "Identifier of the pool to fetch" + } + }, "whitelistAdapter(address,bool)": { "params": { "_isWhitelisted": "New whitelisting status", @@ -459,9 +491,12 @@ "AdapterWhitelisted(address,bool)": { "notice": "Emitted when a new adapter whitelisting rule is set" }, - "ObservationsAdded(bytes32,uint24,(uint32,int24)[],address)": { + "ObservationsAdded(bytes32,uint24,address)": { "notice": "Emitted when a broadcast observation is succesfully processed" }, + "ObservationsCached(bytes32,uint24,address)": { + "notice": "Emitted when a broadcast observation is cached for later processing" + }, "PendingGovernorAccepted(address)": { "notice": "Emitted when a new governor is set" }, @@ -483,6 +518,9 @@ "setPendingGovernor(address)": { "notice": "Allows a governor to propose a new governor" }, + "syncObservations(bytes32,uint256)": { + "notice": "Allows any address to attempt to insert cached observations" + }, "whitelistAdapter(address,bool)": { "notice": "Allows governance to set an adapter whitelisted state" }, @@ -515,20 +553,28 @@ "type": "t_address" }, { - "astId": 15154, + "astId": 14967, "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", "label": "deployedOracles", "offset": 0, "slot": "2", - "type": "t_mapping(t_bytes32,t_contract(IOracleSidechain)18424)" + "type": "t_mapping(t_bytes32,t_contract(IOracleSidechain)18334)" }, { - "astId": 15160, + "astId": 14973, "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", "label": "whitelistedAdapters", "offset": 0, "slot": "3", - "type": "t_mapping(t_contract(IBridgeReceiverAdapter)18559,t_bool)" + "type": "t_mapping(t_contract(IBridgeReceiverAdapter)18469,t_bool)" + }, + { + "astId": 14981, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "_cachedObservations", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_bytes32,t_mapping(t_uint24,t_array(t_struct(ObservationData)18176_storage)dyn_storage))" } ], "types": { @@ -537,6 +583,12 @@ "label": "address", "numberOfBytes": "20" }, + "t_array(t_struct(ObservationData)18176_storage)dyn_storage": { + "base": "t_struct(ObservationData)18176_storage", + "encoding": "dynamic_array", + "label": "struct IOracleSidechain.ObservationData[]", + "numberOfBytes": "32" + }, "t_bool": { "encoding": "inplace", "label": "bool", @@ -547,29 +599,81 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_contract(IBridgeReceiverAdapter)18559": { + "t_contract(IBridgeReceiverAdapter)18469": { "encoding": "inplace", "label": "contract IBridgeReceiverAdapter", "numberOfBytes": "20" }, - "t_contract(IOracleSidechain)18424": { + "t_contract(IOracleSidechain)18334": { "encoding": "inplace", "label": "contract IOracleSidechain", "numberOfBytes": "20" }, - "t_mapping(t_bytes32,t_contract(IOracleSidechain)18424)": { + "t_int24": { + "encoding": "inplace", + "label": "int24", + "numberOfBytes": "3" + }, + "t_mapping(t_bytes32,t_contract(IOracleSidechain)18334)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => contract IOracleSidechain)", "numberOfBytes": "32", - "value": "t_contract(IOracleSidechain)18424" + "value": "t_contract(IOracleSidechain)18334" + }, + "t_mapping(t_bytes32,t_mapping(t_uint24,t_array(t_struct(ObservationData)18176_storage)dyn_storage))": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => mapping(uint24 => struct IOracleSidechain.ObservationData[]))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint24,t_array(t_struct(ObservationData)18176_storage)dyn_storage)" }, - "t_mapping(t_contract(IBridgeReceiverAdapter)18559,t_bool)": { + "t_mapping(t_contract(IBridgeReceiverAdapter)18469,t_bool)": { "encoding": "mapping", - "key": "t_contract(IBridgeReceiverAdapter)18559", + "key": "t_contract(IBridgeReceiverAdapter)18469", "label": "mapping(contract IBridgeReceiverAdapter => bool)", "numberOfBytes": "32", "value": "t_bool" + }, + "t_mapping(t_uint24,t_array(t_struct(ObservationData)18176_storage)dyn_storage)": { + "encoding": "mapping", + "key": "t_uint24", + "label": "mapping(uint24 => struct IOracleSidechain.ObservationData[])", + "numberOfBytes": "32", + "value": "t_array(t_struct(ObservationData)18176_storage)dyn_storage" + }, + "t_struct(ObservationData)18176_storage": { + "encoding": "inplace", + "label": "struct IOracleSidechain.ObservationData", + "members": [ + { + "astId": 18173, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "blockTimestamp", + "offset": 0, + "slot": "0", + "type": "t_uint32" + }, + { + "astId": 18175, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "tick", + "offset": 4, + "slot": "0", + "type": "t_int24" + } + ], + "numberOfBytes": "32" + }, + "t_uint24": { + "encoding": "inplace", + "label": "uint24", + "numberOfBytes": "3" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" } } } diff --git a/deployments/optimism/OracleFactory.json b/deployments/optimism/OracleFactory.json index eff66f9..d7bed04 100644 --- a/deployments/optimism/OracleFactory.json +++ b/deployments/optimism/OracleFactory.json @@ -1,5 +1,5 @@ { - "address": "0x1ce81290Eb4c10cC9Fa71256799665423e87b628", + "address": "0x0BcD059c1546359b45f2606Ed6E08e1F5ef4f4Bf", "abi": [ { "inputs": [ @@ -394,44 +394,44 @@ "type": "function" } ], - "transactionHash": "0x85688f7d876ee3aaaaa379a0bdc28e601ba323daf1a65d9ddfc6cc18d1eeab35", + "transactionHash": "0x70b5d792a0b1c373ea60f48ae24262eeb31f29f47a16f07c0d93f256475911db", "receipt": { "to": null, - "from": "0xb7157Be5c36aE31344e13F49bb4d55066DbB6aC4", - "contractAddress": "0x1ce81290Eb4c10cC9Fa71256799665423e87b628", - "transactionIndex": 0, - "gasUsed": "2226439", - "logsBloom": "0x00000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x15a08cbcf7fd117dde4d2fe42af487b736f247b29a0fdb04df07b8fa7c2b3a59", - "transactionHash": "0x85688f7d876ee3aaaaa379a0bdc28e601ba323daf1a65d9ddfc6cc18d1eeab35", + "from": "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "contractAddress": "0x0BcD059c1546359b45f2606Ed6E08e1F5ef4f4Bf", + "transactionIndex": 17, + "gasUsed": "2228781", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000800000000100000000000000000000000000", + "blockHash": "0x388b0160c1518f1dc9fef8088673632d36f06a8e6c4eef84fb3b0b56467f1a0e", + "transactionHash": "0x70b5d792a0b1c373ea60f48ae24262eeb31f29f47a16f07c0d93f256475911db", "logs": [ { - "transactionIndex": 0, - "blockNumber": 72611784, - "transactionHash": "0x85688f7d876ee3aaaaa379a0bdc28e601ba323daf1a65d9ddfc6cc18d1eeab35", - "address": "0x1ce81290Eb4c10cC9Fa71256799665423e87b628", + "transactionIndex": 17, + "blockNumber": 124330024, + "transactionHash": "0x70b5d792a0b1c373ea60f48ae24262eeb31f29f47a16f07c0d93f256475911db", + "address": "0x0BcD059c1546359b45f2606Ed6E08e1F5ef4f4Bf", "topics": [ "0x23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be" ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000420", - "logIndex": 0, - "blockHash": "0x15a08cbcf7fd117dde4d2fe42af487b736f247b29a0fdb04df07b8fa7c2b3a59" + "data": "0x0000000000000000000000000000000000000000000000000000000000042069", + "logIndex": 84, + "blockHash": "0x388b0160c1518f1dc9fef8088673632d36f06a8e6c4eef84fb3b0b56467f1a0e" } ], - "blockNumber": 72611784, - "cumulativeGasUsed": "2226439", + "blockNumber": 124330024, + "cumulativeGasUsed": "7524415", "status": 1, "byzantium": true }, "args": [ - "0xb7157Be5c36aE31344e13F49bb4d55066DbB6aC4", - "0x0000000000000000000000000000000000000420" + "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "0x0000000000000000000000000000000000042069" ], - "numDeployments": 2, - "solcInputHash": "1a064550c306047de745b0aa850ace2a", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDataReceiver\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"}],\"name\":\"DataReceiverSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"_initialCardinality\",\"type\":\"uint16\"}],\"name\":\"InitialCardinalitySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"_initialNonce\",\"type\":\"uint24\"}],\"name\":\"OracleDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ORACLE_INIT_CODE_HASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dataReceiver\",\"outputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"_initialNonce\",\"type\":\"uint24\"}],\"name\":\"deployOracle\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenA\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenB\",\"type\":\"address\"},{\"internalType\":\"uint24\",\"name\":\"_fee\",\"type\":\"uint24\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenA\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenB\",\"type\":\"address\"},{\"internalType\":\"uint24\",\"name\":\"_fee\",\"type\":\"uint24\"}],\"name\":\"getPoolSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint16\",\"name\":\"_observationCardinalityNext\",\"type\":\"uint16\"}],\"name\":\"increaseOracleCardinality\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialCardinality\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleParameters\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"poolNonce\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"cardinality\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"}],\"name\":\"setDataReceiver\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"_initialCardinality\",\"type\":\"uint16\"}],\"name\":\"setInitialCardinality\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"setPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"deployOracle(bytes32,uint24)\":{\"details\":\"Requires that the salt has not been deployed before\",\"params\":{\"_poolSalt\":\"Pool salt that deterministically binds an oracle with a pool\"},\"returns\":{\"_oracle\":\"The address of the newly deployed oracle\"}},\"getPool(address,address,uint24)\":{\"params\":{\"_fee\":\"The fee denominated in hundredths of a bip\",\"_tokenA\":\"The contract address of either token0 or token1\",\"_tokenB\":\"The contract address of the other token\"},\"returns\":{\"_oracle\":\"The oracle address\"}},\"getPool(bytes32)\":{\"params\":{\"_poolSalt\":\"Identifier of both the pool and the oracle\"},\"returns\":{\"_oracle\":\"The address (if deployed) of the correspondant oracle\"}},\"getPoolSalt(address,address,uint24)\":{\"params\":{\"_fee\":\"The fee denominated in hundredths of a bip\",\"_tokenA\":\"The contract address of either token0 or token1\",\"_tokenB\":\"The contract address of the other token\"},\"returns\":{\"_poolSalt\":\"Pool salt for inquired parameters\"}},\"setDataReceiver(address)\":{\"details\":\"Will disallow the previous dataReceiver\",\"params\":{\"_dataReceiver\":\"The address of the new allowed dataReceiver\"}},\"setInitialCardinality(uint16)\":{\"params\":{\"_initialCardinality\":\"The initial size of the observations memory storage for newly deployed pools\"}},\"setPendingGovernor(address)\":{\"params\":{\"_pendingGovernor\":\"Address of the proposed new governor\"}}},\"stateVariables\":{\"ORACLE_INIT_CODE_HASH\":{\"return\":\"The oracle creation code hash used to calculate their address\",\"returns\":{\"_0\":\"The oracle creation code hash used to calculate their address\"}},\"dataReceiver\":{\"return\":\"The address of the DataReceiver for the oracles to consult\",\"returns\":{\"_0\":\"The address of the DataReceiver for the oracles to consult\"}},\"initialCardinality\":{\"return\":\"The initial size of the observations memory storage for newly deployed pools\",\"returns\":{\"_0\":\"The initial size of the observations memory storage for newly deployed pools\"}},\"oracleParameters\":{\"returns\":{\"cardinality\":\"The size of the observations memory storage\",\"poolNonce\":\"The initial nonce of the pool data\",\"poolSalt\":\"The id of both the oracle and the pool\"}}},\"title\":\"The OracleFactory contract\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"OnlyDataReceiver()\":[{\"notice\":\"Thrown when a contract other than the DataReceiver tries to deploy an oracle\"}],\"OnlyGovernor()\":[{\"notice\":\"Thrown if a non-governor user tries to call a OnlyGovernor function\"}],\"OnlyPendingGovernor()\":[{\"notice\":\"Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"events\":{\"DataReceiverSet(address)\":{\"notice\":\"Emitted when a new DataReceiver is set\"},\"InitialCardinalitySet(uint16)\":{\"notice\":\"Emitted when a new initial oracle cardinality is set\"},\"OracleDeployed(bytes32,address,uint24)\":{\"notice\":\"Emitted when a new oracle is deployed\"},\"PendingGovernorAccepted(address)\":{\"notice\":\"Emitted when a new governor is set\"},\"PendingGovernorSet(address,address)\":{\"notice\":\"Emitted when a new pending governor is set\"}},\"kind\":\"user\",\"methods\":{\"acceptPendingGovernor()\":{\"notice\":\"Allows a proposed governor to accept the governance\"},\"deployOracle(bytes32,uint24)\":{\"notice\":\"Deploys a new oracle given an inputted salt\"},\"getPool(address,address,uint24)\":{\"notice\":\"Overrides UniV3Factory getPool mapping\"},\"getPool(bytes32)\":{\"notice\":\"Tracks the addresses of the oracle by poolSalt\"},\"setDataReceiver(address)\":{\"notice\":\"Allows governor to set a new allowed dataReceiver\"},\"setInitialCardinality(uint16)\":{\"notice\":\"Allows governor to set a new initial cardinality for new oracles\"},\"setPendingGovernor(address)\":{\"notice\":\"Allows a governor to propose a new governor\"}},\"notice\":\"Handles the deployment of new OracleSidechains\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/OracleFactory.sol\":\"OracleFactory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '../interfaces/IGovernable.sol';\\n\\n/// @title Governable contract\\n/// @notice Manages the governor role\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public governor;\\n\\n /// @inheritdoc IGovernable\\n address public pendingGovernor;\\n\\n constructor(address _governor) {\\n if (_governor == address(0)) revert ZeroAddress();\\n governor = _governor;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\\n _setPendingGovernor(_pendingGovernor);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptPendingGovernor() external onlyPendingGovernor {\\n _acceptPendingGovernor();\\n }\\n\\n function _setPendingGovernor(address _pendingGovernor) internal {\\n if (_pendingGovernor == address(0)) revert ZeroAddress();\\n pendingGovernor = _pendingGovernor;\\n emit PendingGovernorSet(governor, _pendingGovernor);\\n }\\n\\n function _acceptPendingGovernor() internal {\\n governor = pendingGovernor;\\n delete pendingGovernor;\\n emit PendingGovernorAccepted(governor);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governor\\n modifier onlyGovernor() {\\n if (msg.sender != governor) revert OnlyGovernor();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernor\\n modifier onlyPendingGovernor() {\\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x3f11408cfcb015a99dc417e075c8ebc39b796fc2adc3e81b036487e4486881b3\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity >=0.8.8 <0.9.0;\\n\\n/// @title Provides functions for deriving a UniswapV3Pool address from its factory, tokens and fee\\nlibrary Create2Address {\\n /// @notice Deterministically computes the pool address given the factory, salt and initCodeHash\\n /// @param _factory The Uniswap V3 factory contract address\\n /// @param _salt The PoolKey encoded bytes\\n /// @param _initCodeHash The Init Code Hash of the target\\n /// @return _pool The contract address of the target UniswapV3Pool\\n function computeAddress(address _factory, bytes32 _salt, bytes32 _initCodeHash)\\n internal\\n pure\\n returns (address _pool)\\n {\\n _pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', _factory, _salt, _initCodeHash)))));\\n }\\n}\\n\",\"keccak256\":\"0x867e71cdb6b5b3a4b5f3e6d9bd27262a13d6b54eb18957e8c27cfbbff886ad9d\",\"license\":\"BUSL-1.1\"},\"@uniswap/v3-core/contracts/libraries/Oracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.0;\\n\\n/// @title Oracle\\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\\n/// @dev Instances of stored oracle data, \\\"observations\\\", are collected in the oracle array\\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\\n/// Observations are overwritten when the full length of the oracle array is populated.\\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\\nlibrary Oracle {\\n error I();\\n error OLD();\\n\\n struct Observation {\\n // the block timestamp of the observation\\n uint32 blockTimestamp;\\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\\n int56 tickCumulative;\\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\\n uint160 secondsPerLiquidityCumulativeX128;\\n // whether or not the observation is initialized\\n bool initialized;\\n }\\n\\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\\n /// @param last The specified observation to be transformed\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @return Observation The newly populated observation\\n function transform(\\n Observation memory last,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity\\n ) private pure returns (Observation memory) {\\n unchecked {\\n uint32 delta = blockTimestamp - last.blockTimestamp;\\n return\\n Observation({\\n blockTimestamp: blockTimestamp,\\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\\n initialized: true\\n });\\n }\\n }\\n\\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\\n /// @param self The stored oracle array\\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\\n /// @return cardinality The number of populated elements in the oracle array\\n /// @return cardinalityNext The new length of the oracle array, independent of population\\n function initialize(Observation[65535] storage self, uint32 time)\\n internal\\n returns (uint16 cardinality, uint16 cardinalityNext)\\n {\\n self[0] = Observation({\\n blockTimestamp: time,\\n tickCumulative: 0,\\n secondsPerLiquidityCumulativeX128: 0,\\n initialized: true\\n });\\n return (1, 1);\\n }\\n\\n /// @notice Writes an oracle observation to the array\\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\\n /// @param self The stored oracle array\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @param cardinalityNext The new length of the oracle array, independent of population\\n /// @return indexUpdated The new index of the most recently written element in the oracle array\\n /// @return cardinalityUpdated The new cardinality of the oracle array\\n function write(\\n Observation[65535] storage self,\\n uint16 index,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity,\\n uint16 cardinality,\\n uint16 cardinalityNext\\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\\n unchecked {\\n Observation memory last = self[index];\\n\\n // early return if we've already written an observation this block\\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\\n\\n // if the conditions are right, we can bump the cardinality\\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\\n cardinalityUpdated = cardinalityNext;\\n } else {\\n cardinalityUpdated = cardinality;\\n }\\n\\n indexUpdated = (index + 1) % cardinalityUpdated;\\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\\n }\\n }\\n\\n /// @notice Prepares the oracle array to store up to `next` observations\\n /// @param self The stored oracle array\\n /// @param current The current next cardinality of the oracle array\\n /// @param next The proposed next cardinality which will be populated in the oracle array\\n /// @return next The next cardinality which will be populated in the oracle array\\n function grow(\\n Observation[65535] storage self,\\n uint16 current,\\n uint16 next\\n ) internal returns (uint16) {\\n unchecked {\\n if (current <= 0) revert I();\\n // no-op if the passed next value isn't greater than the current next value\\n if (next <= current) return current;\\n // store in each slot to prevent fresh SSTOREs in swaps\\n // this data will not be used because the initialized boolean is still false\\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\\n return next;\\n }\\n }\\n\\n /// @notice comparator for 32-bit timestamps\\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\\n /// @param time A timestamp truncated to 32 bits\\n /// @param a A comparison timestamp from which to determine the relative position of `time`\\n /// @param b From which to determine the relative position of `time`\\n /// @return Whether `a` is chronologically <= `b`\\n function lte(\\n uint32 time,\\n uint32 a,\\n uint32 b\\n ) private pure returns (bool) {\\n unchecked {\\n // if there hasn't been overflow, no need to adjust\\n if (a <= time && b <= time) return a <= b;\\n\\n uint256 aAdjusted = a > time ? a : a + 2**32;\\n uint256 bAdjusted = b > time ? b : b + 2**32;\\n\\n return aAdjusted <= bAdjusted;\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\\n /// The result may be the same observation, or adjacent observations.\\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation recorded before, or at, the target\\n /// @return atOrAfter The observation recorded at, or after, the target\\n function binarySearch(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n uint16 index,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n uint256 l = (index + 1) % cardinality; // oldest observation\\n uint256 r = l + cardinality - 1; // newest observation\\n uint256 i;\\n while (true) {\\n i = (l + r) / 2;\\n\\n beforeOrAt = self[i % cardinality];\\n\\n // we've landed on an uninitialized tick, keep searching higher (more recently)\\n if (!beforeOrAt.initialized) {\\n l = i + 1;\\n continue;\\n }\\n\\n atOrAfter = self[(i + 1) % cardinality];\\n\\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\\n\\n // check if we've found the answer!\\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\\n\\n if (!targetAtOrAfter) r = i - 1;\\n else l = i + 1;\\n }\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\\n /// @dev Assumes there is at least 1 initialized observation.\\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param tick The active tick at the time of the returned or simulated observation\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The total pool liquidity at the time of the call\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\\n function getSurroundingObservations(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n // optimistically set before to the newest observation\\n beforeOrAt = self[index];\\n\\n // if the target is chronologically at or after the newest observation, we can early return\\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\\n if (beforeOrAt.blockTimestamp == target) {\\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\\n return (beforeOrAt, atOrAfter);\\n } else {\\n // otherwise, we need to transform\\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\\n }\\n }\\n\\n // now, set before to the oldest observation\\n beforeOrAt = self[(index + 1) % cardinality];\\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\\n\\n // ensure that the target is chronologically at or after the oldest observation\\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\\n\\n // if we've reached this point, we have to binary search\\n return binarySearch(self, time, target, index, cardinality);\\n }\\n }\\n\\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\\n /// at exactly the timestamp between the two observations.\\n /// @param self The stored oracle array\\n /// @param time The current block timestamp\\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\\n function observeSingle(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 secondsAgo,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\\n unchecked {\\n if (secondsAgo == 0) {\\n Observation memory last = self[index];\\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\\n }\\n\\n uint32 target = time - secondsAgo;\\n\\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\\n self,\\n time,\\n target,\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n\\n if (target == beforeOrAt.blockTimestamp) {\\n // we're at the left boundary\\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\\n } else if (target == atOrAfter.blockTimestamp) {\\n // we're at the right boundary\\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\\n } else {\\n // we're in the middle\\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\\n return (\\n beforeOrAt.tickCumulative +\\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\\n int56(uint56(targetDelta)),\\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\\n uint160(\\n (uint256(\\n atOrAfter.secondsPerLiquidityCumulativeX128 -\\n beforeOrAt.secondsPerLiquidityCumulativeX128\\n ) * targetDelta) / observationTimeDelta\\n )\\n );\\n }\\n }\\n }\\n\\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\\n /// @dev Reverts if `secondsAgos` > oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\\n function observe(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32[] memory secondsAgos,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\\n unchecked {\\n if (cardinality <= 0) revert I();\\n\\n tickCumulatives = new int56[](secondsAgos.length);\\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\\n for (uint256 i = 0; i < secondsAgos.length; i++) {\\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\\n self,\\n time,\\n secondsAgos[i],\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa25b18af947c36b9add9e229c361beb6aba176fb435d7a24e6dc723cbc187442\",\"license\":\"BUSL-1.1\"},\"@uniswap/v3-core/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity ^0.8.0;\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n error T();\\n error R();\\n\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n unchecked {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n if (absTick > uint256(int256(MAX_TICK))) revert T();\\n\\n uint256 ratio = absTick & 0x1 != 0\\n ? 0xfffcb933bd6fad37aa2d162d1a594001\\n : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\\n /// ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n unchecked {\\n // second inequality must be < because the price can never reach the price at the max tick\\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5c57de03a91cc2ec8939865dbbcb0197bb6c353b711075eefd8e0fca5e102129\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/OracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\\nimport {OracleSidechain} from './OracleSidechain.sol';\\nimport {IOracleFactory, IOracleSidechain, IDataReceiver} from '../interfaces/IOracleFactory.sol';\\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\\n\\n/// @title The OracleFactory contract\\n/// @notice Handles the deployment of new OracleSidechains\\ncontract OracleFactory is IOracleFactory, Governable {\\n /// @inheritdoc IOracleFactory\\n IDataReceiver public dataReceiver;\\n\\n /// @inheritdoc IOracleFactory\\n OracleParameters public oracleParameters;\\n\\n /// @inheritdoc IOracleFactory\\n uint16 public initialCardinality = 144;\\n\\n /// @inheritdoc IOracleFactory\\n bytes32 public constant ORACLE_INIT_CODE_HASH = keccak256(type(OracleSidechain).creationCode);\\n\\n constructor(address _governor, IDataReceiver _dataReceiver) Governable(_governor) {\\n _setDataReceiver(_dataReceiver);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function deployOracle(bytes32 _poolSalt, uint24 _initialNonce) external onlyDataReceiver returns (IOracleSidechain _oracle) {\\n oracleParameters = OracleParameters({poolSalt: _poolSalt, poolNonce: _initialNonce, cardinality: initialCardinality});\\n _oracle = new OracleSidechain{salt: _poolSalt}();\\n\\n delete oracleParameters;\\n emit OracleDeployed(_poolSalt, address(_oracle), _initialNonce);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function setDataReceiver(IDataReceiver _dataReceiver) external onlyGovernor {\\n _setDataReceiver(_dataReceiver);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function setInitialCardinality(uint16 _initialCardinality) external onlyGovernor {\\n if (_initialCardinality == 0) revert ZeroAmount();\\n\\n initialCardinality = _initialCardinality;\\n emit InitialCardinalitySet(_initialCardinality);\\n }\\n\\n function increaseOracleCardinality(bytes32 _poolSalt, uint16 _observationCardinalityNext) external onlyGovernor {\\n IOracleSidechain _oracle = getPool(_poolSalt);\\n _oracle.increaseObservationCardinalityNext(_observationCardinalityNext);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle) {\\n bytes32 _poolSalt = getPoolSalt(_tokenA, _tokenB, _fee);\\n _oracle = getPool(_poolSalt);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function getPool(bytes32 _poolSalt) public view returns (IOracleSidechain _oracle) {\\n _oracle = IOracleSidechain(Create2Address.computeAddress(address(this), _poolSalt, ORACLE_INIT_CODE_HASH));\\n if (address(_oracle).code.length == 0) return IOracleSidechain(address(0));\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) public pure returns (bytes32 _poolSalt) {\\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\\n _poolSalt = keccak256(abi.encode(_token0, _token1, _fee));\\n }\\n\\n function _setDataReceiver(IDataReceiver _dataReceiver) private {\\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\\n\\n dataReceiver = _dataReceiver;\\n emit DataReceiverSet(_dataReceiver);\\n }\\n\\n modifier onlyDataReceiver() {\\n if (msg.sender != address(dataReceiver)) revert OnlyDataReceiver();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xf0707ebeed3425fca5ccc20dfc2cb291859674ada92d5d651f7271ee3cef3d49\",\"license\":\"MIT\"},\"solidity/contracts/OracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\\n\\n/// @title The SidechainOracle contract\\n/// @notice Computes and stores on-chain price data from Mainnet\\ncontract OracleSidechain is IOracleSidechain {\\n using Oracle for Oracle.Observation[65535];\\n\\n /// @inheritdoc IOracleSidechain\\n IOracleFactory public immutable factory;\\n\\n struct Slot0 {\\n // the current price\\n uint160 sqrtPriceX96;\\n // the current tick\\n int24 tick;\\n // the most-recently updated index of the observations array\\n uint16 observationIndex;\\n // the current maximum number of observations that are being stored\\n uint16 observationCardinality;\\n // the next maximum number of observations to store, triggered in observations.write\\n uint16 observationCardinalityNext;\\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\\n // represented as an integer denominator (1/x)%\\n uint8 feeProtocol;\\n // whether the pool is locked\\n bool unlocked;\\n }\\n /// @inheritdoc IOracleSidechain\\n Slot0 public slot0;\\n\\n /// @inheritdoc IOracleSidechain\\n Oracle.Observation[65535] public observations;\\n\\n /// @inheritdoc IOracleSidechain\\n bytes32 public immutable poolSalt;\\n\\n uint24 public poolNonce;\\n /// @inheritdoc IOracleSidechain\\n address public token0;\\n /// @inheritdoc IOracleSidechain\\n address public token1;\\n /// @inheritdoc IOracleSidechain\\n uint24 public fee;\\n\\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\\n function _getBlockTimestamp() internal view virtual returns (uint32) {\\n return uint32(block.timestamp); // truncation is desired\\n }\\n\\n constructor() {\\n factory = IOracleFactory(msg.sender);\\n uint16 _cardinality;\\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\\n\\n slot0 = Slot0({\\n sqrtPriceX96: 0,\\n tick: 0,\\n observationIndex: _cardinality - 1,\\n observationCardinality: _cardinality,\\n observationCardinalityNext: _cardinality,\\n feeProtocol: 0,\\n unlocked: true\\n });\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external {\\n if (!slot0.unlocked) revert AI();\\n\\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\\n\\n token0 = _token0;\\n token1 = _token1;\\n fee = _fee;\\n slot0.unlocked = false;\\n\\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\\n {\\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\\n if (_poolNonce != poolNonce++) return false;\\n\\n uint256 _observationsDataLength = _observationsData.length;\\n for (uint256 _i; _i < _observationsDataLength; ) {\\n _write(_observationsData[_i]);\\n unchecked {\\n ++_i;\\n }\\n }\\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\\n\\n // emits UniV3 Swap event topic with minimal data\\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\\n return true;\\n }\\n\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\\n if (_observationCardinalityNext <= _observationCardinalityNextOld) revert AI();\\n slot0.observationCardinalityNext = _observationCardinalityNext;\\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\\n }\\n\\n function _write(ObservationData memory _observationData) private {\\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\\n slot0.observationIndex,\\n _observationData.blockTimestamp,\\n slot0.tick,\\n 0,\\n slot0.observationCardinality,\\n slot0.observationCardinalityNext\\n );\\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\\n slot0.tick = _observationData.tick;\\n }\\n\\n modifier onlyDataReceiver() {\\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\\n _;\\n }\\n\\n modifier onlyFactory() {\\n if (msg.sender != address(factory)) revert OnlyFactory();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x99aecf265a572613e65c6d10fe5d42637f7619b6f8039d9e61169ce97c36e92a\",\"license\":\"MIT\"},\"solidity/interfaces/IDataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleFactory} from './IOracleFactory.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\\n\\ninterface IDataReceiver is IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @notice Tracks already deployed oracles\\n /// @param _poolSalt The identifier of the oracle\\n /// @return _deployedOracle The address of the correspondant Oracle\\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\\n\\n /// @notice Tracks the whitelisting of bridge adapters\\n /// @param _adapter Address of the bridge adapter to consult\\n /// @return _isAllowed Whether a bridge adapter is whitelisted\\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a broadcast observation is succesfully processed\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _observationsData Array of tuples containing the dataset\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsAdded(\\n bytes32 indexed _poolSalt,\\n uint24 _poolNonce,\\n IOracleSidechain.ObservationData[] _observationsData,\\n address _receiverAdapter\\n );\\n\\n /// @notice Emitted when a new adapter whitelisting rule is set\\n /// @param _adapter Address of the adapter\\n /// @param _isAllowed New whitelisting status\\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\\n\\n // ERRORS\\n\\n /// @notice Thrown when the broadcast nonce is incorrect\\n error ObservationsNotWritable();\\n\\n /// @notice Thrown when a not-whitelisted adapter triggers an update\\n error UnallowedAdapter();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows whitelisted bridge adapters to push a broadcast\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _poolNonce Nonce of the observation broadcast\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external;\\n\\n /// @notice Allows governance to set an adapter whitelisted state\\n /// @param _receiverAdapter Address of the adapter\\n /// @param _isWhitelisted New whitelisting status\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\\n\\n /// @notice Allows governance to batch set adapters whitelisted state\\n /// @param _receiverAdapters Array of addresses of the adapter\\n /// @param _isWhitelisted Array of whitelisting status for each address\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\\n}\\n\",\"keccak256\":\"0x7970e1941b72624c5d92462a8648ffb95ee99e4132152cd720e13b45039df67c\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IDataReceiver} from './IDataReceiver.sol';\\n\\ninterface IOracleFactory is IGovernable {\\n // STRUCTS\\n\\n struct OracleParameters {\\n bytes32 poolSalt; // Identifier of the pool and oracle\\n uint24 poolNonce; // Initial nonce of the deployed pool\\n uint16 cardinality; // Initial cardinality of the deployed pool\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\\n //solhint-disable-next-line func-name-mixedcase\\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\\n\\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /// @return _poolSalt The id of both the oracle and the pool\\n /// @return _poolNonce The initial nonce of the pool data\\n /// @return _cardinality The size of the observations memory storage\\n function oracleParameters()\\n external\\n view\\n returns (\\n bytes32 _poolSalt,\\n uint24 _poolNonce,\\n uint16 _cardinality\\n );\\n\\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function initialCardinality() external view returns (uint16 _initialCardinality);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new oracle is deployed\\n /// @param _poolSalt The id of both the oracle and the pool\\n /// @param _oracle The address of the deployed oracle\\n /// @param _initialNonce The initial nonce of the pool data\\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\\n\\n /// @notice Emitted when a new DataReceiver is set\\n /// @param _dataReceiver The address of the new DataReceiver\\n event DataReceiverSet(IDataReceiver _dataReceiver);\\n\\n /// @notice Emitted when a new initial oracle cardinality is set\\n /// @param _initialCardinality The initial length of the observationCardinality array\\n event InitialCardinalitySet(uint16 _initialCardinality);\\n\\n // ERRORS\\n\\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\\n error OnlyDataReceiver();\\n\\n // FUNCTIONS\\n\\n /// @notice Deploys a new oracle given an inputted salt\\n /// @dev Requires that the salt has not been deployed before\\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\\n /// @return _oracle The address of the newly deployed oracle\\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\\n\\n /// @notice Allows governor to set a new allowed dataReceiver\\n /// @dev Will disallow the previous dataReceiver\\n /// @param _dataReceiver The address of the new allowed dataReceiver\\n function setDataReceiver(IDataReceiver _dataReceiver) external;\\n\\n /// @notice Allows governor to set a new initial cardinality for new oracles\\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function setInitialCardinality(uint16 _initialCardinality) external;\\n\\n /// @notice Overrides UniV3Factory getPool mapping\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _oracle The oracle address\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle);\\n\\n /// @notice Tracks the addresses of the oracle by poolSalt\\n /// @param _poolSalt Identifier of both the pool and the oracle\\n /// @return _oracle The address (if deployed) of the correspondant oracle\\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\\n\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _poolSalt Pool salt for inquired parameters\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (bytes32 _poolSalt);\\n}\\n\",\"keccak256\":\"0xc32bfc32a274923ce1a089acc024396e702ae354773f0ac0a683e43ded904954\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleFactory} from './IOracleFactory.sol';\\n\\ninterface IOracleSidechain {\\n // STRUCTS\\n\\n struct ObservationData {\\n uint32 blockTimestamp;\\n int24 tick;\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function factory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @return _token0 The mainnet address of the Token0 of the oracle\\n function token0() external view returns (address _token0);\\n\\n /// @return _token1 The mainnet address of the Token1 of the oracle\\n function token1() external view returns (address _token1);\\n\\n /// @return _fee The fee identifier of the pool\\n function fee() external view returns (uint24 _fee);\\n\\n /// @return _poolSalt The identifier of both the pool and the oracle\\n function poolSalt() external view returns (bytes32 _poolSalt);\\n\\n /// @return _poolNonce Last recorded nonce of the pool history\\n function poolNonce() external view returns (uint24 _poolNonce);\\n\\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\\n /// @return _tick Used to maintain compatibility with Uniswap V3\\n /// @return _observationIndex The index of the last oracle observation that was written,\\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\\n /// @return _unlocked Used to track if a pool information was already verified\\n function slot0()\\n external\\n view\\n returns (\\n uint160 _sqrtPriceX96,\\n int24 _tick,\\n uint16 _observationIndex,\\n uint16 _observationCardinality,\\n uint16 _observationCardinalityNext,\\n uint8 _feeProtocol,\\n bool _unlocked\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param _index The element of the observations array to fetch\\n /// @return _blockTimestamp The timestamp of the observation,\\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// @return _initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 _index)\\n external\\n view\\n returns (\\n uint32 _blockTimestamp,\\n int56 _tickCumulative,\\n uint160 _secondsPerLiquidityCumulativeX128,\\n bool _initialized\\n );\\n\\n // EVENTS\\n\\n /// @notice Emitted when the pool information is verified\\n /// @param _poolSalt Identifier of the pool and the oracle\\n /// @param _token0 The contract address of either token0 or token1\\n /// @param _token1 The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\\n\\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param _tick The log base 1.0001 of price of the pool after the swap\\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\\n\\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\\n\\n // ERRORS\\n\\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\\n error AI();\\n\\n /// @notice Thrown if the pool info does not correspond to the pool salt\\n error InvalidPool();\\n\\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\\n error OnlyDataReceiver();\\n\\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\\n error OnlyFactory();\\n\\n // FUNCTIONS\\n\\n /// @notice Permisionless method to verify token0, token1 and fee\\n /// @dev Before verified, token0 and token1 views will return address(0)\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external;\\n\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\\n\\n /// @notice Permisioned method to push a dataset to update\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolNonce Nonce of the observation broadcast\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\\n\\n /// @notice Permisioned method to increase the cardinalityNext value\\n /// @param _observationCardinalityNext The new next length of the observations array\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa90206e3de00ad866b7f4792ce29220ee0ca561d59629ba638a31c4d6fd3941b\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IBridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport {IDataReceiver} from '../IDataReceiver.sol';\\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\\n\\ninterface IBridgeReceiverAdapter is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @notice Gets the address of the DataReceiver contract\\n /// @return _dataReceiver Address of the DataReceiver contract\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /* NOTE: callback methods should be here declared */\\n}\\n\",\"keccak256\":\"0x49e5c9c6a28521933a3f2b01a529fbae9aac1edd71dbe904586a2f06148b1974\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040526005805461ffff1916609017905534801561001e57600080fd5b5060405161277e38038061277e83398101604081905261003d91610128565b816001600160a01b0381166100655760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b039290921691909117905561008e81610095565b5050610162565b6001600160a01b0381166100bc5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be9060200160405180910390a150565b6001600160a01b038116811461012557600080fd5b50565b6000806040838503121561013b57600080fd5b825161014681610110565b602084015190925061015781610110565b809150509250929050565b61260d806101716000396000f3fe60806040523480156200001157600080fd5b5060043610620001095760003560e01c806391a0b97911620000a3578063e8047788116200006e578063e80477881462000247578063ebaa56aa146200025b578063f235757f146200027e578063f6c00927146200029557600080fd5b806391a0b97914620001cd57806397862d6d14620001d757806399df712014620001ee578063e3056a34146200023357600080fd5b80631698ee8211620000e45780631698ee8214620001625780633c1a17ff14620001795780635cc1fd36146200019f57806384b6db1414620001b657600080fd5b806307d5851a146200010e5780630c340a24146200012757806313f6986d1462000158575b600080fd5b620001256200011f36600462000892565b620002ac565b005b6000546200013b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b62000125620002e6565b6200013b62000173366004620008cd565b6200031e565b620001906200018a366004620008cd565b62000344565b6040519081526020016200014f565b6200013b620001b03660046200091b565b620003bf565b62000125620001c73660046200095d565b620004c8565b6200019062000568565b62000125620001e836600462000983565b62000597565b6003546004546200020f919062ffffff8116906301000000900461ffff1683565b6040805193845262ffffff909216602084015261ffff16908201526060016200014f565b6001546200013b906001600160a01b031681565b6002546200013b906001600160a01b031681565b6005546200026a9061ffff1681565b60405161ffff90911681526020016200014f565b620001256200028f36600462000892565b62000634565b6200013b620002a6366004620009a1565b6200066b565b6000546001600160a01b03163314620002d85760405163070545c960e51b815260040160405180910390fd5b620002e38162000714565b50565b6001546001600160a01b031633146200031257604051639ba0305d60e01b815260040160405180910390fd5b6200031c6200078b565b565b6000806200032e85858562000344565b90506200033b816200066b565b95945050505050565b6000806000846001600160a01b0316866001600160a01b0316106200036b5784866200036e565b85855b604080516001600160a01b03808516602083015283169181019190915262ffffff87166060820152919350915060800160405160208183030381529060405280519060200120925050509392505050565b6002546000906001600160a01b03163314620003ee57604051638e5b30cb60e01b815260040160405180910390fd5b6040805160608101825284815262ffffff84166020820181905260055461ffff1691830182905260038690556004805464ffffffffff1916909117630100000090920291909117905551839062000445906200086e565b8190604051809103906000f590508015801562000466573d6000803e3d6000fd5b5060006003556004805464ffffffffff1916905560405162ffffff841681529091506001600160a01b0382169084907f5b7d803564bd9c17d971ee338d1e9ffafd2aa0a8dbd7065f9d3900ecf7a842149060200160405180910390a392915050565b6000546001600160a01b03163314620004f45760405163070545c960e51b815260040160405180910390fd5b600062000501836200066b565b6040516332148f6760e01b815261ffff841660048201529091506001600160a01b038216906332148f6790602401600060405180830381600087803b1580156200054a57600080fd5b505af11580156200055f573d6000803e3d6000fd5b50505050505050565b60405162000579602082016200086e565b6020820181038252601f19601f820116604052508051906020012081565b6000546001600160a01b03163314620005c35760405163070545c960e51b815260040160405180910390fd5b8061ffff16600003620005e957604051631f2a200560e01b815260040160405180910390fd5b6005805461ffff191661ffff83169081179091556040519081527fec9fa937c26cb048aac5fc5992eaace52f38cd13c8da22f42630090bd258261f906020015b60405180910390a150565b6000546001600160a01b03163314620006605760405163070545c960e51b815260040160405180910390fd5b620002e381620007e9565b6000620006f230836040518060200162000685906200086e565b601f1982820381018352601f90910116604081815282516020938401206001600160f81b03198385015260609590951b6bffffffffffffffffffffffff19166021830152603582019390935260558082019490945282518082039094018452607501909152815191012090565b9050806001600160a01b03163b6000036200070f57506000919050565b919050565b6001600160a01b0381166200073c5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be9060200162000629565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6001600160a01b038116620008115760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910162000629565b611c1c80620009bc83390190565b6001600160a01b0381168114620002e357600080fd5b600060208284031215620008a557600080fd5b8135620008b2816200087c565b9392505050565b803562ffffff811681146200070f57600080fd5b600080600060608486031215620008e357600080fd5b8335620008f0816200087c565b9250602084013562000902816200087c565b91506200091260408501620008b9565b90509250925092565b600080604083850312156200092f57600080fd5b823591506200094160208401620008b9565b90509250929050565b803561ffff811681146200070f57600080fd5b600080604083850312156200097157600080fd5b8235915062000941602084016200094a565b6000602082840312156200099657600080fd5b620008b2826200094a565b600060208284031215620009b457600080fd5b503591905056fe60c06040523480156200001157600080fd5b50336080819052604080516304cefb8960e51b81529051600092916399df71209160048083019260609291908290030181865afa15801562000057573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200007d9190620001bb565b62010000805462ffffff191662ffffff939093169290921790915560a0919091526040805160e081018252600080825260208201529192508101620000c460018462000210565b61ffff90811682529283166020808301829052604080840192909252600060608085018290526001608095860152855182549387015194870151918701519587015160a088015160c0909801511515600160f01b0260ff60f01b1960ff99909916600160e81b0260ff60e81b19928b16600160d81b029290921662ffffff60d81b19988b16600160c81b0261ffff60c81b1995909b16600160b81b029490941663ffffffff60b81b1962ffffff909816600160a01b026001600160b81b03199097166001600160a01b0390941693909317959095179590951617969096179390931694909417179190911691909117905562000242565b600080600060608486031215620001d157600080fd5b83519250602084015162ffffff81168114620001ec57600080fd5b604085015190925061ffff811681146200020557600080fd5b809150509250925092565b600061ffff838116908316818110156200023a57634e487b7160e01b600052601160045260246000fd5b039392505050565b60805160a051611998620002846000396000818161027a0152818161068c01526107430152600081816102af01528181610302015261052301526119986000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063883bdbfd11610071578063883bdbfd1461022f5780639fdbd4d714610250578063c1c9115a14610275578063c45a0155146102aa578063d21220a7146102d1578063ddca3f43146102e657600080fd5b80630dfe1681146100b957806323e512d4146100f2578063252c09d71461011557806332148f67146101625780633453952f146101775780633850c7bd1461018a575b600080fd5b62010000546100d590630100000090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610105610100366004611650565b6102fe565b60405190151581526020016100e9565b610128610123366004611751565b6104d3565b6040805163ffffffff909516855260069390930b60208501526001600160a01b0390911691830191909152151560608201526080016100e9565b61017561017036600461176a565b610518565b005b6101756101853660046117a6565b6105f4565b6000546101de906001600160a01b03811690600160a01b810460020b9061ffff600160b81b8204811691600160c81b8104821691600160d81b8204169060ff600160e81b8204811691600160f01b90041687565b604080516001600160a01b03909816885260029690960b602088015261ffff94851695870195909552918316606086015291909116608084015260ff1660a0830152151560c082015260e0016100e9565b61024261023d3660046117ed565b610797565b6040516100e9929190611862565b62010000546102619062ffffff1681565b60405162ffffff90911681526020016100e9565b61029c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100e9565b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b62010001546100d5906001600160a01b031681565b620100015461026190600160a01b900462ffffff1681565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e80477886040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038291906118e9565b6001600160a01b0316336001600160a01b0316146103b357604051638e5b30cb60e01b815260040160405180910390fd5b62010000805462ffffff169060006103ca83611906565b91906101000a81548162ffffff021916908362ffffff16021790555062ffffff168262ffffff16146103fe575060006104cd565b825160005b818110156104355761042d85828151811061042057610420611936565b6020026020010151610808565b600101610403565b5060005461044c90600160a01b900460020b6108a8565b600080546001600160a01b0319166001600160a01b039290921691821780825560408051838152602081018490529081019390935260608301829052600160a01b900460020b60808301529081907fc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca679060a00160405180910390a360019150505b92915050565b60018161ffff81106104e457600080fd5b015463ffffffff81169150600160201b810460060b90600160581b81046001600160a01b031690600160f81b900460ff1684565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461056157604051630636a15760e11b815260040160405180910390fd5b60005461ffff600160d81b909104811690821681106105935760405163139816ff60e31b815260040160405180910390fd5b6000805461ffff60d81b1916600160d81b61ffff8581169182029290921790925560408051918416825260208201929092527fac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a910160405180910390a15050565b600054600160f01b900460ff1661061e5760405163139816ff60e31b815260040160405180910390fd5b600080836001600160a01b0316856001600160a01b031610610641578385610644565b84845b604080516001600160a01b03808516602083015283169181019190915262ffffff861660608201529193509150608001604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000146106c85760405162820f3560e61b815260040160405180910390fd5b6201000080546301000000600160b81b03191663010000006001600160a01b03858116918202929092179092556201000180549184166001600160b81b03199092168217600160a01b62ffffff8816908102919091179091556000805460ff60f01b19169055604080519384526020840192909252908201527f0000000000000000000000000000000000000000000000000000000000000000907fb50ab96cf9f83d6c076a0d2a6e27a65bf1242920ba414829aa618d57d4a263739060600160405180910390a25050505050565b6060806107fd4285858080602002602001604051908101604052809392919081815260200183836020028082843760009201829052508054600196959450600160a01b810460020b935061ffff600160b81b820481169350600160c81b90910416610bca565b915091509250929050565b600080548251829161084a9160019161ffff600160b81b820481169291600160a01b810460020b918791600160c81b8104821691600160d81b90910416610d15565b600080546020969096015163ffffffff60b81b19909616600160c81b61ffff9384160261ffff60b81b191617600160b81b93909216929092021762ffffff60a01b1916600160a01b62ffffff90951694909402939093179092555050565b60008060008360020b126108bf578260020b6108c7565b8260020b6000035b9050620d89e88111156108ed576040516315e4079d60e11b815260040160405180910390fd5b60008160011660000361090457600160801b610916565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff169050600282161561094a576ffff97272373d413259a46990580e213a0260801c5b6004821615610969576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610988576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b60108216156109a7576fffcb9843d60f6159c9db58835c9266440260801c5b60208216156109c6576fff973b41fa98c081472e6896dfb254c00260801c5b60408216156109e5576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610a04576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610a24576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610a44576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610a64576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610a84576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610aa4576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610ac4576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610ae4576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610b04576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610b25576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610b45576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610b64576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610b81576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610ba2578060001981610b9e57610b9e61194c565b0490505b600160201b810615610bb5576001610bb8565b60005b60ff16602082901c0192505050919050565b60608060008361ffff1611610bf257604051636b93000360e11b815260040160405180910390fd5b865167ffffffffffffffff811115610c0c57610c0c6115c8565b604051908082528060200260200182016040528015610c35578160200160208202803683370190505b509150865167ffffffffffffffff811115610c5257610c526115c8565b604051908082528060200260200182016040528015610c7b578160200160208202803683370190505b50905060005b8751811015610d0857610cb28a8a8a8481518110610ca157610ca1611936565b60200260200101518a8a8a8a610e9d565b848381518110610cc457610cc4611936565b60200260200101848481518110610cdd57610cdd611936565b6001600160a01b039093166020938402919091019092019190915260069190910b9052600101610c81565b5097509795505050505050565b6000806000898961ffff1661ffff8110610d3157610d31611936565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff161515606083015290925089169003610d9a5788859250925050610e91565b8461ffff168461ffff16118015610dbb57506001850361ffff168961ffff16145b15610dc857839150610dcc565b8491505b8161ffff168960010161ffff1681610de657610de661194c565b069250610df58189898961104c565b8a8461ffff1661ffff8110610e0c57610e0c611936565b825191018054602084015160408501516060909501511515600160f81b026001600160f81b036001600160a01b03909616600160581b02959095166affffffffffffffffffffff66ffffffffffffff909216600160201b026affffffffffffffffffffff1990931663ffffffff90951694909417919091171691909117919091179055505b97509795505050505050565b6000808663ffffffff16600003610f46576000898661ffff1661ffff8110610ec757610ec7611936565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff16151560608301529092508a1614610f3257610f2f818a898861104c565b90505b806020015181604001519250925050610e91565b868803600080610f5b8c8c858c8c8c8c611111565b91509150816000015163ffffffff168363ffffffff1603610f8c578160200151826040015194509450505050610e91565b806000015163ffffffff168363ffffffff1603610fb9578060200151816040015194509450505050610e91565b60008260000151826000015103905060008360000151850390508063ffffffff168263ffffffff1660060b856020015185602001510360060b81610fff57610fff61194c565b05028460200151018263ffffffff168263ffffffff1686604001518660400151036001600160a01b031602816110375761103761194c565b04856040015101965096505050505050610e91565b604080516080810182526000808252602082018190529181018290526060810191909152600085600001518503905060405180608001604052808663ffffffff1681526020018263ffffffff168660020b0288602001510160060b81526020016000856001600160801b0316116110c45760016110c6565b845b6001600160801b031663ffffffff60801b608085901b16816110ea576110ea61194c565b048860400151016001600160a01b0316815260200160011515815250915050949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152888561ffff1661ffff811061117057611170611936565b60408051608081018252919092015463ffffffff8116808352600160201b820460060b6020840152600160581b82046001600160a01b031693830193909352600160f81b900460ff161515606082015292506111ce9089908961131d565b156111fa57815163ffffffff888116911614610e9157816111f18389898861104c565b91509150610e91565b888361ffff168660010161ffff16816112155761121561194c565b0661ffff1661ffff811061122b5761122b611936565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529092506112d457604080516080810182528a5463ffffffff81168252600160201b810460060b6020830152600160581b81046001600160a01b031692820192909252600160f81b90910460ff161515606082015291505b6112e38883600001518961131d565b611300576040516327e8e87560e01b815260040160405180910390fd5b61130d89898988876113e0565b9150915097509795505050505050565b60008363ffffffff168363ffffffff161115801561134757508363ffffffff168263ffffffff1611155b15611363578163ffffffff168363ffffffff16111590506113d9565b60008463ffffffff168463ffffffff161161138a578363ffffffff16600160201b01611392565b8363ffffffff165b64ffffffffff16905060008563ffffffff168463ffffffff16116113c2578363ffffffff16600160201b016113ca565b8363ffffffff165b64ffffffffff16909111159150505b9392505050565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260008361ffff168560010161ffff16816114445761144461194c565b0661ffff169050600060018561ffff16830103905060005b506002818301048961ffff871682816114775761147761194c565b0661ffff811061148957611489611936565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529095506114ed5780600101925061145c565b898661ffff1682600101816115045761150461194c565b0661ffff811061151657611516611936565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b9091041615156060820152855190945060009061157a908b908b61131d565b905080801561159357506115938a8a876000015161131d565b1561159e57506115bb565b806115ae576001820392506115b5565b8160010193505b5061145c565b5050509550959350505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611601576116016115c8565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611630576116306115c8565b604052919050565b803562ffffff8116811461164b57600080fd5b919050565b600080604080848603121561166457600080fd5b833567ffffffffffffffff8082111561167c57600080fd5b818601915086601f83011261169057600080fd5b81356020828211156116a4576116a46115c8565b6116b2818360051b01611607565b828152818101935060069290921b8401810191898311156116d257600080fd5b938101935b828510156117365785858b0312156116ef5760008081fd5b6116f76115de565b853563ffffffff8116811461170c5760008081fd5b815285830135600281900b81146117235760008081fd5b81840152845293850193928101926116d7565b9650611743888201611638565b955050505050509250929050565b60006020828403121561176357600080fd5b5035919050565b60006020828403121561177c57600080fd5b813561ffff811681146113d957600080fd5b6001600160a01b03811681146117a357600080fd5b50565b6000806000606084860312156117bb57600080fd5b83356117c68161178e565b925060208401356117d68161178e565b91506117e460408501611638565b90509250925092565b6000806020838503121561180057600080fd5b823567ffffffffffffffff8082111561181857600080fd5b818501915085601f83011261182c57600080fd5b81358181111561183b57600080fd5b8660208260051b850101111561185057600080fd5b60209290920196919550909350505050565b604080825283519082018190526000906020906060840190828701845b8281101561189e57815160060b8452928401929084019060010161187f565b5050508381038285015284518082528583019183019060005b818110156118dc5783516001600160a01b0316835292840192918401916001016118b7565b5090979650505050505050565b6000602082840312156118fb57600080fd5b81516113d98161178e565b600062ffffff80831681810361192c57634e487b7160e01b600052601160045260246000fd5b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fdfea26469706673582212202916bd7abff2b56854d422c30b2ee58e7cd52acbe62cc95b756c121881b18caa64736f6c634300080f0033a2646970667358221220af0108e4566d66783279fe1c85273c8dff7d41ac2828db7dc49c3f31c259381364736f6c634300080f0033", - "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620001095760003560e01c806391a0b97911620000a3578063e8047788116200006e578063e80477881462000247578063ebaa56aa146200025b578063f235757f146200027e578063f6c00927146200029557600080fd5b806391a0b97914620001cd57806397862d6d14620001d757806399df712014620001ee578063e3056a34146200023357600080fd5b80631698ee8211620000e45780631698ee8214620001625780633c1a17ff14620001795780635cc1fd36146200019f57806384b6db1414620001b657600080fd5b806307d5851a146200010e5780630c340a24146200012757806313f6986d1462000158575b600080fd5b620001256200011f36600462000892565b620002ac565b005b6000546200013b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b62000125620002e6565b6200013b62000173366004620008cd565b6200031e565b620001906200018a366004620008cd565b62000344565b6040519081526020016200014f565b6200013b620001b03660046200091b565b620003bf565b62000125620001c73660046200095d565b620004c8565b6200019062000568565b62000125620001e836600462000983565b62000597565b6003546004546200020f919062ffffff8116906301000000900461ffff1683565b6040805193845262ffffff909216602084015261ffff16908201526060016200014f565b6001546200013b906001600160a01b031681565b6002546200013b906001600160a01b031681565b6005546200026a9061ffff1681565b60405161ffff90911681526020016200014f565b620001256200028f36600462000892565b62000634565b6200013b620002a6366004620009a1565b6200066b565b6000546001600160a01b03163314620002d85760405163070545c960e51b815260040160405180910390fd5b620002e38162000714565b50565b6001546001600160a01b031633146200031257604051639ba0305d60e01b815260040160405180910390fd5b6200031c6200078b565b565b6000806200032e85858562000344565b90506200033b816200066b565b95945050505050565b6000806000846001600160a01b0316866001600160a01b0316106200036b5784866200036e565b85855b604080516001600160a01b03808516602083015283169181019190915262ffffff87166060820152919350915060800160405160208183030381529060405280519060200120925050509392505050565b6002546000906001600160a01b03163314620003ee57604051638e5b30cb60e01b815260040160405180910390fd5b6040805160608101825284815262ffffff84166020820181905260055461ffff1691830182905260038690556004805464ffffffffff1916909117630100000090920291909117905551839062000445906200086e565b8190604051809103906000f590508015801562000466573d6000803e3d6000fd5b5060006003556004805464ffffffffff1916905560405162ffffff841681529091506001600160a01b0382169084907f5b7d803564bd9c17d971ee338d1e9ffafd2aa0a8dbd7065f9d3900ecf7a842149060200160405180910390a392915050565b6000546001600160a01b03163314620004f45760405163070545c960e51b815260040160405180910390fd5b600062000501836200066b565b6040516332148f6760e01b815261ffff841660048201529091506001600160a01b038216906332148f6790602401600060405180830381600087803b1580156200054a57600080fd5b505af11580156200055f573d6000803e3d6000fd5b50505050505050565b60405162000579602082016200086e565b6020820181038252601f19601f820116604052508051906020012081565b6000546001600160a01b03163314620005c35760405163070545c960e51b815260040160405180910390fd5b8061ffff16600003620005e957604051631f2a200560e01b815260040160405180910390fd5b6005805461ffff191661ffff83169081179091556040519081527fec9fa937c26cb048aac5fc5992eaace52f38cd13c8da22f42630090bd258261f906020015b60405180910390a150565b6000546001600160a01b03163314620006605760405163070545c960e51b815260040160405180910390fd5b620002e381620007e9565b6000620006f230836040518060200162000685906200086e565b601f1982820381018352601f90910116604081815282516020938401206001600160f81b03198385015260609590951b6bffffffffffffffffffffffff19166021830152603582019390935260558082019490945282518082039094018452607501909152815191012090565b9050806001600160a01b03163b6000036200070f57506000919050565b919050565b6001600160a01b0381166200073c5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be9060200162000629565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6001600160a01b038116620008115760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910162000629565b611c1c80620009bc83390190565b6001600160a01b0381168114620002e357600080fd5b600060208284031215620008a557600080fd5b8135620008b2816200087c565b9392505050565b803562ffffff811681146200070f57600080fd5b600080600060608486031215620008e357600080fd5b8335620008f0816200087c565b9250602084013562000902816200087c565b91506200091260408501620008b9565b90509250925092565b600080604083850312156200092f57600080fd5b823591506200094160208401620008b9565b90509250929050565b803561ffff811681146200070f57600080fd5b600080604083850312156200097157600080fd5b8235915062000941602084016200094a565b6000602082840312156200099657600080fd5b620008b2826200094a565b600060208284031215620009b457600080fd5b503591905056fe60c06040523480156200001157600080fd5b50336080819052604080516304cefb8960e51b81529051600092916399df71209160048083019260609291908290030181865afa15801562000057573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200007d9190620001bb565b62010000805462ffffff191662ffffff939093169290921790915560a0919091526040805160e081018252600080825260208201529192508101620000c460018462000210565b61ffff90811682529283166020808301829052604080840192909252600060608085018290526001608095860152855182549387015194870151918701519587015160a088015160c0909801511515600160f01b0260ff60f01b1960ff99909916600160e81b0260ff60e81b19928b16600160d81b029290921662ffffff60d81b19988b16600160c81b0261ffff60c81b1995909b16600160b81b029490941663ffffffff60b81b1962ffffff909816600160a01b026001600160b81b03199097166001600160a01b0390941693909317959095179590951617969096179390931694909417179190911691909117905562000242565b600080600060608486031215620001d157600080fd5b83519250602084015162ffffff81168114620001ec57600080fd5b604085015190925061ffff811681146200020557600080fd5b809150509250925092565b600061ffff838116908316818110156200023a57634e487b7160e01b600052601160045260246000fd5b039392505050565b60805160a051611998620002846000396000818161027a0152818161068c01526107430152600081816102af01528181610302015261052301526119986000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063883bdbfd11610071578063883bdbfd1461022f5780639fdbd4d714610250578063c1c9115a14610275578063c45a0155146102aa578063d21220a7146102d1578063ddca3f43146102e657600080fd5b80630dfe1681146100b957806323e512d4146100f2578063252c09d71461011557806332148f67146101625780633453952f146101775780633850c7bd1461018a575b600080fd5b62010000546100d590630100000090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610105610100366004611650565b6102fe565b60405190151581526020016100e9565b610128610123366004611751565b6104d3565b6040805163ffffffff909516855260069390930b60208501526001600160a01b0390911691830191909152151560608201526080016100e9565b61017561017036600461176a565b610518565b005b6101756101853660046117a6565b6105f4565b6000546101de906001600160a01b03811690600160a01b810460020b9061ffff600160b81b8204811691600160c81b8104821691600160d81b8204169060ff600160e81b8204811691600160f01b90041687565b604080516001600160a01b03909816885260029690960b602088015261ffff94851695870195909552918316606086015291909116608084015260ff1660a0830152151560c082015260e0016100e9565b61024261023d3660046117ed565b610797565b6040516100e9929190611862565b62010000546102619062ffffff1681565b60405162ffffff90911681526020016100e9565b61029c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100e9565b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b62010001546100d5906001600160a01b031681565b620100015461026190600160a01b900462ffffff1681565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e80477886040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038291906118e9565b6001600160a01b0316336001600160a01b0316146103b357604051638e5b30cb60e01b815260040160405180910390fd5b62010000805462ffffff169060006103ca83611906565b91906101000a81548162ffffff021916908362ffffff16021790555062ffffff168262ffffff16146103fe575060006104cd565b825160005b818110156104355761042d85828151811061042057610420611936565b6020026020010151610808565b600101610403565b5060005461044c90600160a01b900460020b6108a8565b600080546001600160a01b0319166001600160a01b039290921691821780825560408051838152602081018490529081019390935260608301829052600160a01b900460020b60808301529081907fc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca679060a00160405180910390a360019150505b92915050565b60018161ffff81106104e457600080fd5b015463ffffffff81169150600160201b810460060b90600160581b81046001600160a01b031690600160f81b900460ff1684565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461056157604051630636a15760e11b815260040160405180910390fd5b60005461ffff600160d81b909104811690821681106105935760405163139816ff60e31b815260040160405180910390fd5b6000805461ffff60d81b1916600160d81b61ffff8581169182029290921790925560408051918416825260208201929092527fac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a910160405180910390a15050565b600054600160f01b900460ff1661061e5760405163139816ff60e31b815260040160405180910390fd5b600080836001600160a01b0316856001600160a01b031610610641578385610644565b84845b604080516001600160a01b03808516602083015283169181019190915262ffffff861660608201529193509150608001604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000146106c85760405162820f3560e61b815260040160405180910390fd5b6201000080546301000000600160b81b03191663010000006001600160a01b03858116918202929092179092556201000180549184166001600160b81b03199092168217600160a01b62ffffff8816908102919091179091556000805460ff60f01b19169055604080519384526020840192909252908201527f0000000000000000000000000000000000000000000000000000000000000000907fb50ab96cf9f83d6c076a0d2a6e27a65bf1242920ba414829aa618d57d4a263739060600160405180910390a25050505050565b6060806107fd4285858080602002602001604051908101604052809392919081815260200183836020028082843760009201829052508054600196959450600160a01b810460020b935061ffff600160b81b820481169350600160c81b90910416610bca565b915091509250929050565b600080548251829161084a9160019161ffff600160b81b820481169291600160a01b810460020b918791600160c81b8104821691600160d81b90910416610d15565b600080546020969096015163ffffffff60b81b19909616600160c81b61ffff9384160261ffff60b81b191617600160b81b93909216929092021762ffffff60a01b1916600160a01b62ffffff90951694909402939093179092555050565b60008060008360020b126108bf578260020b6108c7565b8260020b6000035b9050620d89e88111156108ed576040516315e4079d60e11b815260040160405180910390fd5b60008160011660000361090457600160801b610916565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff169050600282161561094a576ffff97272373d413259a46990580e213a0260801c5b6004821615610969576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610988576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b60108216156109a7576fffcb9843d60f6159c9db58835c9266440260801c5b60208216156109c6576fff973b41fa98c081472e6896dfb254c00260801c5b60408216156109e5576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610a04576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610a24576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610a44576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610a64576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610a84576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610aa4576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610ac4576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610ae4576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610b04576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610b25576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610b45576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610b64576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610b81576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610ba2578060001981610b9e57610b9e61194c565b0490505b600160201b810615610bb5576001610bb8565b60005b60ff16602082901c0192505050919050565b60608060008361ffff1611610bf257604051636b93000360e11b815260040160405180910390fd5b865167ffffffffffffffff811115610c0c57610c0c6115c8565b604051908082528060200260200182016040528015610c35578160200160208202803683370190505b509150865167ffffffffffffffff811115610c5257610c526115c8565b604051908082528060200260200182016040528015610c7b578160200160208202803683370190505b50905060005b8751811015610d0857610cb28a8a8a8481518110610ca157610ca1611936565b60200260200101518a8a8a8a610e9d565b848381518110610cc457610cc4611936565b60200260200101848481518110610cdd57610cdd611936565b6001600160a01b039093166020938402919091019092019190915260069190910b9052600101610c81565b5097509795505050505050565b6000806000898961ffff1661ffff8110610d3157610d31611936565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff161515606083015290925089169003610d9a5788859250925050610e91565b8461ffff168461ffff16118015610dbb57506001850361ffff168961ffff16145b15610dc857839150610dcc565b8491505b8161ffff168960010161ffff1681610de657610de661194c565b069250610df58189898961104c565b8a8461ffff1661ffff8110610e0c57610e0c611936565b825191018054602084015160408501516060909501511515600160f81b026001600160f81b036001600160a01b03909616600160581b02959095166affffffffffffffffffffff66ffffffffffffff909216600160201b026affffffffffffffffffffff1990931663ffffffff90951694909417919091171691909117919091179055505b97509795505050505050565b6000808663ffffffff16600003610f46576000898661ffff1661ffff8110610ec757610ec7611936565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff16151560608301529092508a1614610f3257610f2f818a898861104c565b90505b806020015181604001519250925050610e91565b868803600080610f5b8c8c858c8c8c8c611111565b91509150816000015163ffffffff168363ffffffff1603610f8c578160200151826040015194509450505050610e91565b806000015163ffffffff168363ffffffff1603610fb9578060200151816040015194509450505050610e91565b60008260000151826000015103905060008360000151850390508063ffffffff168263ffffffff1660060b856020015185602001510360060b81610fff57610fff61194c565b05028460200151018263ffffffff168263ffffffff1686604001518660400151036001600160a01b031602816110375761103761194c565b04856040015101965096505050505050610e91565b604080516080810182526000808252602082018190529181018290526060810191909152600085600001518503905060405180608001604052808663ffffffff1681526020018263ffffffff168660020b0288602001510160060b81526020016000856001600160801b0316116110c45760016110c6565b845b6001600160801b031663ffffffff60801b608085901b16816110ea576110ea61194c565b048860400151016001600160a01b0316815260200160011515815250915050949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152888561ffff1661ffff811061117057611170611936565b60408051608081018252919092015463ffffffff8116808352600160201b820460060b6020840152600160581b82046001600160a01b031693830193909352600160f81b900460ff161515606082015292506111ce9089908961131d565b156111fa57815163ffffffff888116911614610e9157816111f18389898861104c565b91509150610e91565b888361ffff168660010161ffff16816112155761121561194c565b0661ffff1661ffff811061122b5761122b611936565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529092506112d457604080516080810182528a5463ffffffff81168252600160201b810460060b6020830152600160581b81046001600160a01b031692820192909252600160f81b90910460ff161515606082015291505b6112e38883600001518961131d565b611300576040516327e8e87560e01b815260040160405180910390fd5b61130d89898988876113e0565b9150915097509795505050505050565b60008363ffffffff168363ffffffff161115801561134757508363ffffffff168263ffffffff1611155b15611363578163ffffffff168363ffffffff16111590506113d9565b60008463ffffffff168463ffffffff161161138a578363ffffffff16600160201b01611392565b8363ffffffff165b64ffffffffff16905060008563ffffffff168463ffffffff16116113c2578363ffffffff16600160201b016113ca565b8363ffffffff165b64ffffffffff16909111159150505b9392505050565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260008361ffff168560010161ffff16816114445761144461194c565b0661ffff169050600060018561ffff16830103905060005b506002818301048961ffff871682816114775761147761194c565b0661ffff811061148957611489611936565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529095506114ed5780600101925061145c565b898661ffff1682600101816115045761150461194c565b0661ffff811061151657611516611936565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b9091041615156060820152855190945060009061157a908b908b61131d565b905080801561159357506115938a8a876000015161131d565b1561159e57506115bb565b806115ae576001820392506115b5565b8160010193505b5061145c565b5050509550959350505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611601576116016115c8565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611630576116306115c8565b604052919050565b803562ffffff8116811461164b57600080fd5b919050565b600080604080848603121561166457600080fd5b833567ffffffffffffffff8082111561167c57600080fd5b818601915086601f83011261169057600080fd5b81356020828211156116a4576116a46115c8565b6116b2818360051b01611607565b828152818101935060069290921b8401810191898311156116d257600080fd5b938101935b828510156117365785858b0312156116ef5760008081fd5b6116f76115de565b853563ffffffff8116811461170c5760008081fd5b815285830135600281900b81146117235760008081fd5b81840152845293850193928101926116d7565b9650611743888201611638565b955050505050509250929050565b60006020828403121561176357600080fd5b5035919050565b60006020828403121561177c57600080fd5b813561ffff811681146113d957600080fd5b6001600160a01b03811681146117a357600080fd5b50565b6000806000606084860312156117bb57600080fd5b83356117c68161178e565b925060208401356117d68161178e565b91506117e460408501611638565b90509250925092565b6000806020838503121561180057600080fd5b823567ffffffffffffffff8082111561181857600080fd5b818501915085601f83011261182c57600080fd5b81358181111561183b57600080fd5b8660208260051b850101111561185057600080fd5b60209290920196919550909350505050565b604080825283519082018190526000906020906060840190828701845b8281101561189e57815160060b8452928401929084019060010161187f565b5050508381038285015284518082528583019183019060005b818110156118dc5783516001600160a01b0316835292840192918401916001016118b7565b5090979650505050505050565b6000602082840312156118fb57600080fd5b81516113d98161178e565b600062ffffff80831681810361192c57634e487b7160e01b600052601160045260246000fd5b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fdfea26469706673582212202916bd7abff2b56854d422c30b2ee58e7cd52acbe62cc95b756c121881b18caa64736f6c634300080f0033a2646970667358221220af0108e4566d66783279fe1c85273c8dff7d41ac2828db7dc49c3f31c259381364736f6c634300080f0033", + "numDeployments": 4, + "solcInputHash": "1ffcc3895a1a8980b9e58deee89219d1", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDataReceiver\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"}],\"name\":\"DataReceiverSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"_initialCardinality\",\"type\":\"uint16\"}],\"name\":\"InitialCardinalitySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"_initialNonce\",\"type\":\"uint24\"}],\"name\":\"OracleDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ORACLE_INIT_CODE_HASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dataReceiver\",\"outputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"_initialNonce\",\"type\":\"uint24\"}],\"name\":\"deployOracle\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenA\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenB\",\"type\":\"address\"},{\"internalType\":\"uint24\",\"name\":\"_fee\",\"type\":\"uint24\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenA\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenB\",\"type\":\"address\"},{\"internalType\":\"uint24\",\"name\":\"_fee\",\"type\":\"uint24\"}],\"name\":\"getPoolSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint16\",\"name\":\"_observationCardinalityNext\",\"type\":\"uint16\"}],\"name\":\"increaseOracleCardinality\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialCardinality\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleParameters\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"poolNonce\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"cardinality\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"}],\"name\":\"setDataReceiver\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"_initialCardinality\",\"type\":\"uint16\"}],\"name\":\"setInitialCardinality\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"setPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"deployOracle(bytes32,uint24)\":{\"details\":\"Requires that the salt has not been deployed before\",\"params\":{\"_poolSalt\":\"Pool salt that deterministically binds an oracle with a pool\"},\"returns\":{\"_oracle\":\"The address of the newly deployed oracle\"}},\"getPool(address,address,uint24)\":{\"params\":{\"_fee\":\"The fee denominated in hundredths of a bip\",\"_tokenA\":\"The contract address of either token0 or token1\",\"_tokenB\":\"The contract address of the other token\"},\"returns\":{\"_oracle\":\"The oracle address\"}},\"getPool(bytes32)\":{\"params\":{\"_poolSalt\":\"Identifier of both the pool and the oracle\"},\"returns\":{\"_oracle\":\"The address (if deployed) of the correspondant oracle\"}},\"getPoolSalt(address,address,uint24)\":{\"params\":{\"_fee\":\"The fee denominated in hundredths of a bip\",\"_tokenA\":\"The contract address of either token0 or token1\",\"_tokenB\":\"The contract address of the other token\"},\"returns\":{\"_poolSalt\":\"Pool salt for inquired parameters\"}},\"setDataReceiver(address)\":{\"details\":\"Will disallow the previous dataReceiver\",\"params\":{\"_dataReceiver\":\"The address of the new allowed dataReceiver\"}},\"setInitialCardinality(uint16)\":{\"params\":{\"_initialCardinality\":\"The initial size of the observations memory storage for newly deployed pools\"}},\"setPendingGovernor(address)\":{\"params\":{\"_pendingGovernor\":\"Address of the proposed new governor\"}}},\"stateVariables\":{\"ORACLE_INIT_CODE_HASH\":{\"return\":\"The oracle creation code hash used to calculate their address\",\"returns\":{\"_0\":\"The oracle creation code hash used to calculate their address\"}},\"dataReceiver\":{\"return\":\"The address of the DataReceiver for the oracles to consult\",\"returns\":{\"_0\":\"The address of the DataReceiver for the oracles to consult\"}},\"initialCardinality\":{\"return\":\"The initial size of the observations memory storage for newly deployed pools\",\"returns\":{\"_0\":\"The initial size of the observations memory storage for newly deployed pools\"}},\"oracleParameters\":{\"returns\":{\"cardinality\":\"The size of the observations memory storage\",\"poolNonce\":\"The initial nonce of the pool data\",\"poolSalt\":\"The id of both the oracle and the pool\"}}},\"title\":\"The OracleFactory contract\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"OnlyDataReceiver()\":[{\"notice\":\"Thrown when a contract other than the DataReceiver tries to deploy an oracle\"}],\"OnlyGovernor()\":[{\"notice\":\"Thrown if a non-governor user tries to call a OnlyGovernor function\"}],\"OnlyPendingGovernor()\":[{\"notice\":\"Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"events\":{\"DataReceiverSet(address)\":{\"notice\":\"Emitted when a new DataReceiver is set\"},\"InitialCardinalitySet(uint16)\":{\"notice\":\"Emitted when a new initial oracle cardinality is set\"},\"OracleDeployed(bytes32,address,uint24)\":{\"notice\":\"Emitted when a new oracle is deployed\"},\"PendingGovernorAccepted(address)\":{\"notice\":\"Emitted when a new governor is set\"},\"PendingGovernorSet(address,address)\":{\"notice\":\"Emitted when a new pending governor is set\"}},\"kind\":\"user\",\"methods\":{\"acceptPendingGovernor()\":{\"notice\":\"Allows a proposed governor to accept the governance\"},\"deployOracle(bytes32,uint24)\":{\"notice\":\"Deploys a new oracle given an inputted salt\"},\"getPool(address,address,uint24)\":{\"notice\":\"Overrides UniV3Factory getPool mapping\"},\"getPool(bytes32)\":{\"notice\":\"Tracks the addresses of the oracle by poolSalt\"},\"setDataReceiver(address)\":{\"notice\":\"Allows governor to set a new allowed dataReceiver\"},\"setInitialCardinality(uint16)\":{\"notice\":\"Allows governor to set a new initial cardinality for new oracles\"},\"setPendingGovernor(address)\":{\"notice\":\"Allows a governor to propose a new governor\"}},\"notice\":\"Handles the deployment of new OracleSidechains\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/OracleFactory.sol\":\"OracleFactory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '../interfaces/IGovernable.sol';\\n\\n/// @title Governable contract\\n/// @notice Manages the governor role\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public governor;\\n\\n /// @inheritdoc IGovernable\\n address public pendingGovernor;\\n\\n constructor(address _governor) {\\n if (_governor == address(0)) revert ZeroAddress();\\n governor = _governor;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\\n _setPendingGovernor(_pendingGovernor);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptPendingGovernor() external onlyPendingGovernor {\\n _acceptPendingGovernor();\\n }\\n\\n function _setPendingGovernor(address _pendingGovernor) internal {\\n if (_pendingGovernor == address(0)) revert ZeroAddress();\\n pendingGovernor = _pendingGovernor;\\n emit PendingGovernorSet(governor, _pendingGovernor);\\n }\\n\\n function _acceptPendingGovernor() internal {\\n governor = pendingGovernor;\\n delete pendingGovernor;\\n emit PendingGovernorAccepted(governor);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governor\\n modifier onlyGovernor() {\\n if (msg.sender != governor) revert OnlyGovernor();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernor\\n modifier onlyPendingGovernor() {\\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x3f11408cfcb015a99dc417e075c8ebc39b796fc2adc3e81b036487e4486881b3\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity >=0.8.8 <0.9.0;\\n\\n/// @title Provides functions for deriving a UniswapV3Pool address from its factory, tokens and fee\\nlibrary Create2Address {\\n /// @notice Deterministically computes the pool address given the factory, salt and initCodeHash\\n /// @param _factory The Uniswap V3 factory contract address\\n /// @param _salt The PoolKey encoded bytes\\n /// @param _initCodeHash The Init Code Hash of the target\\n /// @return _pool The contract address of the target UniswapV3Pool\\n function computeAddress(address _factory, bytes32 _salt, bytes32 _initCodeHash)\\n internal\\n pure\\n returns (address _pool)\\n {\\n _pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', _factory, _salt, _initCodeHash)))));\\n }\\n}\\n\",\"keccak256\":\"0x867e71cdb6b5b3a4b5f3e6d9bd27262a13d6b54eb18957e8c27cfbbff886ad9d\",\"license\":\"BUSL-1.1\"},\"@uniswap/v3-core/contracts/libraries/Oracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.0;\\n\\n/// @title Oracle\\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\\n/// @dev Instances of stored oracle data, \\\"observations\\\", are collected in the oracle array\\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\\n/// Observations are overwritten when the full length of the oracle array is populated.\\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\\nlibrary Oracle {\\n error I();\\n error OLD();\\n\\n struct Observation {\\n // the block timestamp of the observation\\n uint32 blockTimestamp;\\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\\n int56 tickCumulative;\\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\\n uint160 secondsPerLiquidityCumulativeX128;\\n // whether or not the observation is initialized\\n bool initialized;\\n }\\n\\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\\n /// @param last The specified observation to be transformed\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @return Observation The newly populated observation\\n function transform(\\n Observation memory last,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity\\n ) private pure returns (Observation memory) {\\n unchecked {\\n uint32 delta = blockTimestamp - last.blockTimestamp;\\n return\\n Observation({\\n blockTimestamp: blockTimestamp,\\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\\n initialized: true\\n });\\n }\\n }\\n\\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\\n /// @param self The stored oracle array\\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\\n /// @return cardinality The number of populated elements in the oracle array\\n /// @return cardinalityNext The new length of the oracle array, independent of population\\n function initialize(Observation[65535] storage self, uint32 time)\\n internal\\n returns (uint16 cardinality, uint16 cardinalityNext)\\n {\\n self[0] = Observation({\\n blockTimestamp: time,\\n tickCumulative: 0,\\n secondsPerLiquidityCumulativeX128: 0,\\n initialized: true\\n });\\n return (1, 1);\\n }\\n\\n /// @notice Writes an oracle observation to the array\\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\\n /// @param self The stored oracle array\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @param cardinalityNext The new length of the oracle array, independent of population\\n /// @return indexUpdated The new index of the most recently written element in the oracle array\\n /// @return cardinalityUpdated The new cardinality of the oracle array\\n function write(\\n Observation[65535] storage self,\\n uint16 index,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity,\\n uint16 cardinality,\\n uint16 cardinalityNext\\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\\n unchecked {\\n Observation memory last = self[index];\\n\\n // early return if we've already written an observation this block\\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\\n\\n // if the conditions are right, we can bump the cardinality\\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\\n cardinalityUpdated = cardinalityNext;\\n } else {\\n cardinalityUpdated = cardinality;\\n }\\n\\n indexUpdated = (index + 1) % cardinalityUpdated;\\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\\n }\\n }\\n\\n /// @notice Prepares the oracle array to store up to `next` observations\\n /// @param self The stored oracle array\\n /// @param current The current next cardinality of the oracle array\\n /// @param next The proposed next cardinality which will be populated in the oracle array\\n /// @return next The next cardinality which will be populated in the oracle array\\n function grow(\\n Observation[65535] storage self,\\n uint16 current,\\n uint16 next\\n ) internal returns (uint16) {\\n unchecked {\\n if (current <= 0) revert I();\\n // no-op if the passed next value isn't greater than the current next value\\n if (next <= current) return current;\\n // store in each slot to prevent fresh SSTOREs in swaps\\n // this data will not be used because the initialized boolean is still false\\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\\n return next;\\n }\\n }\\n\\n /// @notice comparator for 32-bit timestamps\\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\\n /// @param time A timestamp truncated to 32 bits\\n /// @param a A comparison timestamp from which to determine the relative position of `time`\\n /// @param b From which to determine the relative position of `time`\\n /// @return Whether `a` is chronologically <= `b`\\n function lte(\\n uint32 time,\\n uint32 a,\\n uint32 b\\n ) private pure returns (bool) {\\n unchecked {\\n // if there hasn't been overflow, no need to adjust\\n if (a <= time && b <= time) return a <= b;\\n\\n uint256 aAdjusted = a > time ? a : a + 2**32;\\n uint256 bAdjusted = b > time ? b : b + 2**32;\\n\\n return aAdjusted <= bAdjusted;\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\\n /// The result may be the same observation, or adjacent observations.\\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation recorded before, or at, the target\\n /// @return atOrAfter The observation recorded at, or after, the target\\n function binarySearch(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n uint16 index,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n uint256 l = (index + 1) % cardinality; // oldest observation\\n uint256 r = l + cardinality - 1; // newest observation\\n uint256 i;\\n while (true) {\\n i = (l + r) / 2;\\n\\n beforeOrAt = self[i % cardinality];\\n\\n // we've landed on an uninitialized tick, keep searching higher (more recently)\\n if (!beforeOrAt.initialized) {\\n l = i + 1;\\n continue;\\n }\\n\\n atOrAfter = self[(i + 1) % cardinality];\\n\\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\\n\\n // check if we've found the answer!\\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\\n\\n if (!targetAtOrAfter) r = i - 1;\\n else l = i + 1;\\n }\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\\n /// @dev Assumes there is at least 1 initialized observation.\\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param tick The active tick at the time of the returned or simulated observation\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The total pool liquidity at the time of the call\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\\n function getSurroundingObservations(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n // optimistically set before to the newest observation\\n beforeOrAt = self[index];\\n\\n // if the target is chronologically at or after the newest observation, we can early return\\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\\n if (beforeOrAt.blockTimestamp == target) {\\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\\n return (beforeOrAt, atOrAfter);\\n } else {\\n // otherwise, we need to transform\\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\\n }\\n }\\n\\n // now, set before to the oldest observation\\n beforeOrAt = self[(index + 1) % cardinality];\\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\\n\\n // ensure that the target is chronologically at or after the oldest observation\\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\\n\\n // if we've reached this point, we have to binary search\\n return binarySearch(self, time, target, index, cardinality);\\n }\\n }\\n\\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\\n /// at exactly the timestamp between the two observations.\\n /// @param self The stored oracle array\\n /// @param time The current block timestamp\\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\\n function observeSingle(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 secondsAgo,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\\n unchecked {\\n if (secondsAgo == 0) {\\n Observation memory last = self[index];\\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\\n }\\n\\n uint32 target = time - secondsAgo;\\n\\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\\n self,\\n time,\\n target,\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n\\n if (target == beforeOrAt.blockTimestamp) {\\n // we're at the left boundary\\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\\n } else if (target == atOrAfter.blockTimestamp) {\\n // we're at the right boundary\\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\\n } else {\\n // we're in the middle\\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\\n return (\\n beforeOrAt.tickCumulative +\\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\\n int56(uint56(targetDelta)),\\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\\n uint160(\\n (uint256(\\n atOrAfter.secondsPerLiquidityCumulativeX128 -\\n beforeOrAt.secondsPerLiquidityCumulativeX128\\n ) * targetDelta) / observationTimeDelta\\n )\\n );\\n }\\n }\\n }\\n\\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\\n /// @dev Reverts if `secondsAgos` > oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\\n function observe(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32[] memory secondsAgos,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\\n unchecked {\\n if (cardinality <= 0) revert I();\\n\\n tickCumulatives = new int56[](secondsAgos.length);\\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\\n for (uint256 i = 0; i < secondsAgos.length; i++) {\\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\\n self,\\n time,\\n secondsAgos[i],\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa25b18af947c36b9add9e229c361beb6aba176fb435d7a24e6dc723cbc187442\",\"license\":\"BUSL-1.1\"},\"@uniswap/v3-core/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity ^0.8.0;\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n error T();\\n error R();\\n\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n unchecked {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n if (absTick > uint256(int256(MAX_TICK))) revert T();\\n\\n uint256 ratio = absTick & 0x1 != 0\\n ? 0xfffcb933bd6fad37aa2d162d1a594001\\n : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\\n /// ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n unchecked {\\n // second inequality must be < because the price can never reach the price at the max tick\\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5c57de03a91cc2ec8939865dbbcb0197bb6c353b711075eefd8e0fca5e102129\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/OracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\\nimport {OracleSidechain} from './OracleSidechain.sol';\\nimport {IOracleFactory, IOracleSidechain, IDataReceiver} from '../interfaces/IOracleFactory.sol';\\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\\n\\n/// @title The OracleFactory contract\\n/// @notice Handles the deployment of new OracleSidechains\\ncontract OracleFactory is IOracleFactory, Governable {\\n /// @inheritdoc IOracleFactory\\n IDataReceiver public dataReceiver;\\n\\n /// @inheritdoc IOracleFactory\\n OracleParameters public oracleParameters;\\n\\n /// @inheritdoc IOracleFactory\\n uint16 public initialCardinality = 144;\\n\\n /// @inheritdoc IOracleFactory\\n bytes32 public constant ORACLE_INIT_CODE_HASH = keccak256(type(OracleSidechain).creationCode);\\n\\n constructor(address _governor, IDataReceiver _dataReceiver) Governable(_governor) {\\n _setDataReceiver(_dataReceiver);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function deployOracle(bytes32 _poolSalt, uint24 _initialNonce) external onlyDataReceiver returns (IOracleSidechain _oracle) {\\n oracleParameters = OracleParameters({poolSalt: _poolSalt, poolNonce: _initialNonce, cardinality: initialCardinality});\\n _oracle = new OracleSidechain{salt: _poolSalt}();\\n\\n delete oracleParameters;\\n emit OracleDeployed(_poolSalt, address(_oracle), _initialNonce);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function setDataReceiver(IDataReceiver _dataReceiver) external onlyGovernor {\\n _setDataReceiver(_dataReceiver);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function setInitialCardinality(uint16 _initialCardinality) external onlyGovernor {\\n if (_initialCardinality == 0) revert ZeroAmount();\\n\\n initialCardinality = _initialCardinality;\\n emit InitialCardinalitySet(_initialCardinality);\\n }\\n\\n function increaseOracleCardinality(bytes32 _poolSalt, uint16 _observationCardinalityNext) external onlyGovernor {\\n IOracleSidechain _oracle = getPool(_poolSalt);\\n _oracle.increaseObservationCardinalityNext(_observationCardinalityNext);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle) {\\n bytes32 _poolSalt = getPoolSalt(_tokenA, _tokenB, _fee);\\n _oracle = getPool(_poolSalt);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function getPool(bytes32 _poolSalt) public view returns (IOracleSidechain _oracle) {\\n _oracle = IOracleSidechain(Create2Address.computeAddress(address(this), _poolSalt, ORACLE_INIT_CODE_HASH));\\n if (address(_oracle).code.length == 0) return IOracleSidechain(address(0));\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) public pure returns (bytes32 _poolSalt) {\\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\\n _poolSalt = keccak256(abi.encode(_token0, _token1, _fee));\\n }\\n\\n function _setDataReceiver(IDataReceiver _dataReceiver) private {\\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\\n\\n dataReceiver = _dataReceiver;\\n emit DataReceiverSet(_dataReceiver);\\n }\\n\\n modifier onlyDataReceiver() {\\n if (msg.sender != address(dataReceiver)) revert OnlyDataReceiver();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xf0707ebeed3425fca5ccc20dfc2cb291859674ada92d5d651f7271ee3cef3d49\",\"license\":\"MIT\"},\"solidity/contracts/OracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\\n\\n/// @title The SidechainOracle contract\\n/// @notice Computes and stores on-chain price data from Mainnet\\ncontract OracleSidechain is IOracleSidechain {\\n using Oracle for Oracle.Observation[65535];\\n\\n /// @inheritdoc IOracleSidechain\\n IOracleFactory public immutable factory;\\n\\n struct Slot0 {\\n // the current price\\n uint160 sqrtPriceX96;\\n // the current tick\\n int24 tick;\\n // the most-recently updated index of the observations array\\n uint16 observationIndex;\\n // the current maximum number of observations that are being stored\\n uint16 observationCardinality;\\n // the next maximum number of observations to store, triggered in observations.write\\n uint16 observationCardinalityNext;\\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\\n // represented as an integer denominator (1/x)%\\n uint8 feeProtocol;\\n // whether the pool is locked\\n bool unlocked;\\n }\\n /// @inheritdoc IOracleSidechain\\n Slot0 public slot0;\\n\\n /// @inheritdoc IOracleSidechain\\n Oracle.Observation[65535] public observations;\\n\\n /// @inheritdoc IOracleSidechain\\n bytes32 public immutable poolSalt;\\n\\n uint24 public poolNonce;\\n /// @inheritdoc IOracleSidechain\\n address public token0;\\n /// @inheritdoc IOracleSidechain\\n address public token1;\\n /// @inheritdoc IOracleSidechain\\n uint24 public fee;\\n\\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\\n function _getBlockTimestamp() internal view virtual returns (uint32) {\\n return uint32(block.timestamp); // truncation is desired\\n }\\n\\n constructor() {\\n factory = IOracleFactory(msg.sender);\\n uint16 _cardinality;\\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\\n\\n slot0 = Slot0({\\n sqrtPriceX96: 0,\\n tick: 0,\\n observationIndex: _cardinality - 1,\\n observationCardinality: _cardinality,\\n observationCardinalityNext: _cardinality,\\n feeProtocol: 0,\\n unlocked: true\\n });\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external {\\n if (!slot0.unlocked) revert AI();\\n\\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\\n\\n token0 = _token0;\\n token1 = _token1;\\n fee = _fee;\\n slot0.unlocked = false;\\n\\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\\n {\\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\\n if (_poolNonce != poolNonce) return false;\\n poolNonce++;\\n\\n uint256 _observationsDataLength = _observationsData.length;\\n for (uint256 _i; _i < _observationsDataLength; ) {\\n _write(_observationsData[_i]);\\n unchecked {\\n ++_i;\\n }\\n }\\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\\n\\n // emits UniV3 Swap event topic with minimal data\\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\\n return true;\\n }\\n\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\\n if (_observationCardinalityNext <= _observationCardinalityNextOld) revert AI();\\n slot0.observationCardinalityNext = _observationCardinalityNext;\\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\\n }\\n\\n function _write(ObservationData memory _observationData) private {\\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\\n slot0.observationIndex,\\n _observationData.blockTimestamp,\\n slot0.tick,\\n 0,\\n slot0.observationCardinality,\\n slot0.observationCardinalityNext\\n );\\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\\n slot0.tick = _observationData.tick;\\n }\\n\\n modifier onlyDataReceiver() {\\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\\n _;\\n }\\n\\n modifier onlyFactory() {\\n if (msg.sender != address(factory)) revert OnlyFactory();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x1b830dc6ad7405f2d533e1aa8eb079853edcdf301b396ac6b1d3c41573b62787\",\"license\":\"MIT\"},\"solidity/interfaces/IDataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleFactory} from './IOracleFactory.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\\n\\ninterface IDataReceiver is IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @notice Tracks already deployed oracles\\n /// @param _poolSalt The identifier of the oracle\\n /// @return _deployedOracle The address of the correspondant Oracle\\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\\n\\n /// @notice Tracks the whitelisting of bridge adapters\\n /// @param _adapter Address of the bridge adapter to consult\\n /// @return _isAllowed Whether a bridge adapter is whitelisted\\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a broadcast observation is succesfully processed\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsAdded(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a broadcast observation is cached for later processing\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsCached(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a new adapter whitelisting rule is set\\n /// @param _adapter Address of the adapter\\n /// @param _isAllowed New whitelisting status\\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\\n\\n // ERRORS\\n\\n /// @notice Thrown when the broadcast nonce is incorrect\\n error ObservationsNotWritable();\\n\\n /// @notice Thrown when a not-whitelisted adapter triggers an update\\n error UnallowedAdapter();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows whitelisted bridge adapters to push a broadcast\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _poolNonce Nonce of the observation broadcast\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external;\\n\\n /// @notice Allows any address to attempt to insert cached observations\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _maxObservations Maximum number of observations to process\\n /// @dev Use _maxObservations = 0 to process all possible cached observations\\n function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external;\\n\\n /// @notice Allows governance to set an adapter whitelisted state\\n /// @param _receiverAdapter Address of the adapter\\n /// @param _isWhitelisted New whitelisting status\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\\n\\n /// @notice Allows governance to batch set adapters whitelisted state\\n /// @param _receiverAdapters Array of addresses of the adapter\\n /// @param _isWhitelisted Array of whitelisting status for each address\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\\n}\\n\",\"keccak256\":\"0xd07e75380d5086ea78909bc5c80aadc110903004f50c006b0281cc090f273291\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IDataReceiver} from './IDataReceiver.sol';\\n\\ninterface IOracleFactory is IGovernable {\\n // STRUCTS\\n\\n struct OracleParameters {\\n bytes32 poolSalt; // Identifier of the pool and oracle\\n uint24 poolNonce; // Initial nonce of the deployed pool\\n uint16 cardinality; // Initial cardinality of the deployed pool\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\\n //solhint-disable-next-line func-name-mixedcase\\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\\n\\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /// @return _poolSalt The id of both the oracle and the pool\\n /// @return _poolNonce The initial nonce of the pool data\\n /// @return _cardinality The size of the observations memory storage\\n function oracleParameters()\\n external\\n view\\n returns (\\n bytes32 _poolSalt,\\n uint24 _poolNonce,\\n uint16 _cardinality\\n );\\n\\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function initialCardinality() external view returns (uint16 _initialCardinality);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new oracle is deployed\\n /// @param _poolSalt The id of both the oracle and the pool\\n /// @param _oracle The address of the deployed oracle\\n /// @param _initialNonce The initial nonce of the pool data\\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\\n\\n /// @notice Emitted when a new DataReceiver is set\\n /// @param _dataReceiver The address of the new DataReceiver\\n event DataReceiverSet(IDataReceiver _dataReceiver);\\n\\n /// @notice Emitted when a new initial oracle cardinality is set\\n /// @param _initialCardinality The initial length of the observationCardinality array\\n event InitialCardinalitySet(uint16 _initialCardinality);\\n\\n // ERRORS\\n\\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\\n error OnlyDataReceiver();\\n\\n // FUNCTIONS\\n\\n /// @notice Deploys a new oracle given an inputted salt\\n /// @dev Requires that the salt has not been deployed before\\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\\n /// @return _oracle The address of the newly deployed oracle\\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\\n\\n /// @notice Allows governor to set a new allowed dataReceiver\\n /// @dev Will disallow the previous dataReceiver\\n /// @param _dataReceiver The address of the new allowed dataReceiver\\n function setDataReceiver(IDataReceiver _dataReceiver) external;\\n\\n /// @notice Allows governor to set a new initial cardinality for new oracles\\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function setInitialCardinality(uint16 _initialCardinality) external;\\n\\n /// @notice Overrides UniV3Factory getPool mapping\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _oracle The oracle address\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle);\\n\\n /// @notice Tracks the addresses of the oracle by poolSalt\\n /// @param _poolSalt Identifier of both the pool and the oracle\\n /// @return _oracle The address (if deployed) of the correspondant oracle\\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\\n\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _poolSalt Pool salt for inquired parameters\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (bytes32 _poolSalt);\\n}\\n\",\"keccak256\":\"0xc32bfc32a274923ce1a089acc024396e702ae354773f0ac0a683e43ded904954\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleFactory} from './IOracleFactory.sol';\\n\\ninterface IOracleSidechain {\\n // STRUCTS\\n\\n struct ObservationData {\\n uint32 blockTimestamp;\\n int24 tick;\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function factory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @return _token0 The mainnet address of the Token0 of the oracle\\n function token0() external view returns (address _token0);\\n\\n /// @return _token1 The mainnet address of the Token1 of the oracle\\n function token1() external view returns (address _token1);\\n\\n /// @return _fee The fee identifier of the pool\\n function fee() external view returns (uint24 _fee);\\n\\n /// @return _poolSalt The identifier of both the pool and the oracle\\n function poolSalt() external view returns (bytes32 _poolSalt);\\n\\n /// @return _poolNonce Last recorded nonce of the pool history\\n function poolNonce() external view returns (uint24 _poolNonce);\\n\\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\\n /// @return _tick Used to maintain compatibility with Uniswap V3\\n /// @return _observationIndex The index of the last oracle observation that was written,\\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\\n /// @return _unlocked Used to track if a pool information was already verified\\n function slot0()\\n external\\n view\\n returns (\\n uint160 _sqrtPriceX96,\\n int24 _tick,\\n uint16 _observationIndex,\\n uint16 _observationCardinality,\\n uint16 _observationCardinalityNext,\\n uint8 _feeProtocol,\\n bool _unlocked\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param _index The element of the observations array to fetch\\n /// @return _blockTimestamp The timestamp of the observation,\\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// @return _initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 _index)\\n external\\n view\\n returns (\\n uint32 _blockTimestamp,\\n int56 _tickCumulative,\\n uint160 _secondsPerLiquidityCumulativeX128,\\n bool _initialized\\n );\\n\\n // EVENTS\\n\\n /// @notice Emitted when the pool information is verified\\n /// @param _poolSalt Identifier of the pool and the oracle\\n /// @param _token0 The contract address of either token0 or token1\\n /// @param _token1 The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\\n\\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param _tick The log base 1.0001 of price of the pool after the swap\\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\\n\\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\\n\\n // ERRORS\\n\\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\\n error AI();\\n\\n /// @notice Thrown if the pool info does not correspond to the pool salt\\n error InvalidPool();\\n\\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\\n error OnlyDataReceiver();\\n\\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\\n error OnlyFactory();\\n\\n // FUNCTIONS\\n\\n /// @notice Permisionless method to verify token0, token1 and fee\\n /// @dev Before verified, token0 and token1 views will return address(0)\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external;\\n\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\\n\\n /// @notice Permisioned method to push a dataset to update\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolNonce Nonce of the observation broadcast\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\\n\\n /// @notice Permisioned method to increase the cardinalityNext value\\n /// @param _observationCardinalityNext The new next length of the observations array\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa90206e3de00ad866b7f4792ce29220ee0ca561d59629ba638a31c4d6fd3941b\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IBridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport {IDataReceiver} from '../IDataReceiver.sol';\\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\\n\\ninterface IBridgeReceiverAdapter is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @notice Gets the address of the DataReceiver contract\\n /// @return _dataReceiver Address of the DataReceiver contract\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /* NOTE: callback methods should be here declared */\\n}\\n\",\"keccak256\":\"0x49e5c9c6a28521933a3f2b01a529fbae9aac1edd71dbe904586a2f06148b1974\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040526005805461ffff1916609017905534801561001e57600080fd5b5060405161278638038061278683398101604081905261003d91610128565b816001600160a01b0381166100655760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b039290921691909117905561008e81610095565b5050610162565b6001600160a01b0381166100bc5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be9060200160405180910390a150565b6001600160a01b038116811461012557600080fd5b50565b6000806040838503121561013b57600080fd5b825161014681610110565b602084015190925061015781610110565b809150509250929050565b612615806101716000396000f3fe60806040523480156200001157600080fd5b5060043610620001095760003560e01c806391a0b97911620000a3578063e8047788116200006e578063e80477881462000247578063ebaa56aa146200025b578063f235757f146200027e578063f6c00927146200029557600080fd5b806391a0b97914620001cd57806397862d6d14620001d757806399df712014620001ee578063e3056a34146200023357600080fd5b80631698ee8211620000e45780631698ee8214620001625780633c1a17ff14620001795780635cc1fd36146200019f57806384b6db1414620001b657600080fd5b806307d5851a146200010e5780630c340a24146200012757806313f6986d1462000158575b600080fd5b620001256200011f36600462000892565b620002ac565b005b6000546200013b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b62000125620002e6565b6200013b62000173366004620008cd565b6200031e565b620001906200018a366004620008cd565b62000344565b6040519081526020016200014f565b6200013b620001b03660046200091b565b620003bf565b62000125620001c73660046200095d565b620004c8565b6200019062000568565b62000125620001e836600462000983565b62000597565b6003546004546200020f919062ffffff8116906301000000900461ffff1683565b6040805193845262ffffff909216602084015261ffff16908201526060016200014f565b6001546200013b906001600160a01b031681565b6002546200013b906001600160a01b031681565b6005546200026a9061ffff1681565b60405161ffff90911681526020016200014f565b620001256200028f36600462000892565b62000634565b6200013b620002a6366004620009a1565b6200066b565b6000546001600160a01b03163314620002d85760405163070545c960e51b815260040160405180910390fd5b620002e38162000714565b50565b6001546001600160a01b031633146200031257604051639ba0305d60e01b815260040160405180910390fd5b6200031c6200078b565b565b6000806200032e85858562000344565b90506200033b816200066b565b95945050505050565b6000806000846001600160a01b0316866001600160a01b0316106200036b5784866200036e565b85855b604080516001600160a01b03808516602083015283169181019190915262ffffff87166060820152919350915060800160405160208183030381529060405280519060200120925050509392505050565b6002546000906001600160a01b03163314620003ee57604051638e5b30cb60e01b815260040160405180910390fd5b6040805160608101825284815262ffffff84166020820181905260055461ffff1691830182905260038690556004805464ffffffffff1916909117630100000090920291909117905551839062000445906200086e565b8190604051809103906000f590508015801562000466573d6000803e3d6000fd5b5060006003556004805464ffffffffff1916905560405162ffffff841681529091506001600160a01b0382169084907f5b7d803564bd9c17d971ee338d1e9ffafd2aa0a8dbd7065f9d3900ecf7a842149060200160405180910390a392915050565b6000546001600160a01b03163314620004f45760405163070545c960e51b815260040160405180910390fd5b600062000501836200066b565b6040516332148f6760e01b815261ffff841660048201529091506001600160a01b038216906332148f6790602401600060405180830381600087803b1580156200054a57600080fd5b505af11580156200055f573d6000803e3d6000fd5b50505050505050565b60405162000579602082016200086e565b6020820181038252601f19601f820116604052508051906020012081565b6000546001600160a01b03163314620005c35760405163070545c960e51b815260040160405180910390fd5b8061ffff16600003620005e957604051631f2a200560e01b815260040160405180910390fd5b6005805461ffff191661ffff83169081179091556040519081527fec9fa937c26cb048aac5fc5992eaace52f38cd13c8da22f42630090bd258261f906020015b60405180910390a150565b6000546001600160a01b03163314620006605760405163070545c960e51b815260040160405180910390fd5b620002e381620007e9565b6000620006f230836040518060200162000685906200086e565b601f1982820381018352601f90910116604081815282516020938401206001600160f81b03198385015260609590951b6bffffffffffffffffffffffff19166021830152603582019390935260558082019490945282518082039094018452607501909152815191012090565b9050806001600160a01b03163b6000036200070f57506000919050565b919050565b6001600160a01b0381166200073c5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be9060200162000629565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6001600160a01b038116620008115760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910162000629565b611c2480620009bc83390190565b6001600160a01b0381168114620002e357600080fd5b600060208284031215620008a557600080fd5b8135620008b2816200087c565b9392505050565b803562ffffff811681146200070f57600080fd5b600080600060608486031215620008e357600080fd5b8335620008f0816200087c565b9250602084013562000902816200087c565b91506200091260408501620008b9565b90509250925092565b600080604083850312156200092f57600080fd5b823591506200094160208401620008b9565b90509250929050565b803561ffff811681146200070f57600080fd5b600080604083850312156200097157600080fd5b8235915062000941602084016200094a565b6000602082840312156200099657600080fd5b620008b2826200094a565b600060208284031215620009b457600080fd5b503591905056fe60c06040523480156200001157600080fd5b50336080819052604080516304cefb8960e51b81529051600092916399df71209160048083019260609291908290030181865afa15801562000057573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200007d9190620001bb565b62010000805462ffffff191662ffffff939093169290921790915560a0919091526040805160e081018252600080825260208201529192508101620000c460018462000210565b61ffff90811682529283166020808301829052604080840192909252600060608085018290526001608095860152855182549387015194870151918701519587015160a088015160c0909801511515600160f01b0260ff60f01b1960ff99909916600160e81b0260ff60e81b19928b16600160d81b029290921662ffffff60d81b19988b16600160c81b0261ffff60c81b1995909b16600160b81b029490941663ffffffff60b81b1962ffffff909816600160a01b026001600160b81b03199097166001600160a01b0390941693909317959095179590951617969096179390931694909417179190911691909117905562000242565b600080600060608486031215620001d157600080fd5b83519250602084015162ffffff81168114620001ec57600080fd5b604085015190925061ffff811681146200020557600080fd5b809150509250925092565b600061ffff838116908316818110156200023a57634e487b7160e01b600052601160045260246000fd5b039392505050565b60805160a0516119a0620002846000396000818161027a01528181610694015261074b0152600081816102af01528181610302015261052b01526119a06000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063883bdbfd11610071578063883bdbfd1461022f5780639fdbd4d714610250578063c1c9115a14610275578063c45a0155146102aa578063d21220a7146102d1578063ddca3f43146102e657600080fd5b80630dfe1681146100b957806323e512d4146100f2578063252c09d71461011557806332148f67146101625780633453952f146101775780633850c7bd1461018a575b600080fd5b62010000546100d590630100000090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610105610100366004611658565b6102fe565b60405190151581526020016100e9565b610128610123366004611759565b6104db565b6040805163ffffffff909516855260069390930b60208501526001600160a01b0390911691830191909152151560608201526080016100e9565b610175610170366004611772565b610520565b005b6101756101853660046117ae565b6105fc565b6000546101de906001600160a01b03811690600160a01b810460020b9061ffff600160b81b8204811691600160c81b8104821691600160d81b8204169060ff600160e81b8204811691600160f01b90041687565b604080516001600160a01b03909816885260029690960b602088015261ffff94851695870195909552918316606086015291909116608084015260ff1660a0830152151560c082015260e0016100e9565b61024261023d3660046117f5565b61079f565b6040516100e992919061186a565b62010000546102619062ffffff1681565b60405162ffffff90911681526020016100e9565b61029c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100e9565b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b62010001546100d5906001600160a01b031681565b620100015461026190600160a01b900462ffffff1681565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e80477886040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038291906118f1565b6001600160a01b0316336001600160a01b0316146103b357604051638e5b30cb60e01b815260040160405180910390fd5b620100005462ffffff8381169116146103ce575060006104d5565b62010000805462ffffff169060006103e58361190e565b91906101000a81548162ffffff021916908362ffffff1602179055505060008351905060005b8181101561043d576104358582815181106104285761042861193e565b6020026020010151610810565b60010161040b565b5060005461045490600160a01b900460020b6108b0565b600080546001600160a01b0319166001600160a01b039290921691821780825560408051838152602081018490529081019390935260608301829052600160a01b900460020b60808301529081907fc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca679060a00160405180910390a360019150505b92915050565b60018161ffff81106104ec57600080fd5b015463ffffffff81169150600160201b810460060b90600160581b81046001600160a01b031690600160f81b900460ff1684565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461056957604051630636a15760e11b815260040160405180910390fd5b60005461ffff600160d81b9091048116908216811061059b5760405163139816ff60e31b815260040160405180910390fd5b6000805461ffff60d81b1916600160d81b61ffff8581169182029290921790925560408051918416825260208201929092527fac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a910160405180910390a15050565b600054600160f01b900460ff166106265760405163139816ff60e31b815260040160405180910390fd5b600080836001600160a01b0316856001600160a01b03161061064957838561064c565b84845b604080516001600160a01b03808516602083015283169181019190915262ffffff861660608201529193509150608001604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000146106d05760405162820f3560e61b815260040160405180910390fd5b6201000080546301000000600160b81b03191663010000006001600160a01b03858116918202929092179092556201000180549184166001600160b81b03199092168217600160a01b62ffffff8816908102919091179091556000805460ff60f01b19169055604080519384526020840192909252908201527f0000000000000000000000000000000000000000000000000000000000000000907fb50ab96cf9f83d6c076a0d2a6e27a65bf1242920ba414829aa618d57d4a263739060600160405180910390a25050505050565b6060806108054285858080602002602001604051908101604052809392919081815260200183836020028082843760009201829052508054600196959450600160a01b810460020b935061ffff600160b81b820481169350600160c81b90910416610bd2565b915091509250929050565b60008054825182916108529160019161ffff600160b81b820481169291600160a01b810460020b918791600160c81b8104821691600160d81b90910416610d1d565b600080546020969096015163ffffffff60b81b19909616600160c81b61ffff9384160261ffff60b81b191617600160b81b93909216929092021762ffffff60a01b1916600160a01b62ffffff90951694909402939093179092555050565b60008060008360020b126108c7578260020b6108cf565b8260020b6000035b9050620d89e88111156108f5576040516315e4079d60e11b815260040160405180910390fd5b60008160011660000361090c57600160801b61091e565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615610952576ffff97272373d413259a46990580e213a0260801c5b6004821615610971576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610990576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b60108216156109af576fffcb9843d60f6159c9db58835c9266440260801c5b60208216156109ce576fff973b41fa98c081472e6896dfb254c00260801c5b60408216156109ed576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610a0c576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610a2c576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610a4c576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610a6c576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610a8c576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610aac576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610acc576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610aec576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610b0c576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610b2d576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610b4d576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610b6c576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610b89576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610baa578060001981610ba657610ba6611954565b0490505b600160201b810615610bbd576001610bc0565b60005b60ff16602082901c0192505050919050565b60608060008361ffff1611610bfa57604051636b93000360e11b815260040160405180910390fd5b865167ffffffffffffffff811115610c1457610c146115d0565b604051908082528060200260200182016040528015610c3d578160200160208202803683370190505b509150865167ffffffffffffffff811115610c5a57610c5a6115d0565b604051908082528060200260200182016040528015610c83578160200160208202803683370190505b50905060005b8751811015610d1057610cba8a8a8a8481518110610ca957610ca961193e565b60200260200101518a8a8a8a610ea5565b848381518110610ccc57610ccc61193e565b60200260200101848481518110610ce557610ce561193e565b6001600160a01b039093166020938402919091019092019190915260069190910b9052600101610c89565b5097509795505050505050565b6000806000898961ffff1661ffff8110610d3957610d3961193e565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff161515606083015290925089169003610da25788859250925050610e99565b8461ffff168461ffff16118015610dc357506001850361ffff168961ffff16145b15610dd057839150610dd4565b8491505b8161ffff168960010161ffff1681610dee57610dee611954565b069250610dfd81898989611054565b8a8461ffff1661ffff8110610e1457610e1461193e565b825191018054602084015160408501516060909501511515600160f81b026001600160f81b036001600160a01b03909616600160581b02959095166affffffffffffffffffffff66ffffffffffffff909216600160201b026affffffffffffffffffffff1990931663ffffffff90951694909417919091171691909117919091179055505b97509795505050505050565b6000808663ffffffff16600003610f4e576000898661ffff1661ffff8110610ecf57610ecf61193e565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff16151560608301529092508a1614610f3a57610f37818a8988611054565b90505b806020015181604001519250925050610e99565b868803600080610f638c8c858c8c8c8c611119565b91509150816000015163ffffffff168363ffffffff1603610f94578160200151826040015194509450505050610e99565b806000015163ffffffff168363ffffffff1603610fc1578060200151816040015194509450505050610e99565b60008260000151826000015103905060008360000151850390508063ffffffff168263ffffffff1660060b856020015185602001510360060b8161100757611007611954565b05028460200151018263ffffffff168263ffffffff1686604001518660400151036001600160a01b0316028161103f5761103f611954565b04856040015101965096505050505050610e99565b604080516080810182526000808252602082018190529181018290526060810191909152600085600001518503905060405180608001604052808663ffffffff1681526020018263ffffffff168660020b0288602001510160060b81526020016000856001600160801b0316116110cc5760016110ce565b845b6001600160801b031663ffffffff60801b608085901b16816110f2576110f2611954565b048860400151016001600160a01b0316815260200160011515815250915050949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152888561ffff1661ffff81106111785761117861193e565b60408051608081018252919092015463ffffffff8116808352600160201b820460060b6020840152600160581b82046001600160a01b031693830193909352600160f81b900460ff161515606082015292506111d690899089611325565b1561120257815163ffffffff888116911614610e9957816111f983898988611054565b91509150610e99565b888361ffff168660010161ffff168161121d5761121d611954565b0661ffff1661ffff81106112335761123361193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529092506112dc57604080516080810182528a5463ffffffff81168252600160201b810460060b6020830152600160581b81046001600160a01b031692820192909252600160f81b90910460ff161515606082015291505b6112eb88836000015189611325565b611308576040516327e8e87560e01b815260040160405180910390fd5b61131589898988876113e8565b9150915097509795505050505050565b60008363ffffffff168363ffffffff161115801561134f57508363ffffffff168263ffffffff1611155b1561136b578163ffffffff168363ffffffff16111590506113e1565b60008463ffffffff168463ffffffff1611611392578363ffffffff16600160201b0161139a565b8363ffffffff165b64ffffffffff16905060008563ffffffff168463ffffffff16116113ca578363ffffffff16600160201b016113d2565b8363ffffffff165b64ffffffffff16909111159150505b9392505050565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260008361ffff168560010161ffff168161144c5761144c611954565b0661ffff169050600060018561ffff16830103905060005b506002818301048961ffff8716828161147f5761147f611954565b0661ffff81106114915761149161193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529095506114f557806001019250611464565b898661ffff16826001018161150c5761150c611954565b0661ffff811061151e5761151e61193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b90910416151560608201528551909450600090611582908b908b611325565b905080801561159b575061159b8a8a8760000151611325565b156115a657506115c3565b806115b6576001820392506115bd565b8160010193505b50611464565b5050509550959350505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611609576116096115d0565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611638576116386115d0565b604052919050565b803562ffffff8116811461165357600080fd5b919050565b600080604080848603121561166c57600080fd5b833567ffffffffffffffff8082111561168457600080fd5b818601915086601f83011261169857600080fd5b81356020828211156116ac576116ac6115d0565b6116ba818360051b0161160f565b828152818101935060069290921b8401810191898311156116da57600080fd5b938101935b8285101561173e5785858b0312156116f75760008081fd5b6116ff6115e6565b853563ffffffff811681146117145760008081fd5b815285830135600281900b811461172b5760008081fd5b81840152845293850193928101926116df565b965061174b888201611640565b955050505050509250929050565b60006020828403121561176b57600080fd5b5035919050565b60006020828403121561178457600080fd5b813561ffff811681146113e157600080fd5b6001600160a01b03811681146117ab57600080fd5b50565b6000806000606084860312156117c357600080fd5b83356117ce81611796565b925060208401356117de81611796565b91506117ec60408501611640565b90509250925092565b6000806020838503121561180857600080fd5b823567ffffffffffffffff8082111561182057600080fd5b818501915085601f83011261183457600080fd5b81358181111561184357600080fd5b8660208260051b850101111561185857600080fd5b60209290920196919550909350505050565b604080825283519082018190526000906020906060840190828701845b828110156118a657815160060b84529284019290840190600101611887565b5050508381038285015284518082528583019183019060005b818110156118e45783516001600160a01b0316835292840192918401916001016118bf565b5090979650505050505050565b60006020828403121561190357600080fd5b81516113e181611796565b600062ffffff80831681810361193457634e487b7160e01b600052601160045260246000fd5b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fdfea264697066735822122048903427db1b98c0cd97b26ab800e55a51c8b5b98cd5a363f22490c0ac241d1b64736f6c634300080f0033a2646970667358221220c1e84aa1e8d7c1251c18a95b48835b3934b1d40ccda3e8d1ccc7bd7d096c898964736f6c634300080f0033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620001095760003560e01c806391a0b97911620000a3578063e8047788116200006e578063e80477881462000247578063ebaa56aa146200025b578063f235757f146200027e578063f6c00927146200029557600080fd5b806391a0b97914620001cd57806397862d6d14620001d757806399df712014620001ee578063e3056a34146200023357600080fd5b80631698ee8211620000e45780631698ee8214620001625780633c1a17ff14620001795780635cc1fd36146200019f57806384b6db1414620001b657600080fd5b806307d5851a146200010e5780630c340a24146200012757806313f6986d1462000158575b600080fd5b620001256200011f36600462000892565b620002ac565b005b6000546200013b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b62000125620002e6565b6200013b62000173366004620008cd565b6200031e565b620001906200018a366004620008cd565b62000344565b6040519081526020016200014f565b6200013b620001b03660046200091b565b620003bf565b62000125620001c73660046200095d565b620004c8565b6200019062000568565b62000125620001e836600462000983565b62000597565b6003546004546200020f919062ffffff8116906301000000900461ffff1683565b6040805193845262ffffff909216602084015261ffff16908201526060016200014f565b6001546200013b906001600160a01b031681565b6002546200013b906001600160a01b031681565b6005546200026a9061ffff1681565b60405161ffff90911681526020016200014f565b620001256200028f36600462000892565b62000634565b6200013b620002a6366004620009a1565b6200066b565b6000546001600160a01b03163314620002d85760405163070545c960e51b815260040160405180910390fd5b620002e38162000714565b50565b6001546001600160a01b031633146200031257604051639ba0305d60e01b815260040160405180910390fd5b6200031c6200078b565b565b6000806200032e85858562000344565b90506200033b816200066b565b95945050505050565b6000806000846001600160a01b0316866001600160a01b0316106200036b5784866200036e565b85855b604080516001600160a01b03808516602083015283169181019190915262ffffff87166060820152919350915060800160405160208183030381529060405280519060200120925050509392505050565b6002546000906001600160a01b03163314620003ee57604051638e5b30cb60e01b815260040160405180910390fd5b6040805160608101825284815262ffffff84166020820181905260055461ffff1691830182905260038690556004805464ffffffffff1916909117630100000090920291909117905551839062000445906200086e565b8190604051809103906000f590508015801562000466573d6000803e3d6000fd5b5060006003556004805464ffffffffff1916905560405162ffffff841681529091506001600160a01b0382169084907f5b7d803564bd9c17d971ee338d1e9ffafd2aa0a8dbd7065f9d3900ecf7a842149060200160405180910390a392915050565b6000546001600160a01b03163314620004f45760405163070545c960e51b815260040160405180910390fd5b600062000501836200066b565b6040516332148f6760e01b815261ffff841660048201529091506001600160a01b038216906332148f6790602401600060405180830381600087803b1580156200054a57600080fd5b505af11580156200055f573d6000803e3d6000fd5b50505050505050565b60405162000579602082016200086e565b6020820181038252601f19601f820116604052508051906020012081565b6000546001600160a01b03163314620005c35760405163070545c960e51b815260040160405180910390fd5b8061ffff16600003620005e957604051631f2a200560e01b815260040160405180910390fd5b6005805461ffff191661ffff83169081179091556040519081527fec9fa937c26cb048aac5fc5992eaace52f38cd13c8da22f42630090bd258261f906020015b60405180910390a150565b6000546001600160a01b03163314620006605760405163070545c960e51b815260040160405180910390fd5b620002e381620007e9565b6000620006f230836040518060200162000685906200086e565b601f1982820381018352601f90910116604081815282516020938401206001600160f81b03198385015260609590951b6bffffffffffffffffffffffff19166021830152603582019390935260558082019490945282518082039094018452607501909152815191012090565b9050806001600160a01b03163b6000036200070f57506000919050565b919050565b6001600160a01b0381166200073c5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be9060200162000629565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6001600160a01b038116620008115760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910162000629565b611c2480620009bc83390190565b6001600160a01b0381168114620002e357600080fd5b600060208284031215620008a557600080fd5b8135620008b2816200087c565b9392505050565b803562ffffff811681146200070f57600080fd5b600080600060608486031215620008e357600080fd5b8335620008f0816200087c565b9250602084013562000902816200087c565b91506200091260408501620008b9565b90509250925092565b600080604083850312156200092f57600080fd5b823591506200094160208401620008b9565b90509250929050565b803561ffff811681146200070f57600080fd5b600080604083850312156200097157600080fd5b8235915062000941602084016200094a565b6000602082840312156200099657600080fd5b620008b2826200094a565b600060208284031215620009b457600080fd5b503591905056fe60c06040523480156200001157600080fd5b50336080819052604080516304cefb8960e51b81529051600092916399df71209160048083019260609291908290030181865afa15801562000057573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200007d9190620001bb565b62010000805462ffffff191662ffffff939093169290921790915560a0919091526040805160e081018252600080825260208201529192508101620000c460018462000210565b61ffff90811682529283166020808301829052604080840192909252600060608085018290526001608095860152855182549387015194870151918701519587015160a088015160c0909801511515600160f01b0260ff60f01b1960ff99909916600160e81b0260ff60e81b19928b16600160d81b029290921662ffffff60d81b19988b16600160c81b0261ffff60c81b1995909b16600160b81b029490941663ffffffff60b81b1962ffffff909816600160a01b026001600160b81b03199097166001600160a01b0390941693909317959095179590951617969096179390931694909417179190911691909117905562000242565b600080600060608486031215620001d157600080fd5b83519250602084015162ffffff81168114620001ec57600080fd5b604085015190925061ffff811681146200020557600080fd5b809150509250925092565b600061ffff838116908316818110156200023a57634e487b7160e01b600052601160045260246000fd5b039392505050565b60805160a0516119a0620002846000396000818161027a01528181610694015261074b0152600081816102af01528181610302015261052b01526119a06000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063883bdbfd11610071578063883bdbfd1461022f5780639fdbd4d714610250578063c1c9115a14610275578063c45a0155146102aa578063d21220a7146102d1578063ddca3f43146102e657600080fd5b80630dfe1681146100b957806323e512d4146100f2578063252c09d71461011557806332148f67146101625780633453952f146101775780633850c7bd1461018a575b600080fd5b62010000546100d590630100000090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610105610100366004611658565b6102fe565b60405190151581526020016100e9565b610128610123366004611759565b6104db565b6040805163ffffffff909516855260069390930b60208501526001600160a01b0390911691830191909152151560608201526080016100e9565b610175610170366004611772565b610520565b005b6101756101853660046117ae565b6105fc565b6000546101de906001600160a01b03811690600160a01b810460020b9061ffff600160b81b8204811691600160c81b8104821691600160d81b8204169060ff600160e81b8204811691600160f01b90041687565b604080516001600160a01b03909816885260029690960b602088015261ffff94851695870195909552918316606086015291909116608084015260ff1660a0830152151560c082015260e0016100e9565b61024261023d3660046117f5565b61079f565b6040516100e992919061186a565b62010000546102619062ffffff1681565b60405162ffffff90911681526020016100e9565b61029c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100e9565b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b62010001546100d5906001600160a01b031681565b620100015461026190600160a01b900462ffffff1681565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e80477886040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038291906118f1565b6001600160a01b0316336001600160a01b0316146103b357604051638e5b30cb60e01b815260040160405180910390fd5b620100005462ffffff8381169116146103ce575060006104d5565b62010000805462ffffff169060006103e58361190e565b91906101000a81548162ffffff021916908362ffffff1602179055505060008351905060005b8181101561043d576104358582815181106104285761042861193e565b6020026020010151610810565b60010161040b565b5060005461045490600160a01b900460020b6108b0565b600080546001600160a01b0319166001600160a01b039290921691821780825560408051838152602081018490529081019390935260608301829052600160a01b900460020b60808301529081907fc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca679060a00160405180910390a360019150505b92915050565b60018161ffff81106104ec57600080fd5b015463ffffffff81169150600160201b810460060b90600160581b81046001600160a01b031690600160f81b900460ff1684565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461056957604051630636a15760e11b815260040160405180910390fd5b60005461ffff600160d81b9091048116908216811061059b5760405163139816ff60e31b815260040160405180910390fd5b6000805461ffff60d81b1916600160d81b61ffff8581169182029290921790925560408051918416825260208201929092527fac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a910160405180910390a15050565b600054600160f01b900460ff166106265760405163139816ff60e31b815260040160405180910390fd5b600080836001600160a01b0316856001600160a01b03161061064957838561064c565b84845b604080516001600160a01b03808516602083015283169181019190915262ffffff861660608201529193509150608001604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000146106d05760405162820f3560e61b815260040160405180910390fd5b6201000080546301000000600160b81b03191663010000006001600160a01b03858116918202929092179092556201000180549184166001600160b81b03199092168217600160a01b62ffffff8816908102919091179091556000805460ff60f01b19169055604080519384526020840192909252908201527f0000000000000000000000000000000000000000000000000000000000000000907fb50ab96cf9f83d6c076a0d2a6e27a65bf1242920ba414829aa618d57d4a263739060600160405180910390a25050505050565b6060806108054285858080602002602001604051908101604052809392919081815260200183836020028082843760009201829052508054600196959450600160a01b810460020b935061ffff600160b81b820481169350600160c81b90910416610bd2565b915091509250929050565b60008054825182916108529160019161ffff600160b81b820481169291600160a01b810460020b918791600160c81b8104821691600160d81b90910416610d1d565b600080546020969096015163ffffffff60b81b19909616600160c81b61ffff9384160261ffff60b81b191617600160b81b93909216929092021762ffffff60a01b1916600160a01b62ffffff90951694909402939093179092555050565b60008060008360020b126108c7578260020b6108cf565b8260020b6000035b9050620d89e88111156108f5576040516315e4079d60e11b815260040160405180910390fd5b60008160011660000361090c57600160801b61091e565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615610952576ffff97272373d413259a46990580e213a0260801c5b6004821615610971576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610990576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b60108216156109af576fffcb9843d60f6159c9db58835c9266440260801c5b60208216156109ce576fff973b41fa98c081472e6896dfb254c00260801c5b60408216156109ed576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610a0c576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610a2c576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610a4c576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610a6c576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610a8c576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610aac576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610acc576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610aec576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610b0c576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610b2d576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610b4d576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610b6c576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610b89576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610baa578060001981610ba657610ba6611954565b0490505b600160201b810615610bbd576001610bc0565b60005b60ff16602082901c0192505050919050565b60608060008361ffff1611610bfa57604051636b93000360e11b815260040160405180910390fd5b865167ffffffffffffffff811115610c1457610c146115d0565b604051908082528060200260200182016040528015610c3d578160200160208202803683370190505b509150865167ffffffffffffffff811115610c5a57610c5a6115d0565b604051908082528060200260200182016040528015610c83578160200160208202803683370190505b50905060005b8751811015610d1057610cba8a8a8a8481518110610ca957610ca961193e565b60200260200101518a8a8a8a610ea5565b848381518110610ccc57610ccc61193e565b60200260200101848481518110610ce557610ce561193e565b6001600160a01b039093166020938402919091019092019190915260069190910b9052600101610c89565b5097509795505050505050565b6000806000898961ffff1661ffff8110610d3957610d3961193e565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff161515606083015290925089169003610da25788859250925050610e99565b8461ffff168461ffff16118015610dc357506001850361ffff168961ffff16145b15610dd057839150610dd4565b8491505b8161ffff168960010161ffff1681610dee57610dee611954565b069250610dfd81898989611054565b8a8461ffff1661ffff8110610e1457610e1461193e565b825191018054602084015160408501516060909501511515600160f81b026001600160f81b036001600160a01b03909616600160581b02959095166affffffffffffffffffffff66ffffffffffffff909216600160201b026affffffffffffffffffffff1990931663ffffffff90951694909417919091171691909117919091179055505b97509795505050505050565b6000808663ffffffff16600003610f4e576000898661ffff1661ffff8110610ecf57610ecf61193e565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff16151560608301529092508a1614610f3a57610f37818a8988611054565b90505b806020015181604001519250925050610e99565b868803600080610f638c8c858c8c8c8c611119565b91509150816000015163ffffffff168363ffffffff1603610f94578160200151826040015194509450505050610e99565b806000015163ffffffff168363ffffffff1603610fc1578060200151816040015194509450505050610e99565b60008260000151826000015103905060008360000151850390508063ffffffff168263ffffffff1660060b856020015185602001510360060b8161100757611007611954565b05028460200151018263ffffffff168263ffffffff1686604001518660400151036001600160a01b0316028161103f5761103f611954565b04856040015101965096505050505050610e99565b604080516080810182526000808252602082018190529181018290526060810191909152600085600001518503905060405180608001604052808663ffffffff1681526020018263ffffffff168660020b0288602001510160060b81526020016000856001600160801b0316116110cc5760016110ce565b845b6001600160801b031663ffffffff60801b608085901b16816110f2576110f2611954565b048860400151016001600160a01b0316815260200160011515815250915050949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152888561ffff1661ffff81106111785761117861193e565b60408051608081018252919092015463ffffffff8116808352600160201b820460060b6020840152600160581b82046001600160a01b031693830193909352600160f81b900460ff161515606082015292506111d690899089611325565b1561120257815163ffffffff888116911614610e9957816111f983898988611054565b91509150610e99565b888361ffff168660010161ffff168161121d5761121d611954565b0661ffff1661ffff81106112335761123361193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529092506112dc57604080516080810182528a5463ffffffff81168252600160201b810460060b6020830152600160581b81046001600160a01b031692820192909252600160f81b90910460ff161515606082015291505b6112eb88836000015189611325565b611308576040516327e8e87560e01b815260040160405180910390fd5b61131589898988876113e8565b9150915097509795505050505050565b60008363ffffffff168363ffffffff161115801561134f57508363ffffffff168263ffffffff1611155b1561136b578163ffffffff168363ffffffff16111590506113e1565b60008463ffffffff168463ffffffff1611611392578363ffffffff16600160201b0161139a565b8363ffffffff165b64ffffffffff16905060008563ffffffff168463ffffffff16116113ca578363ffffffff16600160201b016113d2565b8363ffffffff165b64ffffffffff16909111159150505b9392505050565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260008361ffff168560010161ffff168161144c5761144c611954565b0661ffff169050600060018561ffff16830103905060005b506002818301048961ffff8716828161147f5761147f611954565b0661ffff81106114915761149161193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529095506114f557806001019250611464565b898661ffff16826001018161150c5761150c611954565b0661ffff811061151e5761151e61193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b90910416151560608201528551909450600090611582908b908b611325565b905080801561159b575061159b8a8a8760000151611325565b156115a657506115c3565b806115b6576001820392506115bd565b8160010193505b50611464565b5050509550959350505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611609576116096115d0565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611638576116386115d0565b604052919050565b803562ffffff8116811461165357600080fd5b919050565b600080604080848603121561166c57600080fd5b833567ffffffffffffffff8082111561168457600080fd5b818601915086601f83011261169857600080fd5b81356020828211156116ac576116ac6115d0565b6116ba818360051b0161160f565b828152818101935060069290921b8401810191898311156116da57600080fd5b938101935b8285101561173e5785858b0312156116f75760008081fd5b6116ff6115e6565b853563ffffffff811681146117145760008081fd5b815285830135600281900b811461172b5760008081fd5b81840152845293850193928101926116df565b965061174b888201611640565b955050505050509250929050565b60006020828403121561176b57600080fd5b5035919050565b60006020828403121561178457600080fd5b813561ffff811681146113e157600080fd5b6001600160a01b03811681146117ab57600080fd5b50565b6000806000606084860312156117c357600080fd5b83356117ce81611796565b925060208401356117de81611796565b91506117ec60408501611640565b90509250925092565b6000806020838503121561180857600080fd5b823567ffffffffffffffff8082111561182057600080fd5b818501915085601f83011261183457600080fd5b81358181111561184357600080fd5b8660208260051b850101111561185857600080fd5b60209290920196919550909350505050565b604080825283519082018190526000906020906060840190828701845b828110156118a657815160060b84529284019290840190600101611887565b5050508381038285015284518082528583019183019060005b818110156118e45783516001600160a01b0316835292840192918401916001016118bf565b5090979650505050505050565b60006020828403121561190357600080fd5b81516113e181611796565b600062ffffff80831681810361193457634e487b7160e01b600052601160045260246000fd5b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fdfea264697066735822122048903427db1b98c0cd97b26ab800e55a51c8b5b98cd5a363f22490c0ac241d1b64736f6c634300080f0033a2646970667358221220c1e84aa1e8d7c1251c18a95b48835b3934b1d40ccda3e8d1ccc7bd7d096c898964736f6c634300080f0033", "devdoc": { "kind": "dev", "methods": { @@ -625,23 +625,23 @@ "type": "t_address" }, { - "astId": 15411, + "astId": 15437, "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", "label": "dataReceiver", "offset": 0, "slot": "2", - "type": "t_contract(IDataReceiver)18129" + "type": "t_contract(IDataReceiver)18039" }, { - "astId": 15415, + "astId": 15441, "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", "label": "oracleParameters", "offset": 0, "slot": "3", - "type": "t_struct(OracleParameters)18146_storage" + "type": "t_struct(OracleParameters)18056_storage" }, { - "astId": 15419, + "astId": 15445, "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", "label": "initialCardinality", "offset": 0, @@ -660,17 +660,17 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_contract(IDataReceiver)18129": { + "t_contract(IDataReceiver)18039": { "encoding": "inplace", "label": "contract IDataReceiver", "numberOfBytes": "20" }, - "t_struct(OracleParameters)18146_storage": { + "t_struct(OracleParameters)18056_storage": { "encoding": "inplace", "label": "struct IOracleFactory.OracleParameters", "members": [ { - "astId": 18141, + "astId": 18051, "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", "label": "poolSalt", "offset": 0, @@ -678,7 +678,7 @@ "type": "t_bytes32" }, { - "astId": 18143, + "astId": 18053, "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", "label": "poolNonce", "offset": 0, @@ -686,7 +686,7 @@ "type": "t_uint24" }, { - "astId": 18145, + "astId": 18055, "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", "label": "cardinality", "offset": 3, diff --git a/deployments/optimism/OracleSidechain.json b/deployments/optimism/OracleSidechain.json deleted file mode 100644 index 59f5093..0000000 --- a/deployments/optimism/OracleSidechain.json +++ /dev/null @@ -1,396 +0,0 @@ -{ - "address": "0x6A060BF6579318c15138160Ee1f1d225fcC9D409", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "AI", - "type": "error" - }, - { - "inputs": [], - "name": "I", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidPool", - "type": "error" - }, - { - "inputs": [], - "name": "OLD", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyDataReceiver", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyFactory", - "type": "error" - }, - { - "inputs": [], - "name": "T", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "_observationCardinalityNextOld", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint16", - "name": "_observationCardinalityNextNew", - "type": "uint16" - } - ], - "name": "IncreaseObservationCardinalityNext", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "_poolSalt", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "_token0", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "_token1", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint24", - "name": "_fee", - "type": "uint24" - } - ], - "name": "PoolInfoInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "", - "type": "address" - }, - { - "indexed": false, - "internalType": "int256", - "name": "", - "type": "int256" - }, - { - "indexed": false, - "internalType": "int256", - "name": "", - "type": "int256" - }, - { - "indexed": false, - "internalType": "uint160", - "name": "_sqrtPriceX96", - "type": "uint160" - }, - { - "indexed": false, - "internalType": "uint128", - "name": "", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "int24", - "name": "_tick", - "type": "int24" - } - ], - "name": "Swap", - "type": "event" - }, - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "contract IOracleFactory", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "fee", - "outputs": [ - { - "internalType": "uint24", - "name": "", - "type": "uint24" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_observationCardinalityNext", - "type": "uint16" - } - ], - "name": "increaseObservationCardinalityNext", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_tokenA", - "type": "address" - }, - { - "internalType": "address", - "name": "_tokenB", - "type": "address" - }, - { - "internalType": "uint24", - "name": "_fee", - "type": "uint24" - } - ], - "name": "initializePoolInfo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "observations", - "outputs": [ - { - "internalType": "uint32", - "name": "blockTimestamp", - "type": "uint32" - }, - { - "internalType": "int56", - "name": "tickCumulative", - "type": "int56" - }, - { - "internalType": "uint160", - "name": "secondsPerLiquidityCumulativeX128", - "type": "uint160" - }, - { - "internalType": "bool", - "name": "initialized", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32[]", - "name": "_secondsAgos", - "type": "uint32[]" - } - ], - "name": "observe", - "outputs": [ - { - "internalType": "int56[]", - "name": "_tickCumulatives", - "type": "int56[]" - }, - { - "internalType": "uint160[]", - "name": "_secondsPerLiquidityCumulativeX128s", - "type": "uint160[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "poolNonce", - "outputs": [ - { - "internalType": "uint24", - "name": "", - "type": "uint24" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "poolSalt", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "slot0", - "outputs": [ - { - "internalType": "uint160", - "name": "sqrtPriceX96", - "type": "uint160" - }, - { - "internalType": "int24", - "name": "tick", - "type": "int24" - }, - { - "internalType": "uint16", - "name": "observationIndex", - "type": "uint16" - }, - { - "internalType": "uint16", - "name": "observationCardinality", - "type": "uint16" - }, - { - "internalType": "uint16", - "name": "observationCardinalityNext", - "type": "uint16" - }, - { - "internalType": "uint8", - "name": "feeProtocol", - "type": "uint8" - }, - { - "internalType": "bool", - "name": "unlocked", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token0", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token1", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint32", - "name": "blockTimestamp", - "type": "uint32" - }, - { - "internalType": "int24", - "name": "tick", - "type": "int24" - } - ], - "internalType": "struct IOracleSidechain.ObservationData[]", - "name": "_observationsData", - "type": "tuple[]" - }, - { - "internalType": "uint24", - "name": "_poolNonce", - "type": "uint24" - } - ], - "name": "write", - "outputs": [ - { - "internalType": "bool", - "name": "_written", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "numDeployments": 11 -} \ No newline at end of file diff --git a/deployments/optimism/solcInputs/1a064550c306047de745b0aa850ace2a.json b/deployments/optimism/solcInputs/1a064550c306047de745b0aa850ace2a.json deleted file mode 100644 index a8053ba..0000000 --- a/deployments/optimism/solcInputs/1a064550c306047de745b0aa850ace2a.json +++ /dev/null @@ -1,281 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "solidity/contracts/DataFeed.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {PipelineManagement, Governable} from './peripherals/PipelineManagement.sol';\nimport {IDataFeed, IDataFeedStrategy, IUniswapV3Pool, IConnextSenderAdapter, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeed.sol';\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\n\n/// @title The DataFeed contract\n/// @notice Queries UniV3Pools, stores history proofs on chain, handles data broadcast\ncontract DataFeed is IDataFeed, PipelineManagement {\n /// @inheritdoc IDataFeed\n IDataFeedStrategy public strategy;\n\n /// @inheritdoc IDataFeed\n uint32 public minLastOracleDelta;\n\n /// @inheritdoc IDataFeed\n mapping(bytes32 => PoolState) public lastPoolStateObserved;\n\n mapping(bytes32 => bool) internal _observedKeccak;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(\n address _governor,\n IDataFeedStrategy _strategy,\n uint32 _minLastOracleDelta\n ) Governable(_governor) {\n _setStrategy(_strategy);\n _setMinLastOracleDelta(_minLastOracleDelta);\n }\n\n /// @inheritdoc IDataFeed\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external payable validatePipeline(_chainId, _poolSalt, _poolNonce) {\n (uint32 _destinationDomainId, address _dataReceiver) = validateSenderAdapter(_bridgeSenderAdapter, _chainId);\n\n {\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _poolNonce, _observationsData));\n if (!_observedKeccak[_resultingKeccak]) revert UnknownHash();\n }\n\n _bridgeSenderAdapter.bridgeObservations{value: msg.value}(_dataReceiver, _destinationDomainId, _observationsData, _poolSalt, _poolNonce);\n emit DataBroadcast(_poolSalt, _poolNonce, _chainId, _dataReceiver, _bridgeSenderAdapter);\n }\n\n /// @inheritdoc IDataFeed\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external onlyStrategy validatePool(_poolSalt) {\n IOracleSidechain.ObservationData[] memory _observationsData;\n PoolState memory _lastPoolStateObserved = lastPoolStateObserved[_poolSalt];\n\n {\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _tickCumulatives, ) = _pool.observe(_secondsAgos);\n\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _secondsAgo;\n int56 _tickCumulative;\n int24 _arithmeticMeanTick;\n uint256 _secondsAgosLength = _secondsAgos.length;\n uint256 _i;\n\n // If first fetched observation\n if (_lastPoolStateObserved.blockTimestamp == 0) {\n if (_secondsAgosLength == 1) revert InvalidSecondsAgos();\n // Initializes timestamp and cumulative with first item\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength - 1);\n _secondsAgo = _secondsAgos[0];\n _tickCumulative = _tickCumulatives[0];\n // Skips first loop iteration\n // Cannot not calculate twap (there is no last tickCumulative)\n unchecked {\n ++_i;\n }\n } else {\n // Initializes timestamp and cumulative with cache\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength);\n _secondsAgo = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n _tickCumulative = _lastPoolStateObserved.tickCumulative;\n }\n\n uint32 _delta;\n int56 _tickCumulativesDelta;\n uint256 _observationsDataIndex;\n\n for (; _i < _secondsAgosLength; ) {\n // Twap is calculated using the last recorded tickCumulative and time\n _tickCumulativesDelta = _tickCumulatives[_i] - _tickCumulative;\n _delta = _secondsAgo - _secondsAgos[_i];\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n\n // Stores blockTimestamp and tick in observations array\n _observationsData[_observationsDataIndex++] = IOracleSidechain.ObservationData({\n blockTimestamp: _secondsNow - _secondsAgo,\n tick: _arithmeticMeanTick\n });\n\n // Updates state for next iteration calculation\n _secondsAgo = _secondsAgos[_i];\n _tickCumulative = _tickCumulatives[_i];\n\n unchecked {\n ++_i;\n }\n }\n\n if (_delta < minLastOracleDelta) revert InsufficientDelta();\n\n _lastPoolStateObserved = PoolState({\n poolNonce: _lastPoolStateObserved.poolNonce + 1,\n blockTimestamp: _secondsNow - _secondsAgo,\n tickCumulative: _tickCumulative,\n arithmeticMeanTick: _arithmeticMeanTick\n });\n }\n\n // Stores last pool state in the contract cache\n lastPoolStateObserved[_poolSalt] = _lastPoolStateObserved;\n\n // Whitelists keccak256 to be broadcast to other chains\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData));\n _observedKeccak[_resultingKeccak] = true;\n\n // Emits event with data to be read off-chain and used as broadcast input parameters\n emit PoolObserved(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData);\n }\n\n /// @inheritdoc IDataFeed\n function setStrategy(IDataFeedStrategy _strategy) external onlyGovernor {\n _setStrategy(_strategy);\n }\n\n /// @inheritdoc IDataFeed\n function setMinLastOracleDelta(uint32 _minLastOracleDelta) external onlyGovernor {\n _setMinLastOracleDelta(_minLastOracleDelta);\n }\n\n /// @inheritdoc IDataFeed\n function getPoolNonce(bytes32 _poolSalt) public view override(IDataFeed, PipelineManagement) returns (uint24 _poolNonce) {\n PoolState memory _lastPoolStateObserved = lastPoolStateObserved[_poolSalt];\n return _lastPoolStateObserved.poolNonce;\n }\n\n function _setStrategy(IDataFeedStrategy _strategy) private {\n if (address(_strategy) == address(0)) revert ZeroAddress();\n\n strategy = _strategy;\n emit StrategySet(_strategy);\n }\n\n function _setMinLastOracleDelta(uint32 _minLastOracleDelta) private {\n if (_minLastOracleDelta == 0) revert ZeroAmount();\n\n minLastOracleDelta = _minLastOracleDelta;\n emit MinLastOracleDeltaSet(_minLastOracleDelta);\n }\n\n modifier onlyStrategy() {\n if (msg.sender != address(strategy)) revert OnlyStrategy();\n _;\n }\n}\n" - }, - "solidity/contracts/peripherals/PipelineManagement.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {IPipelineManagement, IBridgeSenderAdapter} from '../../interfaces/peripherals/IPipelineManagement.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\n\nabstract contract PipelineManagement is IPipelineManagement, Governable {\n using EnumerableSet for EnumerableSet.Bytes32Set;\n using EnumerableSet for EnumerableSet.UintSet;\n\n EnumerableSet.Bytes32Set private _whitelistedPools;\n\n EnumerableSet.UintSet private _whitelistedChains;\n\n /// @inheritdoc IPipelineManagement\n mapping(uint32 => mapping(bytes32 => uint24)) public whitelistedNonces;\n\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => bool) public whitelistedAdapters;\n\n // adapter => chainId => destinationDomain\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => uint32)) public destinationDomainIds;\n\n // adapter => destinationDomainId => dataReceiver\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => address)) public receivers;\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external onlyGovernor {\n _whitelistPipeline(_chainId, _poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external onlyGovernor {\n uint256 _chainIdsLength = _chainIds.length;\n if (_chainIdsLength != _poolSalts.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _chainIdsLength; ++_i) {\n _whitelistPipeline(_chainIds[_i], _poolSalts[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _whitelistAdapter(_bridgeSenderAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external onlyGovernor {\n _setDestinationDomainId(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _chainIds,\n uint32[] calldata _destinationDomainIds\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _chainIds.length || _bridgeSenderAdapterLength != _destinationDomainIds.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setDestinationDomainId(_bridgeSenderAdapters[_i], _chainIds[_i], _destinationDomainIds[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external onlyGovernor {\n _setReceiver(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _destinationDomainIds.length || _bridgeSenderAdapterLength != _dataReceivers.length)\n revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setReceiver(_bridgeSenderAdapters[_i], _destinationDomainIds[_i], _dataReceivers[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistedPools() external view returns (bytes32[] memory) {\n return _whitelistedPools.values();\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistedChains() external view returns (uint256[] memory) {\n return _whitelistedChains.values();\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return _whitelistedPools.contains(_poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return whitelistedNonces[_chainId][_poolSalt] != 0;\n }\n\n function getPoolNonce(bytes32 _poolSalt) public view virtual returns (uint24 _poolNonce);\n\n /// @inheritdoc IPipelineManagement\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n public\n view\n returns (uint32 _destinationDomainId, address _dataReceiver)\n {\n if (!whitelistedAdapters[_bridgeSenderAdapter]) revert UnallowedAdapter();\n\n _destinationDomainId = destinationDomainIds[_bridgeSenderAdapter][_chainId];\n if (_destinationDomainId == 0) revert DestinationDomainIdNotSet();\n\n _dataReceiver = receivers[_bridgeSenderAdapter][_destinationDomainId];\n if (_dataReceiver == address(0)) revert ReceiverNotSet();\n }\n\n function _whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) internal {\n if (whitelistedNonces[_chainId][_poolSalt] != 0) revert AlreadyAllowedPipeline();\n\n uint24 _whitelistedNonce = getPoolNonce(_poolSalt) + 1;\n whitelistedNonces[_chainId][_poolSalt] = _whitelistedNonce;\n _whitelistedPools.add(_poolSalt);\n _whitelistedChains.add(_chainId);\n emit PipelineWhitelisted(_chainId, _poolSalt, _whitelistedNonce);\n }\n\n function _whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_bridgeSenderAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n function _setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) internal {\n destinationDomainIds[_bridgeSenderAdapter][_chainId] = _destinationDomainId;\n emit DestinationDomainIdSet(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n function _setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) internal {\n receivers[_bridgeSenderAdapter][_destinationDomainId] = _dataReceiver;\n emit ReceiverSet(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n modifier validatePool(bytes32 _poolSalt) {\n if (!_whitelistedPools.contains(_poolSalt)) revert UnallowedPool();\n _;\n }\n\n modifier validatePipeline(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) {\n uint24 _whitelistedNonce = whitelistedNonces[_chainId][_poolSalt];\n if (_whitelistedNonce == 0) revert UnallowedPipeline();\n if (_whitelistedNonce > _poolNonce) revert WrongNonce();\n _;\n }\n}\n" - }, - "solidity/interfaces/IDataFeed.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IPipelineManagement} from './peripherals/IPipelineManagement.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IConnextSenderAdapter} from './bridges/IConnextSenderAdapter.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IDataFeed is IPipelineManagement {\n // STRUCTS\n\n struct PoolState {\n uint24 poolNonce; // Nonce of the last observation\n uint32 blockTimestamp; // Last observed timestamp\n int56 tickCumulative; // Pool's tickCumulative at last observed timestamp\n int24 arithmeticMeanTick; // Last calculated twap\n }\n\n // STATE VARIABLES\n\n /// @return _strategy Address of the contract allowed to trigger an oracle update\n /// @dev The Strategy should define when and with which timestamps the pool should be read\n function strategy() external view returns (IDataFeedStrategy _strategy);\n\n /// @return _minLastOracleDelta Minimum timestamp delta between latest oracle observations\n function minLastOracleDelta() external view returns (uint32 _minLastOracleDelta);\n\n /// @notice Tracks the last observed pool state by salt\n /// @param _poolSalt The id of both the oracle and the pool\n /// @return _lastPoolNonceObserved Nonce of the last observation\n /// @return _lastBlockTimestampObserved Last observed timestamp\n /// @return _lastTickCumulativeObserved Pool's tickCumulative at last observed timestamp\n /// @return _lastArithmeticMeanTickObserved Last calculated twap\n function lastPoolStateObserved(bytes32 _poolSalt)\n external\n view\n returns (\n uint24 _lastPoolNonceObserved,\n uint32 _lastBlockTimestampObserved,\n int56 _lastTickCumulativeObserved,\n int24 _lastArithmeticMeanTickObserved\n );\n\n // EVENTS\n\n /// @notice Emitted when a data batch is broadcast\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _dataReceiver Address of the targeted contract receiving the data\n /// @param _chainId Identifier number of the targeted chain\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n event DataBroadcast(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n uint32 _chainId,\n address _dataReceiver,\n IBridgeSenderAdapter _bridgeSenderAdapter\n );\n\n /// @notice Emitted when a data batch is observed\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n /// @param _observationsData Timestamp and tick data of the broadcast nonce\n event PoolObserved(bytes32 indexed _poolSalt, uint24 indexed _poolNonce, IOracleSidechain.ObservationData[] _observationsData);\n\n /// @notice Emitted when the Strategy contract is set\n /// @param _strategy Address of the new Strategy\n event StrategySet(IDataFeedStrategy _strategy);\n\n /// @notice Emitted when minLastOracleDelta is set\n /// @param _minLastOracleDelta New value of minLastOracleDelta\n event MinLastOracleDeltaSet(uint32 _minLastOracleDelta);\n\n // ERRORS\n\n /// @notice Thrown if set of secondsAgos is invalid to update the oracle\n error InvalidSecondsAgos();\n\n /// @notice Thrown if the last oracle delta is less than minLastOracleDelta\n error InsufficientDelta();\n\n /// @notice Thrown if an unknown dataset is being broadcast\n error UnknownHash();\n\n /// @notice Thrown if a contract other than Strategy calls an update\n error OnlyStrategy();\n\n // FUNCTIONS\n\n /// @notice Broadcasts a validated set of datapoints to a bridge adapter\n /// @dev Permisionless, input parameters are validated to ensure being correct\n /// @param _bridgeSenderAdapter Address of the bridge adapter\n /// @param _chainId Identifier of the receiving chain\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _poolNonce Nonce identifier of the dataset\n /// @param _observationsData Array of tuples representing broadcast dataset\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external payable;\n\n /// @notice Triggers an update of the oracle state\n /// @dev Permisioned, callable only by Strategy\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _secondsAgos Set of time periods to consult the pool with\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external;\n\n /// @notice Sets the Strategy address\n /// @dev Permissioned, callable only by governor\n /// @param _strategy Address of the new Strategy\n function setStrategy(IDataFeedStrategy _strategy) external;\n\n /// @notice Sets the minLastOracleDelta value\n /// @dev Permissioned, callable only by governor\n /// @param _minLastOracleDelta New value of minLastOracleDelta\n function setMinLastOracleDelta(uint32 _minLastOracleDelta) external;\n\n /// @return _poolNonce The last observed nonce of the given pool\n function getPoolNonce(bytes32 _poolSalt) external view returns (uint24 _poolNonce);\n}\n" - }, - "@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.8 <0.9.0;\n\n/// @title Provides functions for deriving a UniswapV3Pool address from its factory, tokens and fee\nlibrary Create2Address {\n /// @notice Deterministically computes the pool address given the factory, salt and initCodeHash\n /// @param _factory The Uniswap V3 factory contract address\n /// @param _salt The PoolKey encoded bytes\n /// @param _initCodeHash The Init Code Hash of the target\n /// @return _pool The contract address of the target UniswapV3Pool\n function computeAddress(address _factory, bytes32 _salt, bytes32 _initCodeHash)\n internal\n pure\n returns (address _pool)\n {\n _pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', _factory, _salt, _initCodeHash)))));\n }\n}\n" - }, - "solidity/interfaces/peripherals/IPipelineManagement.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IBridgeSenderAdapter} from '../bridges/IBridgeSenderAdapter.sol';\n\ninterface IPipelineManagement is IGovernable {\n // STATE VARIABLES\n\n /// @notice Gets the whitelisted nonce of a pipeline\n /// @param _chainId Identifier number of the chain\n /// @param _poolSalt Identifier of the pool\n /// @return _whitelistedNonce The nonce of the observation from which the oracle is fed\n function whitelistedNonces(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _whitelistedNonce);\n\n /// @notice Returns whether a bridge sender adapter is whitelisted or not\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @return _isWhitelisted Whether the bridge sender adapter is whitelisted or not\n function whitelistedAdapters(IBridgeSenderAdapter _bridgeSenderAdapter) external view returns (bool _isWhitelisted);\n\n /// @notice Gets the destination domain id\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _chainId Identifier number of the chain\n /// @return _destinationDomainId Domain id of the destination chain\n function destinationDomainIds(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId) external view returns (uint32 _destinationDomainId);\n\n /// @notice Gets the address of the DataReceiver contract\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _destinationDomainId Domain id of the destination chain\n /// @return _dataReceiver Address of the DataReceiver contract\n function receivers(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId) external view returns (address _dataReceiver);\n\n // EVENTS\n\n /// @notice Emitted when a pipeline is whitelisted\n /// @param _chainId Identifier number of the chain\n /// @param _poolSalt Identifier of the pool\n /// @param _whitelistedNonce The nonce of the observation from which the oracle is fed\n event PipelineWhitelisted(uint32 _chainId, bytes32 indexed _poolSalt, uint24 _whitelistedNonce);\n\n /// @notice Emitted when the whitelist status of a bridge sender adapter is updated\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _isWhitelisted Whether the bridge sender adapter is whitelisted or not\n event AdapterWhitelisted(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted);\n\n /// @notice Emitted when a destination domain id is set\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _chainId Identifier number of the chain\n /// @param _destinationDomainId Domain id of the destination chain\n event DestinationDomainIdSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId, uint32 _destinationDomainId);\n\n /// @notice Emitted when a DataReceiver contract is set\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _destinationDomainId Domain id of the destination chain\n /// @param _dataReceiver Address of the DataReceiver contract\n event ReceiverSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId, address _dataReceiver);\n\n // ERRORS\n\n /// @notice Thrown if the pipeline is already whitelisted\n error AlreadyAllowedPipeline();\n\n /// @notice Thrown if the pool is not whitelisted\n error UnallowedPool();\n\n /// @notice Thrown if the pipeline is not whitelisted\n error UnallowedPipeline();\n\n /// @notice Thrown if the nonce is below the whitelisted nonce\n error WrongNonce();\n\n /// @notice Thrown if the bridge sender adapter is not whitelisted\n error UnallowedAdapter();\n\n /// @notice Thrown if the destination domain id is not set\n error DestinationDomainIdNotSet();\n\n /// @notice Thrown if the DataReceiver contract is not set\n error ReceiverNotSet();\n\n // FUNCTIONS\n\n /// @notice Whitelists a pipeline\n /// @param _chainId Identifier number of the chain\n /// @param _poolSalt Identifier of the pool\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external;\n\n /// @notice Whitelists several pipelines\n /// @param _chainIds Identifier number of each chain\n /// @param _poolSalts Identifier of each pool\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external;\n\n /// @notice Whitelists a bridge sender adapter\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _isWhitelisted Whether to whitelist the bridge sender adapter or not\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external;\n\n /// @notice Whitelists several bridge sender adapters\n /// @param _bridgeSenderAdapters Addresses of the bridge sender adapters\n /// @param _isWhitelisted Whether to whitelist each bridge sender adapter or not\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external;\n\n /// @notice Sets a destination domain id\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _chainId Identifier number of the chain\n /// @param _destinationDomainId Domain id of the destination chain\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external;\n\n /// @notice Sets several destination domain ids\n /// @param _bridgeSenderAdapters Addresses of the bridge sender adapters\n /// @param _chainIds Identifier number of each chain\n /// @param _destinationDomainIds Domain id of each destination chain\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _chainIds,\n uint32[] calldata _destinationDomainIds\n ) external;\n\n /// @notice Sets a DataReceiver contract\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _destinationDomainId Domain id of the destination chain\n /// @param _dataReceiver Address of the DataReceiver contract\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external;\n\n /// @notice Sets several DataReceiver contracts\n /// @param _bridgeSenderAdapters Addresses of the bridge sender adapters\n /// @param _destinationDomainIds Domain id of each destination chain\n /// @param _dataReceivers Address of each DataReceiver contract\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external;\n\n /// @notice Gets the salt of each whitelisted pool\n function whitelistedPools() external view returns (bytes32[] memory);\n\n /// @notice Gets the id of each whitelisted chain\n function whitelistedChains() external view returns (uint256[] memory);\n\n /// @notice Returns whether a pool is whitelisted or not\n /// @param _poolSalt Identifier of the pool\n /// @return _isWhitelisted Whether the pool is whitelisted or not\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n /// @notice Returns whether a pipeline is whitelisted or not\n /// @param _chainId Identifier number of the chain\n /// @param _poolSalt Identifier of the pool\n /// @return _isWhitelisted Whether the pipeline is whitelisted or not\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n /// @notice Validates whether a bridge sender adapter is set up for a particular chain\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _chainId Identifier number of the chain\n /// @return _destinationDomainId Domain id of the destination chain\n /// @return _dataReceiver Address of the DataReceiver contract\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n external\n view\n returns (uint32 _destinationDomainId, address _dataReceiver);\n}\n" - }, - "@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '../interfaces/IGovernable.sol';\n\n/// @title Governable contract\n/// @notice Manages the governor role\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public governor;\n\n /// @inheritdoc IGovernable\n address public pendingGovernor;\n\n constructor(address _governor) {\n if (_governor == address(0)) revert ZeroAddress();\n governor = _governor;\n }\n\n /// @inheritdoc IGovernable\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\n _setPendingGovernor(_pendingGovernor);\n }\n\n /// @inheritdoc IGovernable\n function acceptPendingGovernor() external onlyPendingGovernor {\n _acceptPendingGovernor();\n }\n\n function _setPendingGovernor(address _pendingGovernor) internal {\n if (_pendingGovernor == address(0)) revert ZeroAddress();\n pendingGovernor = _pendingGovernor;\n emit PendingGovernorSet(governor, _pendingGovernor);\n }\n\n function _acceptPendingGovernor() internal {\n governor = pendingGovernor;\n delete pendingGovernor;\n emit PendingGovernorAccepted(governor);\n }\n\n /// @notice Functions with this modifier can only be called by governor\n modifier onlyGovernor() {\n if (msg.sender != governor) revert OnlyGovernor();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernor\n modifier onlyPendingGovernor() {\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\n _;\n }\n}\n" - }, - "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 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 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 => 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 return _values(set._inner);\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 on 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" - }, - "solidity/interfaces/bridges/IBridgeSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeSenderAdapter {\n /// @notice Bridges observations across chains\n /// @param _to Address of the target contract to xcall\n /// @param _destinationDomainId Domain id of the destination chain\n /// @param _observationsData Array of tuples representing broadcast dataset\n /// @param _poolSalt Identifier of the pool\n /// @param _poolNonce Nonce identifier of the dataset\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable;\n}\n" - }, - "@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBaseErrors} from './IBaseErrors.sol';\n\n/// @title Governable interface\ninterface IGovernable is IBaseErrors {\n // STATE VARIABLES\n\n /// @return _governor Address of the current governor\n function governor() external view returns (address _governor);\n\n /// @return _pendingGovernor Address of the current pending governor\n function pendingGovernor() external view returns (address _pendingGovernor);\n\n // EVENTS\n\n /// @notice Emitted when a new pending governor is set\n /// @param _governor Address of the current governor\n /// @param _pendingGovernor Address of the proposed next governor\n event PendingGovernorSet(address _governor, address _pendingGovernor);\n\n /// @notice Emitted when a new governor is set\n /// @param _newGovernor Address of the new governor\n event PendingGovernorAccepted(address _newGovernor);\n\n // ERRORS\n\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\n error OnlyGovernor();\n\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\n error OnlyPendingGovernor();\n\n // FUNCTIONS\n\n /// @notice Allows a governor to propose a new governor\n /// @param _pendingGovernor Address of the proposed new governor\n function setPendingGovernor(address _pendingGovernor) external;\n\n /// @notice Allows a proposed governor to accept the governance\n function acceptPendingGovernor() external;\n}\n" - }, - "solidity/interfaces/IOracleSidechain.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleFactory} from './IOracleFactory.sol';\n\ninterface IOracleSidechain {\n // STRUCTS\n\n struct ObservationData {\n uint32 blockTimestamp;\n int24 tick;\n }\n\n // STATE VARIABLES\n\n /// @return _oracleFactory The address of the OracleFactory\n function factory() external view returns (IOracleFactory _oracleFactory);\n\n /// @return _token0 The mainnet address of the Token0 of the oracle\n function token0() external view returns (address _token0);\n\n /// @return _token1 The mainnet address of the Token1 of the oracle\n function token1() external view returns (address _token1);\n\n /// @return _fee The fee identifier of the pool\n function fee() external view returns (uint24 _fee);\n\n /// @return _poolSalt The identifier of both the pool and the oracle\n function poolSalt() external view returns (bytes32 _poolSalt);\n\n /// @return _poolNonce Last recorded nonce of the pool history\n function poolNonce() external view returns (uint24 _poolNonce);\n\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\n /// @return _tick Used to maintain compatibility with Uniswap V3\n /// @return _observationIndex The index of the last oracle observation that was written,\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\n /// @return _unlocked Used to track if a pool information was already verified\n function slot0()\n external\n view\n returns (\n uint160 _sqrtPriceX96,\n int24 _tick,\n uint16 _observationIndex,\n uint16 _observationCardinality,\n uint16 _observationCardinalityNext,\n uint8 _feeProtocol,\n bool _unlocked\n );\n\n /// @notice Returns data about a specific observation index\n /// @param _index The element of the observations array to fetch\n /// @return _blockTimestamp The timestamp of the observation,\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return _initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 _index)\n external\n view\n returns (\n uint32 _blockTimestamp,\n int56 _tickCumulative,\n uint160 _secondsPerLiquidityCumulativeX128,\n bool _initialized\n );\n\n // EVENTS\n\n /// @notice Emitted when the pool information is verified\n /// @param _poolSalt Identifier of the pool and the oracle\n /// @param _token0 The contract address of either token0 or token1\n /// @param _token1 The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\n\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param _tick The log base 1.0001 of price of the pool after the swap\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\n\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\n\n // ERRORS\n\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\n error AI();\n\n /// @notice Thrown if the pool info does not correspond to the pool salt\n error InvalidPool();\n\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\n error OnlyDataReceiver();\n\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\n error OnlyFactory();\n\n // FUNCTIONS\n\n /// @notice Permisionless method to verify token0, token1 and fee\n /// @dev Before verified, token0 and token1 views will return address(0)\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external;\n\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\n\n /// @notice Permisioned method to push a dataset to update\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolNonce Nonce of the observation broadcast\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\n\n /// @notice Permisioned method to increase the cardinalityNext value\n /// @param _observationCardinalityNext The new next length of the observations array\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\n}\n" - }, - "solidity/interfaces/IOracleFactory.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IDataReceiver} from './IDataReceiver.sol';\n\ninterface IOracleFactory is IGovernable {\n // STRUCTS\n\n struct OracleParameters {\n bytes32 poolSalt; // Identifier of the pool and oracle\n uint24 poolNonce; // Initial nonce of the deployed pool\n uint16 cardinality; // Initial cardinality of the deployed pool\n }\n\n // STATE VARIABLES\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /// @return _poolSalt The id of both the oracle and the pool\n /// @return _poolNonce The initial nonce of the pool data\n /// @return _cardinality The size of the observations memory storage\n function oracleParameters()\n external\n view\n returns (\n bytes32 _poolSalt,\n uint24 _poolNonce,\n uint16 _cardinality\n );\n\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function initialCardinality() external view returns (uint16 _initialCardinality);\n\n // EVENTS\n\n /// @notice Emitted when a new oracle is deployed\n /// @param _poolSalt The id of both the oracle and the pool\n /// @param _oracle The address of the deployed oracle\n /// @param _initialNonce The initial nonce of the pool data\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\n\n /// @notice Emitted when a new DataReceiver is set\n /// @param _dataReceiver The address of the new DataReceiver\n event DataReceiverSet(IDataReceiver _dataReceiver);\n\n /// @notice Emitted when a new initial oracle cardinality is set\n /// @param _initialCardinality The initial length of the observationCardinality array\n event InitialCardinalitySet(uint16 _initialCardinality);\n\n // ERRORS\n\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\n error OnlyDataReceiver();\n\n // FUNCTIONS\n\n /// @notice Deploys a new oracle given an inputted salt\n /// @dev Requires that the salt has not been deployed before\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\n /// @return _oracle The address of the newly deployed oracle\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\n\n /// @notice Allows governor to set a new allowed dataReceiver\n /// @dev Will disallow the previous dataReceiver\n /// @param _dataReceiver The address of the new allowed dataReceiver\n function setDataReceiver(IDataReceiver _dataReceiver) external;\n\n /// @notice Allows governor to set a new initial cardinality for new oracles\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function setInitialCardinality(uint16 _initialCardinality) external;\n\n /// @notice Overrides UniV3Factory getPool mapping\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _oracle The oracle address\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle);\n\n /// @notice Tracks the addresses of the oracle by poolSalt\n /// @param _poolSalt Identifier of both the pool and the oracle\n /// @return _oracle The address (if deployed) of the correspondant oracle\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\n\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _poolSalt Pool salt for inquired parameters\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (bytes32 _poolSalt);\n}\n" - }, - "solidity/interfaces/IDataReceiver.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IOracleFactory} from './IOracleFactory.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\n\ninterface IDataReceiver is IGovernable {\n // STATE VARIABLES\n\n /// @return _oracleFactory The address of the OracleFactory\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\n\n /// @notice Tracks already deployed oracles\n /// @param _poolSalt The identifier of the oracle\n /// @return _deployedOracle The address of the correspondant Oracle\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\n\n /// @notice Tracks the whitelisting of bridge adapters\n /// @param _adapter Address of the bridge adapter to consult\n /// @return _isAllowed Whether a bridge adapter is whitelisted\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\n\n // EVENTS\n\n /// @notice Emitted when a broadcast observation is succesfully processed\n /// @param _poolSalt Identifier of the pool to fetch\n /// @return _poolNonce Nonce of the observation broadcast\n /// @return _observationsData Array of tuples containing the dataset\n /// @return _receiverAdapter Handler of the broadcast\n event ObservationsAdded(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] _observationsData,\n address _receiverAdapter\n );\n\n /// @notice Emitted when a new adapter whitelisting rule is set\n /// @param _adapter Address of the adapter\n /// @param _isAllowed New whitelisting status\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\n\n // ERRORS\n\n /// @notice Thrown when the broadcast nonce is incorrect\n error ObservationsNotWritable();\n\n /// @notice Thrown when a not-whitelisted adapter triggers an update\n error UnallowedAdapter();\n\n // FUNCTIONS\n\n /// @notice Allows whitelisted bridge adapters to push a broadcast\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _poolNonce Nonce of the observation broadcast\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external;\n\n /// @notice Allows governance to set an adapter whitelisted state\n /// @param _receiverAdapter Address of the adapter\n /// @param _isWhitelisted New whitelisting status\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\n\n /// @notice Allows governance to batch set adapters whitelisted state\n /// @param _receiverAdapters Array of addresses of the adapter\n /// @param _isWhitelisted Array of whitelisting status for each address\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\nimport {IDataReceiver} from '../IDataReceiver.sol';\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeReceiverAdapter is IBaseErrors {\n // STATE VARIABLES\n\n /// @notice Gets the address of the DataReceiver contract\n /// @return _dataReceiver Address of the DataReceiver contract\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /* NOTE: callback methods should be here declared */\n}\n" - }, - "@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Thrown if an address is invalid\n error InvalidAddress();\n\n /// @notice Thrown if an amount is invalid\n error InvalidAmount();\n\n /// @notice Thrown if the lengths of a set of lists mismatch\n error LengthMismatch();\n\n /// @notice Thrown if an address is the zero address\n error ZeroAddress();\n\n /// @notice Thrown if an amount is zero\n error ZeroAmount();\n}\n" - }, - "solidity/interfaces/IDataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\n\ninterface IDataFeedStrategy is IGovernable {\n // ENUMS\n\n enum TriggerReason {\n NONE,\n TIME,\n TWAP,\n OLD\n }\n\n // STRUCTS\n\n struct StrategySettings {\n uint32 periodDuration; // Resolution of the oracle, target twap length\n uint32 strategyCooldown; // Time since last update to wait to time-trigger update\n uint24 defaultTwapThreshold; // Default twap difference, in ticks, to twap-trigger update\n uint32 twapLength; // Twap length, in seconds, used for twap-trigger update\n }\n\n // STATE VARIABLES\n\n /// @return _dataFeed The address of the DataFeed contract\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _periodDuration The targetted amount of seconds between pool consultations\n /// @dev Defines the resolution of the oracle, averaging data between consultations\n function periodDuration() external view returns (uint32 _periodDuration);\n\n /// @return _strategyCooldown Time in seconds since last update required to time-trigger an update\n function strategyCooldown() external view returns (uint32 _strategyCooldown);\n\n /// @return _defaultTwapThreshold Default twap difference, in ticks, to twap-trigger an update\n function defaultTwapThreshold() external view returns (uint24 _defaultTwapThreshold);\n\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _twapThreshold Twap difference, in ticks, to twap-trigger an update\n function twapThreshold(bytes32 _poolSalt) external view returns (uint24 _twapThreshold);\n\n /// @return _twapLength The time length, in seconds, used to calculate twap-trigger\n function twapLength() external view returns (uint32 _twapLength);\n\n // EVENTS\n\n /// @notice Emitted when a data fetch is triggered\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier number of the reason that triggered the fetch request\n event StrategicFetch(bytes32 indexed _poolSalt, TriggerReason _reason);\n\n /// @notice Emitted when the owner updates the job cooldown\n /// @param _strategyCooldown The new job cooldown\n event StrategyCooldownSet(uint32 _strategyCooldown);\n\n /// @notice Emitted when the owner updates the job default twap threshold percentage\n /// @param _defaultTwapThreshold The default twap difference threshold used to trigger an update of the oracle\n event DefaultTwapThresholdSet(uint24 _defaultTwapThreshold);\n\n /// @notice Emitted when the owner updates the job twap threshold percentage of a pool\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _twapThreshold The default twap difference threshold used to trigger an update of the oracle\n event TwapThresholdSet(bytes32 _poolSalt, uint24 _twapThreshold);\n\n /// @notice Emitted when the owner updates the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n event TwapLengthSet(uint32 _twapLength);\n\n /// @notice Emitted when the owner updates the job period length\n /// @param _periodDuration The new length of reading resolution periods\n event PeriodDurationSet(uint32 _periodDuration);\n\n // ERRORS\n\n /// @notice Thrown if the tx is not strategic\n error NotStrategic();\n\n /// @notice Thrown if setting breaks strategyCooldown >= twapLength >= periodDuration\n error WrongSetting();\n\n // FUNCTIONS\n\n /// @notice Permisionless, used to update the oracle state\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier of trigger reason (time/twap)\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external;\n\n /// @notice Sets the job cooldown\n /// @param _strategyCooldown The job cooldown to be set\n function setStrategyCooldown(uint32 _strategyCooldown) external;\n\n /// @notice Sets the job default twap threshold percentage\n /// @param _defaultTwapThreshold The default twap difference threshold used to trigger an update of the oracle\n function setDefaultTwapThreshold(uint24 _defaultTwapThreshold) external;\n\n /// @notice Sets the job twap threshold percentage of a pool\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n function setTwapThreshold(bytes32 _poolSalt, uint24 _twapThreshold) external;\n\n /// @notice Sets the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n function setTwapLength(uint32 _twapLength) external;\n\n /// @notice Sets the job period length\n /// @param _periodDuration The new length of reading resolution periods\n function setPeriodDuration(uint32 _periodDuration) external;\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the strategy can be executed\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason);\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the strategy can be executed\n /// @return _isStrategic Whether the tx is strategic or not\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) external view returns (bool _isStrategic);\n\n /// @notice Builds the secondsAgos array with periodDuration between each datapoint\n /// @param _fromSecondsAgo Seconds ago of the timestamp from which to backfill the oracle with\n /// @return _secondsAgos Array of secondsAgo that backfills the history from fromSecondsAgo\n function calculateSecondsAgos(uint32 _fromSecondsAgo) external view returns (uint32[] memory _secondsAgos);\n}\n" - }, - "solidity/interfaces/bridges/IConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeSenderAdapter, IOracleSidechain} from './IBridgeSenderAdapter.sol';\nimport {IDataFeed} from '../IDataFeed.sol';\n\ninterface IConnextSenderAdapter is IBaseErrors, IBridgeSenderAdapter {\n // STATE VARIABLES\n\n /// @notice Gets the address of the DataFeed contract\n /// @return _dataFeed Address of the DataFeed contract\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @notice Gets the ConnextHandler contract on this domain\n /// @return _connext Address of the ConnextHandler contract\n function connext() external view returns (IConnext _connext);\n\n // ERRORS\n\n /// @notice Thrown if the DataFeed contract is not the one calling for bridging observations\n error OnlyDataFeed();\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport {IUniswapV3PoolImmutables} from './pool/IUniswapV3PoolImmutables.sol';\nimport {IUniswapV3PoolState} from './pool/IUniswapV3PoolState.sol';\nimport {IUniswapV3PoolDerivedState} from './pool/IUniswapV3PoolDerivedState.sol';\nimport {IUniswapV3PoolActions} from './pool/IUniswapV3PoolActions.sol';\nimport {IUniswapV3PoolOwnerActions} from './pool/IUniswapV3PoolOwnerActions.sol';\nimport {IUniswapV3PoolErrors} from './pool/IUniswapV3PoolErrors.sol';\nimport {IUniswapV3PoolEvents} from './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolErrors,\n IUniswapV3PoolEvents\n{\n\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolErrors.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Errors emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolErrors {\n error LOK();\n error TLU();\n error TLM();\n error TUM();\n error AI();\n error M0();\n error M1();\n error AS();\n error IIA();\n error L();\n error F0();\n error F1();\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// @return tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// @return observationIndex The index of the last oracle observation that was written,\n /// @return observationCardinality The current maximum number of observations stored in the pool,\n /// @return observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n /// @return The liquidity at the current price of the pool\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper\n /// @return liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// @return feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// @return feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// @return tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// @return secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// @return secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// @return initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return liquidity The amount of liquidity in the position,\n /// @return feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// @return feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// @return tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// @return tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// @return tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {ExecuteArgs, TransferInfo, TokenId, DestinationTransferStatus} from \"../libraries/LibConnextStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {SwapUtils} from \"../libraries/SwapUtils.sol\";\n\nimport {IStableSwap} from \"./IStableSwap.sol\";\n\nimport {IDiamondCut} from \"./IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\ninterface IConnext is IDiamondLoupe, IDiamondCut {\n // TokenFacet\n function canonicalToAdopted(bytes32 _key) external view returns (address);\n\n function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\n\n function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\n\n function canonicalToRepresentation(bytes32 _key) external view returns (address);\n\n function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\n\n function representationToCanonical(address _adopted) external view returns (TokenId memory);\n\n function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\n\n function approvedAssets(bytes32 _key) external view returns (bool);\n\n function approvedAssets(TokenId calldata _canonical) external view returns (bool);\n\n function adoptedToLocalPools(bytes32 _key) external view returns (IStableSwap);\n\n function adoptedToLocalPools(TokenId calldata _canonical) external view returns (IStableSwap);\n\n function getTokenId(address _candidate) external view returns (TokenId memory);\n\n function setupAsset(\n TokenId calldata _canonical,\n uint8 _canonicalDecimals,\n string memory _representationName,\n string memory _representationSymbol,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function setupAssetWithDeployedRepresentation(\n TokenId calldata _canonical,\n address _representation,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\n\n function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\n\n function removeAssetId(\n bytes32 _key,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function removeAssetId(\n TokenId calldata _canonical,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function updateDetails(\n TokenId calldata _canonical,\n string memory _name,\n string memory _symbol\n ) external;\n\n // BaseConnextFacet\n\n // BridgeFacet\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\n\n function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\n\n function remote(uint32 _domain) external view returns (address);\n\n function domain() external view returns (uint256);\n\n function nonce() external view returns (uint256);\n\n function approvedSequencers(address _sequencer) external view returns (bool);\n\n function xAppConnectionManager() external view returns (address);\n\n function addConnextion(uint32 _domain, address _connext) external;\n\n function addSequencer(address _sequencer) external;\n\n function removeSequencer(address _sequencer) external;\n\n function xcall(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function xcallIntoLocal(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\n\n function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\n\n function bumpTransfer(bytes32 _transferId) external payable;\n\n function setXAppConnectionManager(address _xAppConnectionManager) external;\n\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n function enrollCustom(\n uint32 _domain,\n bytes32 _id,\n address _custom\n ) external;\n\n // InboxFacet\n\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external;\n\n // ProposedOwnableFacet\n\n function owner() external view returns (address);\n\n function routerWhitelistRemoved() external view returns (bool);\n\n function assetWhitelistRemoved() external view returns (bool);\n\n function proposed() external view returns (address);\n\n function proposedTimestamp() external view returns (uint256);\n\n function routerWhitelistTimestamp() external view returns (uint256);\n\n function assetWhitelistTimestamp() external view returns (uint256);\n\n function delay() external view returns (uint256);\n\n function proposeRouterWhitelistRemoval() external;\n\n function removeRouterWhitelist() external;\n\n function proposeAssetWhitelistRemoval() external;\n\n function removeAssetWhitelist() external;\n\n function renounced() external view returns (bool);\n\n function proposeNewOwner(address newlyProposed) external;\n\n function renounceOwnership() external;\n\n function acceptProposedOwner() external;\n\n function pause() external;\n\n function unpause() external;\n\n // RelayerFacet\n function approvedRelayers(address _relayer) external view returns (bool);\n\n function relayerFeeVault() external view returns (address);\n\n function setRelayerFeeVault(address _relayerFeeVault) external;\n\n function addRelayer(address _relayer) external;\n\n function removeRelayer(address _relayer) external;\n\n // RoutersFacet\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\n\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\n\n function getRouterApproval(address _router) external view returns (bool);\n\n function getRouterRecipient(address _router) external view returns (address);\n\n function getRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\n\n function maxRoutersPerTransfer() external view returns (uint256);\n\n function routerBalances(address _router, address _asset) external view returns (uint256);\n\n function getRouterApprovalForPortal(address _router) external view returns (bool);\n\n function setupRouter(\n address router,\n address owner,\n address recipient\n ) external;\n\n function removeRouter(address router) external;\n\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\n\n function setLiquidityFeeNumerator(uint256 _numerator) external;\n\n function approveRouterForPortal(address _router) external;\n\n function unapproveRouterForPortal(address _router) external;\n\n function setRouterRecipient(address router, address recipient) external;\n\n function proposeRouterOwner(address router, address proposed) external;\n\n function acceptProposedRouterOwner(address router) external;\n\n function addRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address _router\n ) external payable;\n\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\n\n function removeRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address payable _to,\n address _router\n ) external;\n\n function removeRouterLiquidity(\n uint256 _amount,\n address _local,\n address payable _to\n ) external;\n\n // PortalFacet\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\n\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\n\n function aavePool() external view returns (address);\n\n function aavePortalFee() external view returns (uint256);\n\n function setAavePool(address _aavePool) external;\n\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\n\n function repayAavePortal(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount,\n uint256 _maxIn\n ) external;\n\n function repayAavePortalFor(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount\n ) external;\n\n // StableSwapFacet\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\n\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\n\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\n\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\n\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\n\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\n\n function calculateSwap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapTokenAmount(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n bool deposit\n ) external view returns (uint256);\n\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) external view returns (uint256);\n\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\n\n function swap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n bytes32 canonicalId,\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n bytes32 canonicalId,\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function addSwapLiquidity(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidity(\n bytes32 canonicalId,\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidityImbalance(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n\n // SwapAdminFacet\n\n function initializeSwap(\n bytes32 _canonicalId,\n IERC20[] memory _pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 _a,\n uint256 _fee,\n uint256 _adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\n\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\n\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\n\n function rampA(\n bytes32 canonicalId,\n uint256 futureA,\n uint256 futureTime\n ) external;\n\n function stopRampA(bytes32 canonicalId) external;\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\nimport {IConnectorManager} from \"../../../messaging/interfaces/IConnectorManager.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n// ============= Enum =============\n\n/// @notice Enum representing address role\n// Returns uint\n// None - 0\n// Router - 1\n// Watcher - 2\n// Admin - 3\nenum Role {\n None,\n Router,\n Watcher,\n Admin\n}\n\n/**\n * @notice Enum representing status of destination transfer\n * @dev Status is only assigned on the destination domain, will always be \"none\" for the\n * origin domains\n * @return uint - Index of value in enum\n */\nenum DestinationTransferStatus {\n None, // 0\n Reconciled, // 1\n Executed, // 2\n Completed // 3 - executed + reconciled\n}\n\n// ============= Structs =============\n\nstruct TokenId {\n uint32 domain;\n bytes32 id;\n}\n\n/**\n * @notice These are the parameters that will remain constant between the\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\n * @property to - The account that receives funds, in the event of a crosschain call,\n * will receive funds if the call fails.\n *\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\n * @param canonicalDomain - The canonical domain of the asset you are bridging\n * @param to - The address you are sending funds (and potentially data) to\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\n * a user takes 1% slippage, this is expressed as 1_000)\n * @param originSender - The msg.sender of the xcall\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\n */\nstruct TransferInfo {\n uint32 originDomain;\n uint32 destinationDomain;\n uint32 canonicalDomain;\n address to;\n address delegate;\n bool receiveLocal;\n bytes callData;\n uint256 slippage;\n address originSender;\n uint256 bridgedAmt;\n uint256 normalizedIn;\n uint256 nonce;\n bytes32 canonicalId;\n}\n\n/**\n * @notice\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\n * @param routers - The routers who you are sending the funds on behalf of.\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\n * for the signed transfer ID.\n * @param sequencer - The sequencer who assigned the router path to this transfer.\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\n * for the path that was signed.\n */\nstruct ExecuteArgs {\n TransferInfo params;\n address[] routers;\n bytes[] routerSignatures;\n address sequencer;\n bytes sequencerSignature;\n}\n\n/**\n * @notice Contains RouterFacet related state\n * @param approvedRouters - Mapping of whitelisted router addresses\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\n * (if configured) or the router itself\n * @param routerOwners - Mapping of router owners\n * If set, can update the routerRecipient\n * @param proposedRouterOwners - Mapping of proposed router owners\n * Must wait timeout to set the\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\n * When accepting a proposed owner, must wait for delay to elapse\n */\nstruct RouterPermissionsManagerInfo {\n mapping(address => bool) approvedRouters;\n mapping(address => bool) approvedForPortalRouters;\n mapping(address => address) routerRecipients;\n mapping(address => address) routerOwners;\n mapping(address => address) proposedRouterOwners;\n mapping(address => uint256) proposedRouterTimestamp;\n}\n\nstruct AppStorage {\n //\n // 0\n bool initialized;\n //\n // Connext\n //\n // 1\n uint256 LIQUIDITY_FEE_NUMERATOR;\n /**\n * @notice The local address that is custodying relayer fees\n */\n // 2\n address relayerFeeVault;\n /**\n * @notice Nonce for the contract, used to keep unique transfer ids.\n * @dev Assigned at first interaction (xcall on origin domain).\n */\n // 3\n uint256 nonce;\n /**\n * @notice The domain this contract exists on.\n * @dev Must match the nomad domain, which is distinct from the \"chainId\".\n */\n // 4\n uint32 domain;\n /**\n * @notice Mapping holding the AMMs for swapping in and out of local assets.\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon).\n * This mapping is keyed on the hash of the canonical id + domain for local asset.\n */\n // 6\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\n /**\n * @notice Mapping of whitelisted assets on same domain as contract.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => bool) approvedAssets;\n /**\n * @notice Mapping of liquidity caps of whitelisted assets. If 0, no cap is enforced.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => uint256) caps;\n /**\n * @notice Mapping of adopted to canonical asset information.\n * @dev If the adopted asset is the native asset, the keyed address will\n * be the wrapped asset address.\n */\n // 8\n mapping(address => TokenId) adoptedToCanonical;\n /**\n * @notice Mapping of representation to canonical asset information.\n */\n // 9\n mapping(address => TokenId) representationToCanonical;\n /**\n * @notice Mapping of hash(canonicalId, canonicalDomain) to adopted asset on this domain.\n * @dev If the adopted asset is the native asset, the stored address will be the\n * wrapped asset address.\n */\n // 10\n mapping(bytes32 => address) canonicalToAdopted;\n /**\n * @notice Mapping of canonical to representation asset information.\n * @dev If the token is of local origin (meaning it was originanlly deployed on this chain),\n * this MUST map to address(0).\n */\n // 11\n mapping(bytes32 => address) canonicalToRepresentation;\n /**\n * @notice Mapping to track transfer status on destination domain\n */\n // 12\n mapping(bytes32 => DestinationTransferStatus) transferStatus;\n /**\n * @notice Mapping holding router address that provided fast liquidity.\n */\n // 13\n mapping(bytes32 => address[]) routedTransfers;\n /**\n * @notice Mapping of router to available balance of an asset.\n * @dev Routers should always store liquidity that they can expect to receive via the bridge on\n * this domain (the nomad local asset).\n */\n // 14\n mapping(address => mapping(address => uint256)) routerBalances;\n /**\n * @notice Mapping of approved relayers\n * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\n */\n // 15\n mapping(address => bool) approvedRelayers;\n /**\n * @notice The max amount of routers a payment can be routed through.\n */\n // 18\n uint256 maxRoutersPerTransfer;\n /**\n * @notice Stores a mapping of transfer id to slippage overrides.\n */\n // 20\n mapping(bytes32 => uint256) slippage;\n /**\n * @notice Stores a mapping of remote routers keyed on domains.\n * @dev Addresses are cast to bytes32.\n * This mapping is required because the Connext now contains the BridgeRouter and must implement\n * the remotes interface.\n */\n // 21\n mapping(uint32 => bytes32) remotes;\n //\n // ProposedOwnable\n //\n // 22\n address _proposed;\n // 23\n uint256 _proposedOwnershipTimestamp;\n // 24\n bool _routerWhitelistRemoved;\n // 25\n uint256 _routerWhitelistTimestamp;\n // 26\n bool _assetWhitelistRemoved;\n // 27\n uint256 _assetWhitelistTimestamp;\n /**\n * @notice Stores a mapping of address to Roles\n * @dev returns uint representing the enum Role value\n */\n // 28\n mapping(address => Role) roles;\n //\n // RouterFacet\n //\n // 29\n RouterPermissionsManagerInfo routerPermissionInfo;\n //\n // ReentrancyGuard\n //\n // 30\n uint256 _status;\n //\n // StableSwap\n //\n /**\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\n * Struct storing data responsible for automatic market maker functionalities. In order to\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\n */\n // 31\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\n /**\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\n */\n // 32\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\n /**\n * @notice Stores whether or not bribing, AMMs, have been paused.\n */\n // 33\n bool _paused;\n //\n // AavePortals\n //\n /**\n * @notice Address of Aave Pool contract.\n */\n // 34\n address aavePool;\n /**\n * @notice Fee percentage numerator for using Portal liquidity.\n * @dev Assumes the same basis points as the liquidity fee.\n */\n // 35\n uint256 aavePortalFeeNumerator;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 36\n mapping(bytes32 => uint256) portalDebt;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 37\n mapping(bytes32 => uint256) portalFeeDebt;\n /**\n * @notice Mapping of approved sequencers\n * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\n * for the fast liquidity route.\n */\n // 38\n mapping(address => bool) approvedSequencers;\n /**\n * @notice Remote connection manager for xapp.\n */\n // 39\n IConnectorManager xAppConnectionManager;\n}\n\nlibrary LibConnextStorage {\n function connextStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= 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 > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20, IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {LPToken} from \"../helpers/LPToken.sol\";\n\nimport {AmplificationUtils} from \"./AmplificationUtils.sol\";\nimport {MathUtils} from \"./MathUtils.sol\";\n\n/**\n * @title SwapUtils library\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\n * Admin functions should be protected within contracts using this library.\n */\nlibrary SwapUtils {\n using SafeERC20 for IERC20;\n using MathUtils for uint256;\n\n /*** EVENTS ***/\n\n event TokenSwap(\n bytes32 indexed key,\n address indexed buyer,\n uint256 tokensSold,\n uint256 tokensBought,\n uint128 soldId,\n uint128 boughtId\n );\n event AddLiquidity(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n bytes32 indexed key,\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\n event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\n\n struct Swap {\n // variables around the ramp management of A,\n // the amplification coefficient * n * (n - 1)\n // see https://www.curve.fi/stableswap-paper.pdf for details\n bytes32 key;\n uint256 initialA;\n uint256 futureA;\n uint256 initialATime;\n uint256 futureATime;\n // fee calculation\n uint256 swapFee;\n uint256 adminFee;\n LPToken lpToken;\n // contract references for all tokens being pooled\n IERC20[] pooledTokens;\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\n uint256[] tokenPrecisionMultipliers;\n // the pool balance of each token, in the token's precision\n // the contract's actual token balance might differ\n uint256[] balances;\n // the admin fee balance of each token, in the token's precision\n uint256[] adminFees;\n }\n\n // Struct storing variables used in calculations in the\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\n struct CalculateWithdrawOneTokenDYInfo {\n uint256 d0;\n uint256 d1;\n uint256 newY;\n uint256 feePerToken;\n uint256 preciseA;\n }\n\n // Struct storing variables used in calculations in the\n // {add,remove}Liquidity functions to avoid stack too deep errors\n struct ManageLiquidityInfo {\n uint256 d0;\n uint256 d1;\n uint256 d2;\n uint256 preciseA;\n LPToken lpToken;\n uint256 totalSupply;\n uint256[] balances;\n uint256[] multipliers;\n }\n\n // the precision all pools tokens will be converted to\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\n\n // the denominator used to calculate admin and LP fees. For example, an\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\n uint256 internal constant FEE_DENOMINATOR = 1e10;\n\n // Max swap fee is 1% or 100bps of each swap\n uint256 internal constant MAX_SWAP_FEE = 1e8;\n\n // Max adminFee is 100% of the swapFee\n // adminFee does not add additional fee on top of swapFee\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\n // users but only on the earnings of LPs\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\n\n // Constant value used as max loop limit\n uint256 internal constant MAX_LOOP_LIMIT = 256;\n\n /*** VIEW & PURE FUNCTIONS ***/\n\n function _getAPrecise(Swap storage self) private view returns (uint256) {\n return AmplificationUtils._getAPrecise(self);\n }\n\n /**\n * @notice Calculate the dy, the amount of selected token that user receives and\n * the fee of withdrawing in one token\n * @param tokenAmount the amount to withdraw in the pool's precision\n * @param tokenIndex which token will be withdrawn\n * @param self Swap struct to read from\n * @return the amount of token user will receive\n */\n function calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) internal view returns (uint256) {\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\n self,\n tokenAmount,\n tokenIndex,\n self.lpToken.totalSupply()\n );\n return availableTokenAmount;\n }\n\n function _calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 totalSupply\n ) private view returns (uint256, uint256) {\n uint256 dy;\n uint256 newY;\n uint256 currentY;\n\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\n\n // dy_0 (without fees)\n // dy, dy_0 - dy\n\n uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\n\n return (dy, dySwapFee);\n }\n\n /**\n * @notice Calculate the dy of withdrawing in one token\n * @param self Swap struct to read from\n * @param tokenIndex which token will be withdrawn\n * @param tokenAmount the amount to withdraw in the pools precision\n * @return the d and the new y after withdrawing one token\n */\n function calculateWithdrawOneTokenDY(\n Swap storage self,\n uint8 tokenIndex,\n uint256 tokenAmount,\n uint256 totalSupply\n )\n internal\n view\n returns (\n uint256,\n uint256,\n uint256\n )\n {\n // Get the current D, then solve the stableswap invariant\n // y_i for D - tokenAmount\n uint256[] memory xp = _xp(self);\n\n require(tokenIndex < xp.length, \"index out of range\");\n\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\n v.preciseA = _getAPrecise(self);\n v.d0 = getD(xp, v.preciseA);\n v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\n\n require(tokenAmount <= xp[tokenIndex], \"exceeds available\");\n\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\n\n uint256[] memory xpReduced = new uint256[](xp.length);\n\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\n for (uint256 i; i < xp.length; ) {\n uint256 xpi = xp[i];\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\n xpReduced[i] =\n xpi -\n ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\n FEE_DENOMINATOR);\n\n unchecked {\n ++i;\n }\n }\n\n uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\n dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\n\n return (dy, v.newY, xp[tokenIndex]);\n }\n\n /**\n * @notice Calculate the price of a token in the pool with given\n * precision-adjusted balances and a particular D.\n *\n * @dev This is accomplished via solving the invariant iteratively.\n * See the StableSwap paper and Curve.fi implementation for further details.\n *\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\n * x_1**2 + b*x_1 = c\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\n *\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\n * @param tokenIndex Index of token we are calculating for.\n * @param xp a precision-adjusted set of pool balances. Array should be\n * the same cardinality as the pool.\n * @param d the stableswap invariant\n * @return the price of the token, in the same precision as in xp\n */\n function getYD(\n uint256 a,\n uint8 tokenIndex,\n uint256[] memory xp,\n uint256 d\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndex < numTokens, \"Token not found\");\n\n uint256 c = d;\n uint256 s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < numTokens; ) {\n if (i != tokenIndex) {\n s += xp[i];\n c = (c * d) / (xp[i] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n }\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\n * as the pool.\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\n * See the StableSwap paper for details\n * @return the invariant, at the precision of the pool\n */\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n uint256 s;\n for (uint256 i; i < numTokens; ) {\n s += xp[i];\n\n unchecked {\n ++i;\n }\n }\n if (s == 0) {\n return 0;\n }\n\n uint256 prevD;\n uint256 d = s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n uint256 dP = d;\n for (uint256 j; j < numTokens; ) {\n dP = (dP * d) / (xp[j] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // dP = dP * D * D * D * ... overflow!\n\n unchecked {\n ++j;\n }\n }\n prevD = d;\n d =\n (((nA * s) / AmplificationUtils.A_PRECISION + dP * numTokens) * d) /\n ((((nA - AmplificationUtils.A_PRECISION) * d) / AmplificationUtils.A_PRECISION + (numTokens + 1) * dP));\n if (d.within1(prevD)) {\n return d;\n }\n\n unchecked {\n ++i;\n }\n }\n\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\n // function which does not rely on D.\n revert(\"D does not converge\");\n }\n\n /**\n * @notice Given a set of balances and precision multipliers, return the\n * precision-adjusted balances.\n *\n * @param balances an array of token balances, in their native precisions.\n * These should generally correspond with pooled tokens.\n *\n * @param precisionMultipliers an array of multipliers, corresponding to\n * the amounts in the balances array. When multiplied together they\n * should yield amounts at the pool's precision.\n *\n * @return an array of amounts \"scaled\" to the pool's precision\n */\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\n internal\n pure\n returns (uint256[] memory)\n {\n uint256 numTokens = balances.length;\n require(numTokens == precisionMultipliers.length, \"mismatch multipliers\");\n uint256[] memory xp = new uint256[](numTokens);\n for (uint256 i; i < numTokens; ) {\n xp[i] = balances[i] * precisionMultipliers[i];\n\n unchecked {\n ++i;\n }\n }\n return xp;\n }\n\n /**\n * @notice Return the precision-adjusted balances of all tokens in the pool\n * @param self Swap struct to read from\n * @return the pool balances \"scaled\" to the pool's precision, allowing\n * them to be more easily compared.\n */\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\n return _xp(self.balances, self.tokenPrecisionMultipliers);\n }\n\n /**\n * @notice Get the virtual price, to help calculate profit\n * @param self Swap struct to read from\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\n */\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\n uint256 d = getD(_xp(self), _getAPrecise(self));\n LPToken lpToken = self.lpToken;\n uint256 supply = lpToken.totalSupply();\n if (supply != 0) {\n return (d * (10**uint256(POOL_PRECISION_DECIMALS))) / supply;\n }\n return 0;\n }\n\n /**\n * @notice Calculate the new balances of the tokens given the indexes of the token\n * that is swapped from (FROM) and the token that is swapped to (TO).\n * This function is used as a helper function to calculate how much TO token\n * the user should receive on swap.\n *\n * @param preciseA precise form of amplification coefficient\n * @param tokenIndexFrom index of FROM token\n * @param tokenIndexTo index of TO token\n * @param x the new total amount of FROM token\n * @param xp balances of the tokens in the pool\n * @return the amount of TO token that should remain in the pool\n */\n function getY(\n uint256 preciseA,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 x,\n uint256[] memory xp\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \"token not found\");\n\n uint256 d = getD(xp, preciseA);\n uint256 c = d;\n uint256 s;\n uint256 nA = numTokens * preciseA;\n\n uint256 _x;\n for (uint256 i; i < numTokens; ) {\n if (i == tokenIndexFrom) {\n _x = x;\n } else if (i != tokenIndexTo) {\n _x = xp[i];\n } else {\n unchecked {\n ++i;\n }\n continue;\n }\n s += _x;\n c = (c * d) / (_x * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n\n // iterative approximation\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get\n */\n function calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) internal view returns (uint256 dy) {\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy.\n * @return dx the number of tokens the user have to transfer + fee\n */\n function calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) internal view returns (uint256 dx) {\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\n * @return dyFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256[] memory balances\n ) internal view returns (uint256 dy, uint256 dyFee) {\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\n dy = xp[tokenIndexTo] - y - 1;\n dyFee = (dy * self.swapFee) / FEE_DENOMINATOR;\n dy = (dy - dyFee) / multipliers[tokenIndexTo];\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\n * @return dxFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256[] memory balances\n ) internal view returns (uint256 dx, uint256 dxFee) {\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n\n uint256 a = _getAPrecise(self);\n uint256 d0 = getD(xp, a);\n\n xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\n dx = x - xp[tokenIndexFrom] + 1;\n dxFee = (dx * self.swapFee) / FEE_DENOMINATOR;\n dx = (dx + dxFee) / multipliers[tokenIndexFrom];\n }\n\n /**\n * @notice A simple method to calculate amount of each underlying\n * tokens that is returned upon burning given amount of\n * LP tokens\n *\n * @param amount the amount of LP tokens that would to be burned on\n * withdrawal\n * @return array of amounts of tokens user will receive\n */\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\n }\n\n function _calculateRemoveLiquidity(\n uint256[] memory balances,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (uint256[] memory) {\n require(amount <= totalSupply, \"exceed total supply\");\n\n uint256 numBalances = balances.length;\n uint256[] memory amounts = new uint256[](numBalances);\n\n for (uint256 i; i < numBalances; ) {\n amounts[i] = (balances[i] * amount) / totalSupply;\n\n unchecked {\n ++i;\n }\n }\n return amounts;\n }\n\n /**\n * @notice A simple method to calculate prices from deposits or\n * withdrawals, excluding fees but including slippage. This is\n * helpful as an input into the various \"min\" parameters on calls\n * to fight front-running\n *\n * @dev This shouldn't be used outside frontends for user estimates.\n *\n * @param self Swap struct to read from\n * @param amounts an array of token amounts to deposit or withdrawal,\n * corresponding to pooledTokens. The amount should be in each\n * pooled token's native precision. If a token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @param deposit whether this is a deposit or a withdrawal\n * @return if deposit was true, total amount of lp token that will be minted and if\n * deposit was false, total amount of lp token that will be burned\n */\n function calculateTokenAmount(\n Swap storage self,\n uint256[] calldata amounts,\n bool deposit\n ) internal view returns (uint256) {\n uint256 a = _getAPrecise(self);\n uint256[] memory balances = self.balances;\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n\n uint256 numBalances = balances.length;\n uint256 d0 = getD(_xp(balances, multipliers), a);\n for (uint256 i; i < numBalances; ) {\n if (deposit) {\n balances[i] = balances[i] + amounts[i];\n } else {\n balances[i] = balances[i] - amounts[i];\n }\n\n unchecked {\n ++i;\n }\n }\n uint256 d1 = getD(_xp(balances, multipliers), a);\n uint256 totalSupply = self.lpToken.totalSupply();\n\n if (deposit) {\n return ((d1 - d0) * totalSupply) / d0;\n } else {\n return ((d0 - d1) * totalSupply) / d0;\n }\n }\n\n /**\n * @notice return accumulated amount of admin fees of the token with given index\n * @param self Swap struct to read from\n * @param index Index of the pooled token\n * @return admin balance in the token's precision\n */\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\n require(index < self.pooledTokens.length, \"index out of range\");\n return self.adminFees[index];\n }\n\n /**\n * @notice internal helper function to calculate fee per token multiplier used in\n * swap fee calculations\n * @param swapFee swap fee for the tokens\n * @param numTokens number of tokens pooled\n */\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\n return (swapFee * numTokens) / ((numTokens - 1) * 4);\n }\n\n /*** STATE MODIFYING FUNCTIONS ***/\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"swap more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"no fee token support\");\n }\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dy the amount of tokens the user wants to buy\n * @param maxDx the max amount the user would like to send.\n * @return amount of token user have to transfer on swap\n */\n function swapOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \">pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"not support fee token\");\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice swap two tokens in the pool internally\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swapInternal(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n require(dx <= self.balances[tokenIndexFrom], \"more than pool balance\");\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice Should get exact amount out of AMM for asset put in\n */\n function swapInternalOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \"more than pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice Add liquidity to the pool\n * @param self Swap struct to read from and write to\n * @param amounts the amounts of each token to add, in their native precision\n * @param minToMint the minimum LP tokens adding this amount of liquidity\n * should mint, otherwise revert. Handy for front-running mitigation\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\n * @return amount of LP token user received\n */\n function addLiquidity(\n Swap storage self,\n uint256[] memory amounts,\n uint256 minToMint\n ) internal returns (uint256) {\n uint256 numTokens = self.pooledTokens.length;\n require(amounts.length == numTokens, \"mismatch pooled tokens\");\n\n // current state\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n if (v.totalSupply != 0) {\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n }\n\n uint256[] memory newBalances = new uint256[](numTokens);\n\n for (uint256 i; i < numTokens; ) {\n require(v.totalSupply != 0 || amounts[i] != 0, \"!supply all tokens\");\n\n // Transfer tokens first to see if a fee was charged on transfer\n if (amounts[i] != 0) {\n IERC20 token = self.pooledTokens[i];\n uint256 beforeBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), amounts[i]);\n\n // Update the amounts[] with actual transfer amount\n amounts[i] = token.balanceOf(address(this)) - beforeBalance;\n }\n\n newBalances[i] = v.balances[i] + amounts[i];\n\n unchecked {\n ++i;\n }\n }\n\n // invariant after change\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n require(v.d1 > v.d0, \"D should increase\");\n\n // updated to reflect fees and calculate the user's LP tokens\n v.d2 = v.d1;\n uint256[] memory fees = new uint256[](numTokens);\n\n if (v.totalSupply != 0) {\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n for (uint256 i; i < numTokens; ) {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / FEE_DENOMINATOR;\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = newBalances[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n newBalances[i] = newBalances[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n } else {\n // the initial depositor doesn't pay fees\n self.balances = newBalances;\n }\n\n uint256 toMint;\n if (v.totalSupply == 0) {\n toMint = v.d1;\n } else {\n toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\n }\n\n require(toMint >= minToMint, \"mint < min\");\n\n // mint the user's LP tokens\n v.lpToken.mint(msg.sender, toMint);\n\n emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\n\n return toMint;\n }\n\n /**\n * @notice Burn LP tokens to remove liquidity from the pool.\n * @dev Liquidity can always be removed, even when the pool is paused.\n * @param self Swap struct to read from and write to\n * @param amount the amount of LP tokens to burn\n * @param minAmounts the minimum amounts of each token in the pool\n * acceptable for this burn. Useful as a front-running mitigation\n * @return amounts of tokens the user received\n */\n function removeLiquidity(\n Swap storage self,\n uint256 amount,\n uint256[] calldata minAmounts\n ) internal returns (uint256[] memory) {\n LPToken lpToken = self.lpToken;\n require(amount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(minAmounts.length == numTokens, \"mismatch poolTokens\");\n\n uint256[] memory balances = self.balances;\n uint256 totalSupply = lpToken.totalSupply();\n\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\n\n uint256 numAmounts = amounts.length;\n for (uint256 i; i < numAmounts; ) {\n require(amounts[i] >= minAmounts[i], \"amounts[i] < minAmounts[i]\");\n self.balances[i] = balances[i] - amounts[i];\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n lpToken.burnFrom(msg.sender, amount);\n\n emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\n\n return amounts;\n }\n\n /**\n * @notice Remove liquidity from the pool all in one token.\n * @param self Swap struct to read from and write to\n * @param tokenAmount the amount of the lp tokens to burn\n * @param tokenIndex the index of the token you want to receive\n * @param minAmount the minimum amount to withdraw, otherwise revert\n * @return amount chosen token that user received\n */\n function removeLiquidityOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount\n ) internal returns (uint256) {\n LPToken lpToken = self.lpToken;\n\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(tokenIndex < numTokens, \"not found\");\n\n uint256 totalSupply = lpToken.totalSupply();\n\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\n\n require(dy >= minAmount, \"dy < minAmount\");\n\n uint256 adminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR;\n self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\n if (adminFee != 0) {\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\n }\n lpToken.burnFrom(msg.sender, tokenAmount);\n self.pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\n\n emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\n\n return dy;\n }\n\n /**\n * @notice Remove liquidity from the pool, weighted differently than the\n * pool's current balances.\n *\n * @param self Swap struct to read from and write to\n * @param amounts how much of each token to withdraw\n * @param maxBurnAmount the max LP token provider is willing to pay to\n * remove liquidity. Useful as a front-running mitigation.\n * @return actual amount of LP tokens burned in the withdrawal\n */\n function removeLiquidityImbalance(\n Swap storage self,\n uint256[] memory amounts,\n uint256 maxBurnAmount\n ) internal returns (uint256) {\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n\n uint256 numTokens = self.pooledTokens.length;\n uint256 numAmounts = amounts.length;\n require(numAmounts == numTokens, \"mismatch pool tokens\");\n\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \">LP.balanceOf\");\n\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n uint256[] memory fees = new uint256[](numTokens);\n {\n uint256[] memory balances1 = new uint256[](numTokens);\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n for (uint256 i; i < numTokens; ) {\n require(v.balances[i] >= amounts[i], \"withdraw more than available\");\n\n unchecked {\n balances1[i] = v.balances[i] - amounts[i];\n ++i;\n }\n }\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\n\n for (uint256 i; i < numTokens; ) {\n {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n uint256 difference = idealBalance.difference(balances1[i]);\n fees[i] = (feePerToken * difference) / FEE_DENOMINATOR;\n }\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = balances1[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n balances1[i] = balances1[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\n }\n uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\n require(tokenAmount != 0, \"!zero amount\");\n tokenAmount = tokenAmount + 1;\n\n require(tokenAmount <= maxBurnAmount, \"tokenAmount > maxBurnAmount\");\n\n v.lpToken.burnFrom(msg.sender, tokenAmount);\n\n for (uint256 i; i < numTokens; ) {\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\n\n return tokenAmount;\n }\n\n /**\n * @notice withdraw all admin fees to a given address\n * @param self Swap struct to withdraw fees from\n * @param to Address to send the fees to\n */\n function withdrawAdminFees(Swap storage self, address to) internal {\n uint256 numTokens = self.pooledTokens.length;\n for (uint256 i; i < numTokens; ) {\n IERC20 token = self.pooledTokens[i];\n uint256 balance = self.adminFees[i];\n if (balance != 0) {\n self.adminFees[i] = 0;\n token.safeTransfer(to, balance);\n }\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Sets the admin fee\n * @dev adminFee cannot be higher than 100% of the swap fee\n * @param self Swap struct to update\n * @param newAdminFee new admin fee to be applied on future transactions\n */\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\n require(newAdminFee <= MAX_ADMIN_FEE, \"too high\");\n self.adminFee = newAdminFee;\n\n emit NewAdminFee(self.key, newAdminFee);\n }\n\n /**\n * @notice update the swap fee\n * @dev fee cannot be higher than 1% of each swap\n * @param self Swap struct to update\n * @param newSwapFee new swap fee to be applied on future transactions\n */\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\n require(newSwapFee <= MAX_SWAP_FEE, \"too high\");\n self.swapFee = newSwapFee;\n\n emit NewSwapFee(self.key, newSwapFee);\n }\n\n /**\n * @notice Check if this stableswap pool exists and is valid (i.e. has been\n * initialized and tokens have been added).\n * @return bool true if this stableswap pool is valid, false if not.\n */\n function exists(Swap storage self) internal view returns (bool) {\n return self.pooledTokens.length != 0;\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n // hash of proposed facets => acceptance time\n mapping(bytes32 => uint256) acceptanceTimes;\n // acceptance delay for upgrading facets\n uint256 acceptanceDelay;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function acceptanceDelay() internal view returns (uint256) {\n return diamondStorage().acceptanceDelay;\n }\n\n function acceptanceTime(bytes32 _key) internal view returns (uint256) {\n return diamondStorage().acceptanceTimes[_key];\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, \"LibDiamond: !contract owner\");\n }\n\n event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n function proposeDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 acceptance = block.timestamp + ds.acceptanceDelay;\n ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\n emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\n }\n\n event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n function rescindDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\n // period or befor the delay elpases\n diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = 0;\n emit DiamondCutRescinded(_diamondCut, _init, _calldata);\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n if (ds.facetAddresses.length != 0) {\n uint256 time = ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\n require(time != 0 && time <= block.timestamp, \"LibDiamond: delay not elapsed\");\n } // Otherwise, this is the first instance of deployment and it can be set automatically\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress != _facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, \"LibDiamondCut: New facet has no code\");\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n require(_calldata.length == 0, \"LibDiamondCut: _init is address(0) but_calldata is not empty\");\n } else {\n require(_calldata.length != 0, \"LibDiamondCut: _calldata is empty but _init is not address(0)\");\n if (_init != address(this)) {\n enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");\n }\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length != 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize != 0, _errorMessage);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IStableSwap {\n /*** EVENTS ***/\n\n // events replicated from SwapUtils to make the ABI easier for dumb\n // clients\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\n event AddLiquidity(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(uint256 newAdminFee);\n event NewSwapFee(uint256 newSwapFee);\n event NewWithdrawFee(uint256 newWithdrawFee);\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n function swap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function getA() external view returns (uint256);\n\n function getToken(uint8 index) external view returns (IERC20);\n\n function getTokenIndex(address tokenAddress) external view returns (uint8);\n\n function getTokenBalance(uint8 index) external view returns (uint256);\n\n function getVirtualPrice() external view returns (uint256);\n\n // min return calculation functions\n function calculateSwap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapOut(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) external view returns (uint256);\n\n function calculateSwapFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountIn\n ) external view returns (uint256);\n\n function calculateSwapOutFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountOut\n ) external view returns (uint256);\n\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\n\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\n external\n view\n returns (uint256 availableTokenAmount);\n\n // state modifying functions\n function initialize(\n IERC20[] memory pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 a,\n uint256 fee,\n uint256 adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function addLiquidity(\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidity(\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeLiquidityOneToken(\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidityImbalance(\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function proposeDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function rescindDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\nimport {IOutbox} from \"./IOutbox.sol\";\n\n/**\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\n * allows an admin to call `setXAppConnectionManager` to update the underlying\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\n *\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\n * will interface with.\n */\ninterface IConnectorManager {\n /**\n * @notice Get the local inbox contract from the xAppConnectionManager\n * @return The local inbox contract\n * @dev The local inbox contract is a SpokeConnector with AMBs, and a\n * Home contract with nomad\n */\n function home() external view returns (IOutbox);\n\n /**\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\n * @return True if _potentialReplica is an enrolled Replica\n */\n function isReplica(address _potentialReplica) external view returns (bool);\n\n /**\n * @notice Get the local domain from the xAppConnectionManager\n * @return The local domain\n */\n function localDomain() external view returns (uint32);\n}\n" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\n/**\n * @notice Interface for all contracts sending messages originating on their\n * current domain.\n *\n * @dev These are the Home.sol interface methods used by the `Router`\n * and exposed via `home()` on the `XAppConnectionClient`\n */\ninterface IOutbox {\n /**\n * @notice Emitted when a new message is added to an outbound message merkle root\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination << 32) & nonce)\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\n * @param committedRoot the latest notarized root submitted in the last signed Update\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes32 committedRoot,\n bytes message\n );\n\n /**\n * @notice Dispatch the message it to the destination domain & recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n * @return bytes32 The leaf added to the tree\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n bytes memory _messageBody\n ) external returns (bytes32);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n/**\n * @title AmplificationUtils library\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\n * This library assumes the struct is fully validated.\n */\nlibrary AmplificationUtils {\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n // Constant values used in ramping A calculations\n uint256 public constant A_PRECISION = 100;\n uint256 public constant MAX_A = 10**6;\n uint256 private constant MAX_A_CHANGE = 2;\n uint256 private constant MIN_RAMP_TIME = 14 days;\n\n /**\n * @notice Return A, the amplification coefficient * n * (n - 1)\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter\n */\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self) / A_PRECISION;\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self);\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n uint256 t1 = self.futureATime; // time when ramp is finished\n uint256 a1 = self.futureA; // final A value when ramp is finished\n\n if (block.timestamp < t1) {\n uint256 t0 = self.initialATime; // time when ramp is started\n uint256 a0 = self.initialA; // initial A value when ramp is started\n if (a1 > a0) {\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\n return a0 + ((a1 - a0) * (block.timestamp - t0)) / (t1 - t0);\n } else {\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\n return a0 - ((a0 - a1) * (block.timestamp - t0)) / (t1 - t0);\n }\n } else {\n return a1;\n }\n }\n\n /**\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\n * Checks if the change is too rapid, and commits the new A value only when it falls under\n * the limit range.\n * @param self Swap struct to update\n * @param futureA_ the new A to ramp towards\n * @param futureTime_ timestamp when the new A should be reached\n */\n function rampA(\n SwapUtils.Swap storage self,\n uint256 futureA_,\n uint256 futureTime_\n ) internal {\n require(block.timestamp >= self.initialATime + 1 days, \"Wait 1 day before starting ramp\");\n require(futureTime_ >= block.timestamp + MIN_RAMP_TIME, \"Insufficient ramp time\");\n require(futureA_ != 0 && futureA_ < MAX_A, \"futureA_ must be > 0 and < MAX_A\");\n\n uint256 initialAPrecise = _getAPrecise(self);\n uint256 futureAPrecise = futureA_ * A_PRECISION;\n\n if (futureAPrecise < initialAPrecise) {\n require(futureAPrecise * MAX_A_CHANGE >= initialAPrecise, \"futureA_ is too small\");\n } else {\n require(futureAPrecise <= initialAPrecise * MAX_A_CHANGE, \"futureA_ is too large\");\n }\n\n self.initialA = initialAPrecise;\n self.futureA = futureAPrecise;\n self.initialATime = block.timestamp;\n self.futureATime = futureTime_;\n\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\n }\n\n /**\n * @notice Stops ramping A immediately. Once this function is called, rampA()\n * cannot be called for another 24 hours\n * @param self Swap struct to update\n */\n function stopRampA(SwapUtils.Swap storage self) internal {\n require(self.futureATime > block.timestamp, \"Ramp is already stopped\");\n\n uint256 currentA = _getAPrecise(self);\n self.initialA = currentA;\n self.futureA = currentA;\n self.initialATime = block.timestamp;\n self.futureATime = block.timestamp;\n\n emit StopRampA(currentA, block.timestamp);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title Liquidity Provider Token\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\n * It is used to represent user's shares when providing liquidity to swap contracts.\n * @dev Only Swap contracts should initialize and own LPToken contracts.\n */\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\n // ============ Upgrade Gap ============\n\n uint256[49] private __GAP; // gap for upgrade safety\n\n // ============ Storage ============\n\n /**\n * @notice Used to enforce proper token dilution\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\n * See audit recommendations here:\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\n * and uniswap v2 implementation here:\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\n */\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\n\n // ============ Initializer ============\n\n /**\n * @notice Initializes this LPToken contract with the given name and symbol\n * @dev The caller of this function will become the owner. A Swap contract should call this\n * in its initializer function.\n * @param name name of this token\n * @param symbol symbol of this token\n */\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\n __Context_init_unchained();\n __ERC20_init_unchained(name, symbol);\n __Ownable_init_unchained();\n return true;\n }\n\n // ============ External functions ============\n\n /**\n * @notice Mints the given amount of LPToken to the recipient.\n * @dev only owner can call this mint function\n * @param recipient address of account to receive the tokens\n * @param amount amount of tokens to mint\n */\n function mint(address recipient, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot mint 0\");\n if (totalSupply() == 0) {\n // NOTE: using the _mint function directly will error because it is going\n // to the 0 address. fix by using the address(1) here instead\n _mint(address(1), MINIMUM_LIQUIDITY);\n }\n _mint(recipient, amount);\n }\n\n /**\n * @notice Burns the given amount of LPToken from provided account\n * @dev only owner can call this burn function\n * @param account address of account from which to burn token\n * @param amount amount of tokens to mint\n */\n function burnFrom(address account, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot burn 0\");\n _burn(account, amount);\n }\n\n // ============ Internal functions ============\n\n /**\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\n * This assumes the owner is set to a Swap contract's address.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20Upgradeable) {\n super._beforeTokenTransfer(from, to, amount);\n require(to != address(this), \"LPToken: cannot send to itself\");\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\n/**\n * @title MathUtils library\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\n * differences between two uint256.\n */\nlibrary MathUtils {\n /**\n * @notice Compares a and b and returns true if the difference between a and b\n * is less than 1 or equal to each other.\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return True if the difference between a and b is less than 1 or equal,\n * otherwise return false\n */\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\n return (difference(a, b) <= 1);\n }\n\n /**\n * @notice Calculates absolute difference between a and b\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return Difference between a and b\n */\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a > b) {\n return a - b;\n }\n return b - a;\n }\n}\n" - }, - "@openzeppelin/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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/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" - }, - "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.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 IERC20Upgradeable {\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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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" - }, - "solidity/for-test/DataReceiverForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {DataReceiver} from '../contracts/DataReceiver.sol';\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\n\ncontract DataReceiverForTest is DataReceiver {\n constructor(address _governor, IOracleFactory _oracleFactory) DataReceiver(_governor, _oracleFactory) {}\n\n function internalAddObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "solidity/contracts/DataReceiver.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\n\n/// @title The DataReceiver contract\n/// @notice Handles reception of broadcast data and delivers it to correspondant oracle\ncontract DataReceiver is IDataReceiver, Governable {\n /// @inheritdoc IDataReceiver\n IOracleFactory public immutable oracleFactory;\n\n /// @inheritdoc IDataReceiver\n mapping(bytes32 => IOracleSidechain) public deployedOracles;\n\n /// @inheritdoc IDataReceiver\n mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters;\n\n constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) {\n if (address(_oracleFactory) == address(0)) revert ZeroAddress();\n oracleFactory = _oracleFactory;\n }\n\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external onlyWhitelistedAdapters {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n // Read, store or deploy oracle given poolSalt\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.getPool(_poolSalt);\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.deployOracle(_poolSalt, _poolNonce);\n }\n deployedOracles[_poolSalt] = _oracle;\n }\n // Try to write observations data into oracle\n if (_oracle.write(_observationsData, _poolNonce)) {\n emit ObservationsAdded(_poolSalt, _poolNonce, _observationsData, msg.sender);\n } else {\n revert ObservationsNotWritable();\n }\n }\n\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_receiverAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IDataReceiver\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _receiverAdapterLength = _receiverAdapters.length;\n if (_receiverAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _receiverAdapterLength; ++_i) {\n _whitelistAdapter(_receiverAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n function _whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_receiverAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_receiverAdapter, _isWhitelisted);\n }\n\n modifier onlyWhitelistedAdapters() {\n if (!whitelistedAdapters[IBridgeReceiverAdapter(msg.sender)]) revert UnallowedAdapter();\n _;\n }\n}\n" - }, - "solidity/contracts/OracleSidechain.sol": { - "content": "//SPDX-License-Identifier: MIT\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\n\n/// @title The SidechainOracle contract\n/// @notice Computes and stores on-chain price data from Mainnet\ncontract OracleSidechain is IOracleSidechain {\n using Oracle for Oracle.Observation[65535];\n\n /// @inheritdoc IOracleSidechain\n IOracleFactory public immutable factory;\n\n struct Slot0 {\n // the current price\n uint160 sqrtPriceX96;\n // the current tick\n int24 tick;\n // the most-recently updated index of the observations array\n uint16 observationIndex;\n // the current maximum number of observations that are being stored\n uint16 observationCardinality;\n // the next maximum number of observations to store, triggered in observations.write\n uint16 observationCardinalityNext;\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\n // represented as an integer denominator (1/x)%\n uint8 feeProtocol;\n // whether the pool is locked\n bool unlocked;\n }\n /// @inheritdoc IOracleSidechain\n Slot0 public slot0;\n\n /// @inheritdoc IOracleSidechain\n Oracle.Observation[65535] public observations;\n\n /// @inheritdoc IOracleSidechain\n bytes32 public immutable poolSalt;\n\n uint24 public poolNonce;\n /// @inheritdoc IOracleSidechain\n address public token0;\n /// @inheritdoc IOracleSidechain\n address public token1;\n /// @inheritdoc IOracleSidechain\n uint24 public fee;\n\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\n function _getBlockTimestamp() internal view virtual returns (uint32) {\n return uint32(block.timestamp); // truncation is desired\n }\n\n constructor() {\n factory = IOracleFactory(msg.sender);\n uint16 _cardinality;\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\n\n slot0 = Slot0({\n sqrtPriceX96: 0,\n tick: 0,\n observationIndex: _cardinality - 1,\n observationCardinality: _cardinality,\n observationCardinalityNext: _cardinality,\n feeProtocol: 0,\n unlocked: true\n });\n }\n\n /// @inheritdoc IOracleSidechain\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external {\n if (!slot0.unlocked) revert AI();\n\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\n\n token0 = _token0;\n token1 = _token1;\n fee = _fee;\n slot0.unlocked = false;\n\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\n }\n\n /// @inheritdoc IOracleSidechain\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\n {\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\n }\n\n /// @inheritdoc IOracleSidechain\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\n if (_poolNonce != poolNonce++) return false;\n\n uint256 _observationsDataLength = _observationsData.length;\n for (uint256 _i; _i < _observationsDataLength; ) {\n _write(_observationsData[_i]);\n unchecked {\n ++_i;\n }\n }\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\n\n // emits UniV3 Swap event topic with minimal data\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\n return true;\n }\n\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\n if (_observationCardinalityNext <= _observationCardinalityNextOld) revert AI();\n slot0.observationCardinalityNext = _observationCardinalityNext;\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\n }\n\n function _write(ObservationData memory _observationData) private {\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\n slot0.observationIndex,\n _observationData.blockTimestamp,\n slot0.tick,\n 0,\n slot0.observationCardinality,\n slot0.observationCardinalityNext\n );\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\n slot0.tick = _observationData.tick;\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\n _;\n }\n\n modifier onlyFactory() {\n if (msg.sender != address(factory)) revert OnlyFactory();\n _;\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/Oracle.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/// @title Oracle\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\n/// @dev Instances of stored oracle data, \"observations\", are collected in the oracle array\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\n/// Observations are overwritten when the full length of the oracle array is populated.\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\nlibrary Oracle {\n error I();\n error OLD();\n\n struct Observation {\n // the block timestamp of the observation\n uint32 blockTimestamp;\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\n int56 tickCumulative;\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\n uint160 secondsPerLiquidityCumulativeX128;\n // whether or not the observation is initialized\n bool initialized;\n }\n\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\n /// @param last The specified observation to be transformed\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @return Observation The newly populated observation\n function transform(\n Observation memory last,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity\n ) private pure returns (Observation memory) {\n unchecked {\n uint32 delta = blockTimestamp - last.blockTimestamp;\n return\n Observation({\n blockTimestamp: blockTimestamp,\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\n initialized: true\n });\n }\n }\n\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\n /// @param self The stored oracle array\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\n /// @return cardinality The number of populated elements in the oracle array\n /// @return cardinalityNext The new length of the oracle array, independent of population\n function initialize(Observation[65535] storage self, uint32 time)\n internal\n returns (uint16 cardinality, uint16 cardinalityNext)\n {\n self[0] = Observation({\n blockTimestamp: time,\n tickCumulative: 0,\n secondsPerLiquidityCumulativeX128: 0,\n initialized: true\n });\n return (1, 1);\n }\n\n /// @notice Writes an oracle observation to the array\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\n /// @param self The stored oracle array\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @param cardinality The number of populated elements in the oracle array\n /// @param cardinalityNext The new length of the oracle array, independent of population\n /// @return indexUpdated The new index of the most recently written element in the oracle array\n /// @return cardinalityUpdated The new cardinality of the oracle array\n function write(\n Observation[65535] storage self,\n uint16 index,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity,\n uint16 cardinality,\n uint16 cardinalityNext\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\n unchecked {\n Observation memory last = self[index];\n\n // early return if we've already written an observation this block\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\n\n // if the conditions are right, we can bump the cardinality\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\n cardinalityUpdated = cardinalityNext;\n } else {\n cardinalityUpdated = cardinality;\n }\n\n indexUpdated = (index + 1) % cardinalityUpdated;\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\n }\n }\n\n /// @notice Prepares the oracle array to store up to `next` observations\n /// @param self The stored oracle array\n /// @param current The current next cardinality of the oracle array\n /// @param next The proposed next cardinality which will be populated in the oracle array\n /// @return next The next cardinality which will be populated in the oracle array\n function grow(\n Observation[65535] storage self,\n uint16 current,\n uint16 next\n ) internal returns (uint16) {\n unchecked {\n if (current <= 0) revert I();\n // no-op if the passed next value isn't greater than the current next value\n if (next <= current) return current;\n // store in each slot to prevent fresh SSTOREs in swaps\n // this data will not be used because the initialized boolean is still false\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\n return next;\n }\n }\n\n /// @notice comparator for 32-bit timestamps\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\n /// @param time A timestamp truncated to 32 bits\n /// @param a A comparison timestamp from which to determine the relative position of `time`\n /// @param b From which to determine the relative position of `time`\n /// @return Whether `a` is chronologically <= `b`\n function lte(\n uint32 time,\n uint32 a,\n uint32 b\n ) private pure returns (bool) {\n unchecked {\n // if there hasn't been overflow, no need to adjust\n if (a <= time && b <= time) return a <= b;\n\n uint256 aAdjusted = a > time ? a : a + 2**32;\n uint256 bAdjusted = b > time ? b : b + 2**32;\n\n return aAdjusted <= bAdjusted;\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\n /// The result may be the same observation, or adjacent observations.\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation recorded before, or at, the target\n /// @return atOrAfter The observation recorded at, or after, the target\n function binarySearch(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n uint16 index,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n uint256 l = (index + 1) % cardinality; // oldest observation\n uint256 r = l + cardinality - 1; // newest observation\n uint256 i;\n while (true) {\n i = (l + r) / 2;\n\n beforeOrAt = self[i % cardinality];\n\n // we've landed on an uninitialized tick, keep searching higher (more recently)\n if (!beforeOrAt.initialized) {\n l = i + 1;\n continue;\n }\n\n atOrAfter = self[(i + 1) % cardinality];\n\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\n\n // check if we've found the answer!\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\n\n if (!targetAtOrAfter) r = i - 1;\n else l = i + 1;\n }\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\n /// @dev Assumes there is at least 1 initialized observation.\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param tick The active tick at the time of the returned or simulated observation\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The total pool liquidity at the time of the call\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\n function getSurroundingObservations(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n // optimistically set before to the newest observation\n beforeOrAt = self[index];\n\n // if the target is chronologically at or after the newest observation, we can early return\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\n if (beforeOrAt.blockTimestamp == target) {\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\n return (beforeOrAt, atOrAfter);\n } else {\n // otherwise, we need to transform\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\n }\n }\n\n // now, set before to the oldest observation\n beforeOrAt = self[(index + 1) % cardinality];\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\n\n // ensure that the target is chronologically at or after the oldest observation\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\n\n // if we've reached this point, we have to binary search\n return binarySearch(self, time, target, index, cardinality);\n }\n }\n\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\n /// at exactly the timestamp between the two observations.\n /// @param self The stored oracle array\n /// @param time The current block timestamp\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\n function observeSingle(\n Observation[65535] storage self,\n uint32 time,\n uint32 secondsAgo,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\n unchecked {\n if (secondsAgo == 0) {\n Observation memory last = self[index];\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\n }\n\n uint32 target = time - secondsAgo;\n\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\n self,\n time,\n target,\n tick,\n index,\n liquidity,\n cardinality\n );\n\n if (target == beforeOrAt.blockTimestamp) {\n // we're at the left boundary\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\n } else if (target == atOrAfter.blockTimestamp) {\n // we're at the right boundary\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\n } else {\n // we're in the middle\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\n return (\n beforeOrAt.tickCumulative +\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\n int56(uint56(targetDelta)),\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\n uint160(\n (uint256(\n atOrAfter.secondsPerLiquidityCumulativeX128 -\n beforeOrAt.secondsPerLiquidityCumulativeX128\n ) * targetDelta) / observationTimeDelta\n )\n );\n }\n }\n }\n\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\n /// @dev Reverts if `secondsAgos` > oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\n function observe(\n Observation[65535] storage self,\n uint32 time,\n uint32[] memory secondsAgos,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\n unchecked {\n if (cardinality <= 0) revert I();\n\n tickCumulatives = new int56[](secondsAgos.length);\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\n for (uint256 i = 0; i < secondsAgos.length; i++) {\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\n self,\n time,\n secondsAgos[i],\n tick,\n index,\n liquidity,\n cardinality\n );\n }\n }\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/TickMath.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n error T();\n error R();\n\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n unchecked {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n if (absTick > uint256(int256(MAX_TICK))) revert T();\n\n uint256 ratio = absTick & 0x1 != 0\n ? 0xfffcb933bd6fad37aa2d162d1a594001\n : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\n /// ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n unchecked {\n // second inequality must be < because the price can never reach the price at the max tick\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n }\n}\n" - }, - "solidity/contracts/bridges/ConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext, IConnextSenderAdapter, IBridgeSenderAdapter, IDataFeed, IOracleSidechain} from '../../interfaces/bridges/IConnextSenderAdapter.sol';\nimport {LibConnextStorage, TransferInfo} from '@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol';\n\ncontract ConnextSenderAdapter is IConnextSenderAdapter {\n /// @inheritdoc IConnextSenderAdapter\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IConnextSenderAdapter\n IConnext public immutable connext;\n\n constructor(IDataFeed _dataFeed, IConnext _connext) {\n if (address(_dataFeed) == address(0) || address(_connext) == address(0)) revert ZeroAddress();\n dataFeed = _dataFeed;\n connext = _connext;\n }\n\n /// @inheritdoc IBridgeSenderAdapter\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable onlyDataFeed {\n bytes memory _callData = abi.encode(_observationsData, _poolSalt, _poolNonce);\n\n connext.xcall{value: msg.value}({\n _destination: _destinationDomainId, // unique identifier for destination domain\n _to: _to, // recipient of funds, where calldata will be executed\n _asset: address(0), // asset being transferred\n _delegate: address(0), // permissioned address to recover in edgecases on destination domain\n _amount: 0, // amount being transferred\n _slippage: 0, // slippage in bps\n _callData: _callData // to be executed on _to on the destination domain\n });\n }\n\n modifier onlyDataFeed() {\n if (msg.sender != address(dataFeed)) revert OnlyDataFeed();\n _;\n }\n}\n" - }, - "solidity/interfaces/bridges/IConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from './IBridgeReceiverAdapter.sol';\n\ninterface IConnextReceiverAdapter is IXReceiver, IBridgeReceiverAdapter {\n // STATE VARIABLES\n\n /// @notice Gets the ConnextHandler contract on this domain\n /// @return _connext Address of the ConnextHandler contract\n function connext() external view returns (IConnext _connext);\n\n /// @notice Gets the DAO that is expected as the xcaller\n /// @return _originContract Address of the xcaller contract\n function source() external view returns (address _originContract);\n\n /// @notice Gets the origin domain id\n /// @return _originDomain The origin domain id\n function originDomain() external view returns (uint32 _originDomain);\n\n // ERRORS\n\n /// @notice Thrown if a caller is not authorized\n error UnauthorizedCaller();\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface IXReceiver {\n function xReceive(\n bytes32 _transferId,\n uint256 _amount,\n address _asset,\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external returns (bytes memory);\n}\n" - }, - "solidity/for-test/ConnextHandlerForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextHandlerForTest {\n uint32 public origin;\n\n constructor() {\n origin = 1111;\n }\n\n function xcall(\n uint32, // _destination, unique identifier for destination domain\n address _to, // recipient of funds, where calldata will be executed\n address, // _asset, asset being transferred\n address, // _delegate, permissioned address to recover in edgecases on destination domain\n uint256, // _amount, amount being transferred\n uint256, // _slippage, slippage in bps\n bytes calldata _callData // to be executed on _to on the destination domain\n ) external payable returns (bytes32) {\n IXReceiver(_to).xReceive({_transferId: 0, _amount: 0, _asset: address(0), _originSender: msg.sender, _origin: origin, _callData: _callData});\n\n return bytes32(abi.encode('random'));\n }\n}\n" - }, - "solidity/interfaces/IStrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IKeep3rJob} from './peripherals/IKeep3rJob.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IStrategyJob is IKeep3rJob {\n // STATE VARIABLES\n\n /// @return _dataFeedStrategy The address of the current DataFeedStrategy\n function dataFeedStrategy() external view returns (IDataFeedStrategy _dataFeedStrategy);\n\n /// @return _dataFeed The address of the DataFeed\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _defaultBridgeSenderAdapter The address of the job bridge sender adapter\n function defaultBridgeSenderAdapter() external view returns (IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n /// @param _chainId The identifier of the chain\n /// @param _poolSalt The identifier of both the pool and oracle\n /// @return _lastPoolNonceBridged Last nonce of the oracle observed\n function lastPoolNonceBridged(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _lastPoolNonceBridged);\n\n // EVENTS\n\n /// @notice Emitted when a new default bridge sender adapter is set\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n event DefaultBridgeSenderAdapterSet(IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n // ERRORS\n\n /// @notice Thrown when the job is not workable\n error NotWorkable();\n\n // FUNCTIONS\n\n /// @notice Calls to send observations in the DataFeed contract\n /// @param _chainId The Ethereum chain identification\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Calls to fetch observations and update the oracle state in the DataFeed contract\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The identifier of the reason to trigger an update\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external;\n\n /// @notice Allows governor to set a new default bridge sender adapter\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external;\n\n /// @notice Returns if the job can be worked\n /// @param _chainId The destination chain ID\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n /// @return _isWorkable Whether the job is workable or not\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external view returns (bool _isWorkable);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the job can be worked\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the job can be worked\n /// @return _isWorkable Whether the job is workable or not\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external view returns (bool _isWorkable);\n}\n" - }, - "solidity/interfaces/peripherals/IKeep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport {IKeep3r} from '@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol';\n\ninterface IKeep3rJob is IGovernable {\n // STATE VARIABLES\n\n /// @return _keep3r Address of the Keep3r contract\n function keep3r() external view returns (IKeep3r _keep3r);\n\n // EVENTS\n\n /// @notice Emitted when a new Keep3r contract is set\n /// @param _keep3r Address of the new Keep3r contract\n event Keep3rSet(IKeep3r _keep3r);\n\n // ERRORS\n\n /// @notice Throws when a keeper fails the validation\n error KeeperNotValid();\n\n // FUNCTIONS\n\n /// @notice Allows governor to set a new Keep3r contract\n /// @param _keep3r Address of the new Keep3r contract\n function setKeep3r(IKeep3r _keep3r) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rParameters.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rKeepers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rJobs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rAccountance.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rRoles.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IBaseErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IGovernable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IDustCollector.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rDisputable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" - }, - "@uniswap/v3-periphery/contracts/libraries/OracleLibrary.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/libraries/FullMath.sol';\nimport '@uniswap/v3-core/contracts/libraries/TickMath.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n/// @title Oracle library\n/// @notice Provides functions to integrate with V3 pool oracle\nlibrary OracleLibrary {\n /// @notice Calculates time-weighted means of tick and liquidity for a given Uniswap V3 pool\n /// @param pool Address of the pool that we want to observe\n /// @param secondsAgo Number of seconds in the past from which to calculate the time-weighted means\n /// @return arithmeticMeanTick The arithmetic mean tick from (block.timestamp - secondsAgo) to block.timestamp\n /// @return harmonicMeanLiquidity The harmonic mean liquidity from (block.timestamp - secondsAgo) to block.timestamp\n function consult(address pool, uint32 secondsAgo)\n internal\n view\n returns (int24 arithmeticMeanTick, uint128 harmonicMeanLiquidity)\n {\n require(secondsAgo != 0, 'BP');\n\n uint32[] memory secondsAgos = new uint32[](2);\n secondsAgos[0] = secondsAgo;\n secondsAgos[1] = 0;\n\n (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) = IUniswapV3Pool(pool)\n .observe(secondsAgos);\n\n int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0];\n uint160 secondsPerLiquidityCumulativesDelta = secondsPerLiquidityCumulativeX128s[1] -\n secondsPerLiquidityCumulativeX128s[0];\n\n arithmeticMeanTick = int24(tickCumulativesDelta / int56(uint56(secondsAgo)));\n // Always round to negative infinity\n if (tickCumulativesDelta < 0 && (tickCumulativesDelta % int56(uint56(secondsAgo)) != 0)) arithmeticMeanTick--;\n\n // We are multiplying here instead of shifting to ensure that harmonicMeanLiquidity doesn't overflow uint128\n uint192 secondsAgoX160 = uint192(secondsAgo) * type(uint160).max;\n harmonicMeanLiquidity = uint128(secondsAgoX160 / (uint192(secondsPerLiquidityCumulativesDelta) << 32));\n }\n\n /// @notice Given a tick and a token amount, calculates the amount of token received in exchange\n /// @param tick Tick value used to calculate the quote\n /// @param baseAmount Amount of token to be converted\n /// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination\n /// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination\n /// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken\n function getQuoteAtTick(\n int24 tick,\n uint128 baseAmount,\n address baseToken,\n address quoteToken\n ) internal pure returns (uint256 quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick);\n\n // Calculate quoteAmount with better precision if it doesn't overflow when multiplied by itself\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n quoteAmount = baseToken < quoteToken\n ? FullMath.mulDiv(ratioX192, baseAmount, 1 << 192)\n : FullMath.mulDiv(1 << 192, baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n quoteAmount = baseToken < quoteToken\n ? FullMath.mulDiv(ratioX128, baseAmount, 1 << 128)\n : FullMath.mulDiv(1 << 128, baseAmount, ratioX128);\n }\n }\n\n /// @notice Given a pool, it returns the number of seconds ago of the oldest stored observation\n /// @param pool Address of Uniswap V3 pool that we want to observe\n /// @return secondsAgo The number of seconds ago of the oldest observation stored for the pool\n function getOldestObservationSecondsAgo(address pool) internal view returns (uint32 secondsAgo) {\n (, , uint16 observationIndex, uint16 observationCardinality, , , ) = IUniswapV3Pool(pool).slot0();\n require(observationCardinality > 0, 'NI');\n\n (uint32 observationTimestamp, , , bool initialized) = IUniswapV3Pool(pool).observations(\n (observationIndex + 1) % observationCardinality\n );\n\n // The next index might not be initialized if the cardinality is in the process of increasing\n // In this case the oldest observation is always in index 0\n if (!initialized) {\n (observationTimestamp, , , ) = IUniswapV3Pool(pool).observations(0);\n }\n\n unchecked {\n secondsAgo = uint32(block.timestamp) - observationTimestamp;\n }\n }\n\n /// @notice Given a pool, it returns the tick value as of the start of the current block\n /// @param pool Address of Uniswap V3 pool\n /// @return The tick that the pool was in at the start of the current block\n function getBlockStartingTickAndLiquidity(address pool) internal view returns (int24, uint128) {\n (, int24 tick, uint16 observationIndex, uint16 observationCardinality, , , ) = IUniswapV3Pool(pool).slot0();\n\n // 2 observations are needed to reliably calculate the block starting tick\n require(observationCardinality > 1, 'NEO');\n\n // If the latest observation occurred in the past, then no tick-changing trades have happened in this block\n // therefore the tick in `slot0` is the same as at the beginning of the current block.\n // We don't need to check if this observation is initialized - it is guaranteed to be.\n (\n uint32 observationTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n\n ) = IUniswapV3Pool(pool).observations(observationIndex);\n if (observationTimestamp != uint32(block.timestamp)) {\n return (tick, IUniswapV3Pool(pool).liquidity());\n }\n\n uint256 prevIndex = (uint256(observationIndex) + observationCardinality - 1) % observationCardinality;\n (\n uint32 prevObservationTimestamp,\n int56 prevTickCumulative,\n uint160 prevSecondsPerLiquidityCumulativeX128,\n bool prevInitialized\n ) = IUniswapV3Pool(pool).observations(prevIndex);\n\n require(prevInitialized, 'ONI');\n\n uint32 delta = observationTimestamp - prevObservationTimestamp;\n tick = int24((tickCumulative - int56(uint56(prevTickCumulative))) / int56(uint56(delta)));\n uint128 liquidity = uint128(\n (uint192(delta) * type(uint160).max) /\n (uint192(secondsPerLiquidityCumulativeX128 - prevSecondsPerLiquidityCumulativeX128) << 32)\n );\n return (tick, liquidity);\n }\n\n /// @notice Information for calculating a weighted arithmetic mean tick\n struct WeightedTickData {\n int24 tick;\n uint128 weight;\n }\n\n /// @notice Given an array of ticks and weights, calculates the weighted arithmetic mean tick\n /// @param weightedTickData An array of ticks and weights\n /// @return weightedArithmeticMeanTick The weighted arithmetic mean tick\n /// @dev Each entry of `weightedTickData` should represents ticks from pools with the same underlying pool tokens. If they do not,\n /// extreme care must be taken to ensure that ticks are comparable (including decimal differences).\n /// @dev Note that the weighted arithmetic mean tick corresponds to the weighted geometric mean price.\n function getWeightedArithmeticMeanTick(WeightedTickData[] memory weightedTickData)\n internal\n pure\n returns (int24 weightedArithmeticMeanTick)\n {\n // Accumulates the sum of products between each tick and its weight\n int256 numerator;\n\n // Accumulates the sum of the weights\n uint256 denominator;\n\n // Products fit in 152 bits, so it would take an array of length ~2**104 to overflow this logic\n for (uint256 i; i < weightedTickData.length; i++) {\n numerator += weightedTickData[i].tick * int256(uint256(weightedTickData[i].weight));\n denominator += weightedTickData[i].weight;\n }\n\n weightedArithmeticMeanTick = int24(numerator / int256(denominator));\n // Always round to negative infinity\n if (numerator < 0 && (numerator % int256(denominator) != 0)) weightedArithmeticMeanTick--;\n }\n\n /// @notice Returns the \"synthetic\" tick which represents the price of the first entry in `tokens` in terms of the last\n /// @dev Useful for calculating relative prices along routes.\n /// @dev There must be one tick for each pairwise set of tokens.\n /// @param tokens The token contract addresses\n /// @param ticks The ticks, representing the price of each token pair in `tokens`\n /// @return syntheticTick The synthetic tick, representing the relative price of the outermost tokens in `tokens`\n function getChainedPrice(address[] memory tokens, int24[] memory ticks)\n internal\n pure\n returns (int256 syntheticTick)\n {\n require(tokens.length - 1 == ticks.length, 'DL');\n for (uint256 i = 1; i <= ticks.length; i++) {\n // check the tokens for address sort order, then accumulate the\n // ticks into the running synthetic tick, ensuring that intermediate tokens \"cancel out\"\n tokens[i - 1] < tokens[i] ? syntheticTick += ticks[i - 1] : syntheticTick -= ticks[i - 1];\n }\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/FullMath.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (0 - denominator) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" - }, - "solidity/for-test/DummyAdapterForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\nimport {IDataReceiver} from '../interfaces/IDataReceiver.sol';\nimport {IBridgeSenderAdapter} from '../interfaces/bridges/IBridgeSenderAdapter.sol';\n\ncontract DummyAdapterForTest is IBridgeSenderAdapter {\n event Create2Hash(bytes32);\n\n bool public ignoreTxs;\n\n constructor() {\n /// @dev Emitted to validate correct calculation of ORACLE_INIT_CODE_HASH\n emit Create2Hash(keccak256(type(OracleSidechain).creationCode));\n }\n\n function bridgeObservations(\n address _to,\n uint32,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable {\n if (!ignoreTxs) {\n IDataReceiver(_to).addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n }\n\n function setIgnoreTxs(bool _ignoreTxs) external {\n ignoreTxs = _ignoreTxs;\n }\n}\n" - }, - "solidity/contracts/OracleFactory.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IOracleFactory, IOracleSidechain, IDataReceiver} from '../interfaces/IOracleFactory.sol';\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\n\n/// @title The OracleFactory contract\n/// @notice Handles the deployment of new OracleSidechains\ncontract OracleFactory is IOracleFactory, Governable {\n /// @inheritdoc IOracleFactory\n IDataReceiver public dataReceiver;\n\n /// @inheritdoc IOracleFactory\n OracleParameters public oracleParameters;\n\n /// @inheritdoc IOracleFactory\n uint16 public initialCardinality = 144;\n\n /// @inheritdoc IOracleFactory\n bytes32 public constant ORACLE_INIT_CODE_HASH = keccak256(type(OracleSidechain).creationCode);\n\n constructor(address _governor, IDataReceiver _dataReceiver) Governable(_governor) {\n _setDataReceiver(_dataReceiver);\n }\n\n /// @inheritdoc IOracleFactory\n function deployOracle(bytes32 _poolSalt, uint24 _initialNonce) external onlyDataReceiver returns (IOracleSidechain _oracle) {\n oracleParameters = OracleParameters({poolSalt: _poolSalt, poolNonce: _initialNonce, cardinality: initialCardinality});\n _oracle = new OracleSidechain{salt: _poolSalt}();\n\n delete oracleParameters;\n emit OracleDeployed(_poolSalt, address(_oracle), _initialNonce);\n }\n\n /// @inheritdoc IOracleFactory\n function setDataReceiver(IDataReceiver _dataReceiver) external onlyGovernor {\n _setDataReceiver(_dataReceiver);\n }\n\n /// @inheritdoc IOracleFactory\n function setInitialCardinality(uint16 _initialCardinality) external onlyGovernor {\n if (_initialCardinality == 0) revert ZeroAmount();\n\n initialCardinality = _initialCardinality;\n emit InitialCardinalitySet(_initialCardinality);\n }\n\n function increaseOracleCardinality(bytes32 _poolSalt, uint16 _observationCardinalityNext) external onlyGovernor {\n IOracleSidechain _oracle = getPool(_poolSalt);\n _oracle.increaseObservationCardinalityNext(_observationCardinalityNext);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle) {\n bytes32 _poolSalt = getPoolSalt(_tokenA, _tokenB, _fee);\n _oracle = getPool(_poolSalt);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(bytes32 _poolSalt) public view returns (IOracleSidechain _oracle) {\n _oracle = IOracleSidechain(Create2Address.computeAddress(address(this), _poolSalt, ORACLE_INIT_CODE_HASH));\n if (address(_oracle).code.length == 0) return IOracleSidechain(address(0));\n }\n\n /// @inheritdoc IOracleFactory\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) public pure returns (bytes32 _poolSalt) {\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n _poolSalt = keccak256(abi.encode(_token0, _token1, _fee));\n }\n\n function _setDataReceiver(IDataReceiver _dataReceiver) private {\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\n\n dataReceiver = _dataReceiver;\n emit DataReceiverSet(_dataReceiver);\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(dataReceiver)) revert OnlyDataReceiver();\n _;\n }\n}\n" - }, - "solidity/contracts/peripherals/Keep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {IKeep3rJob, IKeep3r} from '../../interfaces/peripherals/IKeep3rJob.sol';\n\nabstract contract Keep3rJob is IKeep3rJob, Governable {\n /// @inheritdoc IKeep3rJob\n IKeep3r public keep3r = IKeep3r(0xeb02addCfD8B773A5FFA6B9d1FE99c566f8c44CC);\n\n /// @inheritdoc IKeep3rJob\n function setKeep3r(IKeep3r _keep3r) external onlyGovernor {\n _setKeep3r(_keep3r);\n }\n\n function _setKeep3r(IKeep3r _keep3r) internal {\n keep3r = _keep3r;\n emit Keep3rSet(_keep3r);\n }\n\n function _isValidKeeper(address _keeper) internal virtual {\n if (!keep3r.isKeeper(_keeper)) revert KeeperNotValid();\n }\n\n modifier upkeep() {\n _isValidKeeper(msg.sender);\n _;\n keep3r.worked(msg.sender);\n }\n}\n" - }, - "solidity/for-test/Keep3rJobForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from '../contracts/peripherals/Keep3rJob.sol';\n\ncontract Keep3rJobForTest is Keep3rJob {\n constructor(address _governor) Governable(_governor) {}\n\n function internalIsValidKeeper(address _keeper) external {\n _isValidKeeper(_keeper);\n }\n}\n" - }, - "solidity/contracts/StrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from './peripherals/Keep3rJob.sol';\nimport {IStrategyJob, IDataFeedStrategy, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IStrategyJob.sol';\n\n/// @title The StrategyJob contract\n/// @notice Adds a reward layer for triggering fetch and bridge transactions\ncontract StrategyJob is IStrategyJob, Keep3rJob {\n /// @inheritdoc IStrategyJob\n IDataFeedStrategy public immutable dataFeedStrategy;\n\n /// @inheritdoc IStrategyJob\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IStrategyJob\n IBridgeSenderAdapter public defaultBridgeSenderAdapter;\n\n /// @inheritdoc IStrategyJob\n mapping(uint32 => mapping(bytes32 => uint24)) public lastPoolNonceBridged;\n\n constructor(\n address _governor,\n IDataFeedStrategy _dataFeedStrategy,\n IDataFeed _dataFeed,\n IBridgeSenderAdapter _defaultBridgeSenderAdapter\n ) Governable(_governor) {\n if (address(_dataFeedStrategy) == address(0) || address(_dataFeed) == address(0)) revert ZeroAddress();\n dataFeedStrategy = _dataFeedStrategy;\n dataFeed = _dataFeed;\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external upkeep {\n if (!_workable(_chainId, _poolSalt, _poolNonce)) revert NotWorkable();\n lastPoolNonceBridged[_chainId][_poolSalt] = _poolNonce;\n dataFeed.sendObservations(defaultBridgeSenderAdapter, _chainId, _poolSalt, _poolNonce, _observationsData);\n }\n\n /// @inheritdoc IStrategyJob\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external upkeep {\n dataFeedStrategy.strategicFetchObservations(_poolSalt, _reason);\n }\n\n /// @inheritdoc IStrategyJob\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external onlyGovernor {\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external view returns (bool _isWorkable) {\n uint24 _whitelistedNonce = dataFeed.whitelistedNonces(_chainId, _poolSalt);\n if (_whitelistedNonce != 0 && _whitelistedNonce <= _poolNonce) return _workable(_chainId, _poolSalt, _poolNonce);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external view returns (bool _isWorkable) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt, _reason);\n }\n\n function _workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal view returns (bool _isWorkable) {\n uint24 _lastPoolNonceBridged = lastPoolNonceBridged[_chainId][_poolSalt];\n if (_lastPoolNonceBridged == 0) {\n (uint24 _lastPoolNonceObserved, , , ) = dataFeed.lastPoolStateObserved(_poolSalt);\n return _poolNonce == _lastPoolNonceObserved;\n } else {\n return _poolNonce == ++_lastPoolNonceBridged;\n }\n }\n\n function _setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) private {\n if (address(_defaultBridgeSenderAdapter) == address(0)) revert ZeroAddress();\n\n defaultBridgeSenderAdapter = _defaultBridgeSenderAdapter;\n emit DefaultBridgeSenderAdapterSet(_defaultBridgeSenderAdapter);\n }\n}\n" - }, - "solidity/contracts/DataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport {IDataFeedStrategy, IUniswapV3Pool, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeedStrategy.sol';\nimport {OracleLibrary} from '@uniswap/v3-periphery/contracts/libraries/OracleLibrary.sol';\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\n\n/// @title The DataFeed Strategy contract\n/// @notice Handles when and how a history of a pool should be updated\ncontract DataFeedStrategy is IDataFeedStrategy, Governable {\n /// @inheritdoc IDataFeedStrategy\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public periodDuration;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public strategyCooldown;\n\n /// @inheritdoc IDataFeedStrategy\n uint24 public defaultTwapThreshold;\n\n mapping(bytes32 => uint24) internal _twapThreshold;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public twapLength;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(\n address _governor,\n IDataFeed _dataFeed,\n StrategySettings memory _params\n ) Governable(_governor) {\n if (address(_dataFeed) == address(0)) revert ZeroAddress();\n dataFeed = _dataFeed;\n _setStrategyCooldown(_params.strategyCooldown);\n _setDefaultTwapThreshold(_params.defaultTwapThreshold);\n _setTwapLength(_params.twapLength);\n _setPeriodDuration(_params.periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _fromSecondsAgo;\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n\n if (_reason == TriggerReason.OLD) {\n uint32 _timeSinceLastObservation = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n uint32 _poolOldestSecondsAgo = _getPoolOldestSecondsAgo(_poolSalt);\n if (!(_timeSinceLastObservation > _poolOldestSecondsAgo)) revert NotStrategic();\n _fromSecondsAgo = _poolOldestSecondsAgo;\n } else {\n if (!_isStrategic(_poolSalt, _lastPoolStateObserved, _reason)) revert NotStrategic();\n _fromSecondsAgo = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n }\n\n uint32[] memory _secondsAgos = calculateSecondsAgos(_fromSecondsAgo);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n emit StrategicFetch(_poolSalt, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setStrategyCooldown(uint32 _strategyCooldown) external onlyGovernor {\n _setStrategyCooldown(_strategyCooldown);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setDefaultTwapThreshold(uint24 _defaultTwapThreshold) external onlyGovernor {\n _setDefaultTwapThreshold(_defaultTwapThreshold);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapThreshold(bytes32 _poolSalt, uint24 _poolTwapThreshold) external onlyGovernor {\n _setTwapThreshold(_poolSalt, _poolTwapThreshold);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapLength(uint32 _twapLength) external onlyGovernor {\n _setTwapLength(_twapLength);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setPeriodDuration(uint32 _periodDuration) external onlyGovernor {\n _setPeriodDuration(_periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function twapThreshold(bytes32 _poolSalt) external view returns (uint24 _poolTwapThreshold) {\n _poolTwapThreshold = _twapThreshold[_poolSalt];\n if (_poolTwapThreshold == 0) return defaultTwapThreshold;\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason) {\n if (isStrategic(_poolSalt, TriggerReason.TIME)) return TriggerReason.TIME;\n if (isStrategic(_poolSalt, TriggerReason.TWAP)) return TriggerReason.TWAP;\n if (isStrategic(_poolSalt, TriggerReason.OLD)) return TriggerReason.OLD;\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) public view returns (bool _strategic) {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n return _isStrategic(_poolSalt, _lastPoolStateObserved, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function calculateSecondsAgos(uint32 _fromSecondsAgo) public view returns (uint32[] memory _secondsAgos) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n if (_fromSecondsAgo == _secondsNow) return _initializeSecondsAgos();\n\n uint32 _periodDuration = periodDuration;\n uint32 _maxPeriods = strategyCooldown / _periodDuration;\n uint32 _periods = _fromSecondsAgo / _periodDuration;\n uint32 _remainder = _fromSecondsAgo % _periodDuration;\n uint32 _i;\n\n if (_periods > _maxPeriods) {\n _remainder += (_periods - _maxPeriods) * _periodDuration;\n _periods = _maxPeriods;\n }\n\n if (_remainder != 0) {\n _secondsAgos = new uint32[](++_periods);\n _fromSecondsAgo -= _remainder;\n _secondsAgos[_i++] = _fromSecondsAgo;\n } else {\n _secondsAgos = new uint32[](_periods);\n }\n\n while (_fromSecondsAgo > 0) {\n _fromSecondsAgo -= _periodDuration;\n _secondsAgos[_i++] = _fromSecondsAgo;\n }\n }\n\n function _isStrategic(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n TriggerReason _reason\n ) internal view returns (bool _strategic) {\n if (_reason == TriggerReason.TIME) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n return _secondsNow >= _lastPoolStateObserved.blockTimestamp + strategyCooldown;\n } else if (_reason == TriggerReason.TWAP) {\n return _twapIsOutOfThresholds(_poolSalt, _lastPoolStateObserved);\n } else if (_reason == TriggerReason.OLD) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _timeSinceLastObservation = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n uint32 _poolOldestSecondsAgo = _getPoolOldestSecondsAgo(_poolSalt);\n return _timeSinceLastObservation > _poolOldestSecondsAgo;\n }\n }\n\n function _twapIsOutOfThresholds(bytes32 _poolSalt, IDataFeed.PoolState memory _lastPoolStateObserved)\n internal\n view\n returns (bool _isOutOfThresholds)\n {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _twapLength = twapLength;\n\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[0] = _twapLength;\n _secondsAgos[1] = 0;\n\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _poolTickCumulatives, ) = _pool.observe(_secondsAgos);\n\n int24 _poolArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _poolTickCumulatives[1], _twapLength);\n\n uint32 _oracleDelta = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n int56 _oracleTickCumulative = _lastPoolStateObserved.tickCumulative + int56(_lastPoolStateObserved.arithmeticMeanTick) * int32(_oracleDelta);\n\n int24 _oracleArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _oracleTickCumulative, _twapLength);\n\n uint24 _poolTwapThreshold = _twapThreshold[_poolSalt];\n if (_poolTwapThreshold == 0) _poolTwapThreshold = defaultTwapThreshold;\n\n return\n _poolArithmeticMeanTick > _oracleArithmeticMeanTick + int24(_poolTwapThreshold) ||\n _poolArithmeticMeanTick < _oracleArithmeticMeanTick - int24(_poolTwapThreshold);\n }\n\n function _computeTwap(\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n uint32 _delta\n ) internal pure returns (int24 _arithmeticMeanTick) {\n int56 _tickCumulativesDelta = _tickCumulative2 - _tickCumulative1;\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n }\n\n function _getPoolOldestSecondsAgo(bytes32 _poolSalt) internal view returns (uint32 _poolOldestSecondsAgo) {\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n _poolOldestSecondsAgo = OracleLibrary.getOldestObservationSecondsAgo(address(_pool));\n }\n\n function _initializeSecondsAgos() internal view returns (uint32[] memory _secondsAgos) {\n _secondsAgos = new uint32[](2);\n _secondsAgos[0] = periodDuration;\n _secondsAgos[1] = 0;\n }\n\n function _setStrategyCooldown(uint32 _strategyCooldown) private {\n if (_strategyCooldown < twapLength) revert WrongSetting();\n\n strategyCooldown = _strategyCooldown;\n emit StrategyCooldownSet(_strategyCooldown);\n }\n\n function _setDefaultTwapThreshold(uint24 _defaultTwapThreshold) private {\n if (_defaultTwapThreshold == 0) revert ZeroAmount();\n\n defaultTwapThreshold = _defaultTwapThreshold;\n emit DefaultTwapThresholdSet(_defaultTwapThreshold);\n }\n\n function _setTwapThreshold(bytes32 _poolSalt, uint24 _poolTwapThreshold) private {\n _twapThreshold[_poolSalt] = _poolTwapThreshold;\n emit TwapThresholdSet(_poolSalt, _poolTwapThreshold);\n }\n\n function _setTwapLength(uint32 _twapLength) private {\n if ((_twapLength > strategyCooldown) || (_twapLength < periodDuration)) revert WrongSetting();\n\n twapLength = _twapLength;\n emit TwapLengthSet(_twapLength);\n }\n\n function _setPeriodDuration(uint32 _periodDuration) private {\n if (_periodDuration > twapLength || _periodDuration == 0) revert WrongSetting();\n\n periodDuration = _periodDuration;\n emit PeriodDurationSet(_periodDuration);\n }\n}\n" - }, - "solidity/contracts/bridges/BridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IBridgeReceiverAdapter.sol';\n\nabstract contract BridgeReceiverAdapter is IBridgeReceiverAdapter {\n /// @inheritdoc IBridgeReceiverAdapter\n IDataReceiver public immutable dataReceiver;\n\n constructor(IDataReceiver _dataReceiver) {\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\n dataReceiver = _dataReceiver;\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n dataReceiver.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "solidity/contracts/bridges/ConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {BridgeReceiverAdapter} from './BridgeReceiverAdapter.sol';\nimport {IConnext, IXReceiver, IConnextReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IConnextReceiverAdapter.sol';\n\ncontract ConnextReceiverAdapter is IConnextReceiverAdapter, BridgeReceiverAdapter {\n /// @inheritdoc IConnextReceiverAdapter\n IConnext public immutable connext;\n\n /// @inheritdoc IConnextReceiverAdapter\n address public immutable source;\n\n /// @inheritdoc IConnextReceiverAdapter\n uint32 public immutable originDomain;\n\n constructor(\n IDataReceiver _dataReceiver,\n IConnext _connext,\n address _source,\n uint32 _originDomain\n ) BridgeReceiverAdapter(_dataReceiver) {\n if (address(_connext) == address(0) || _source == address(0)) revert ZeroAddress();\n connext = _connext;\n source = _source;\n originDomain = _originDomain;\n }\n\n /// @inheritdoc IXReceiver\n function xReceive(\n bytes32, // _transferId\n uint256, // _amount\n address, // _asset\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external onlyExecutor(_originSender, _origin) returns (bytes memory) {\n (IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, uint24 _poolNonce) = abi.decode(\n _callData,\n (IOracleSidechain.ObservationData[], bytes32, uint24)\n );\n\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n\n modifier onlyExecutor(address _originSender, uint32 _originDomain) {\n if (msg.sender != address(connext) || _originSender != source || _originDomain != originDomain) revert UnauthorizedCaller();\n _;\n }\n}\n" - }, - "solidity/for-test/UniswapV3Importer.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Factory} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';\nimport {ISwapRouter} from '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';\n\ninterface INFTPositionManager {\n struct MintParams {\n address token0;\n address token1;\n uint24 fee;\n int24 tickLower;\n int24 tickUpper;\n uint256 amount0Desired;\n uint256 amount1Desired;\n uint256 amount0Min;\n uint256 amount1Min;\n address recipient;\n uint256 deadline;\n }\n\n function mint(MintParams calldata _params)\n external\n payable\n returns (\n uint256 _tokenId,\n uint128 _liquidity,\n uint256 _amount0,\n uint256 _amount1\n );\n}\n\n// solhint-disable-next-line no-empty-blocks\ncontract UniswapV3Importer {\n\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title The interface for the Uniswap V3 Factory\n/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees\ninterface IUniswapV3Factory {\n /// @notice Emitted when the owner of the factory is changed\n /// @param oldOwner The owner before the owner was changed\n /// @param newOwner The owner after the owner was changed\n event OwnerChanged(address indexed oldOwner, address indexed newOwner);\n\n /// @notice Emitted when a pool is created\n /// @param token0 The first token of the pool by address sort order\n /// @param token1 The second token of the pool by address sort order\n /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip\n /// @param tickSpacing The minimum number of ticks between initialized ticks\n /// @param pool The address of the created pool\n event PoolCreated(\n address indexed token0,\n address indexed token1,\n uint24 indexed fee,\n int24 tickSpacing,\n address pool\n );\n\n /// @notice Emitted when a new fee amount is enabled for pool creation via the factory\n /// @param fee The enabled fee, denominated in hundredths of a bip\n /// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee\n event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing);\n\n /// @notice Returns the current owner of the factory\n /// @dev Can be changed by the current owner via setOwner\n /// @return The address of the factory owner\n function owner() external view returns (address);\n\n /// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled\n /// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context\n /// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee\n /// @return The tick spacing\n function feeAmountTickSpacing(uint24 fee) external view returns (int24);\n\n /// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist\n /// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order\n /// @param tokenA The contract address of either token0 or token1\n /// @param tokenB The contract address of the other token\n /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip\n /// @return pool The pool address\n function getPool(\n address tokenA,\n address tokenB,\n uint24 fee\n ) external view returns (address pool);\n\n /// @notice Creates a pool for the given two tokens and fee\n /// @param tokenA One of the two tokens in the desired pool\n /// @param tokenB The other of the two tokens in the desired pool\n /// @param fee The desired fee for the pool\n /// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved\n /// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments\n /// are invalid.\n /// @return pool The address of the newly created pool\n function createPool(\n address tokenA,\n address tokenB,\n uint24 fee\n ) external returns (address pool);\n\n /// @notice Updates the owner of the factory\n /// @dev Must be called by the current owner\n /// @param _owner The new owner of the factory\n function setOwner(address _owner) external;\n\n /// @notice Enables a fee amount with the given tickSpacing\n /// @dev Fee amounts may never be removed once enabled\n /// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6)\n /// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount\n function enableFeeAmount(uint24 fee, int24 tickSpacing) external;\n}\n" - }, - "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\npragma abicoder v2;\n\nimport '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface ISwapRouter is IUniswapV3SwapCallback {\n struct ExactInputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactOutputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);\n\n struct ExactOutputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Callback for IUniswapV3PoolActions#swap\n/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface\ninterface IUniswapV3SwapCallback {\n /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n /// @dev In the implementation you must pay the pool tokens owed for the swap.\n /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n function uniswapV3SwapCallback(\n int256 amount0Delta,\n int256 amount1Delta,\n bytes calldata data\n ) external;\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file diff --git a/deployments/optimism/solcInputs/c13a9c9fec104b95e6c1800beae11ff9.json b/deployments/optimism/solcInputs/c13a9c9fec104b95e6c1800beae11ff9.json deleted file mode 100644 index 8670d9a..0000000 --- a/deployments/optimism/solcInputs/c13a9c9fec104b95e6c1800beae11ff9.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "solidity/contracts/DataFeed.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {PipelineManagement, Governable} from './peripherals/PipelineManagement.sol';\nimport {IDataFeed, IDataFeedStrategy, IUniswapV3Pool, IConnextSenderAdapter, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeed.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The DataFeed interface\n/// @notice Queries UniV3Pools, stores history proofs on chain, handles data broadcast\ncontract DataFeed is IDataFeed, PipelineManagement {\n /// @inheritdoc IDataFeed\n IDataFeedStrategy public strategy;\n\n /// @inheritdoc IDataFeed\n mapping(bytes32 => PoolState) public lastPoolStateObserved;\n\n mapping(bytes32 => bool) internal _observedKeccak;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(address _governor, IDataFeedStrategy _strategy) Governable(_governor) {\n _setStrategy(_strategy);\n }\n\n /// @inheritdoc IDataFeed\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external validatePipeline(_chainId, _poolSalt, _poolNonce) {\n (uint32 _destinationDomainId, address _dataReceiver) = validateSenderAdapter(_bridgeSenderAdapter, _chainId);\n\n {\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _poolNonce, _observationsData));\n if (!_observedKeccak[_resultingKeccak]) revert UnknownHash();\n }\n\n _bridgeSenderAdapter.bridgeObservations(_dataReceiver, _destinationDomainId, _observationsData, _poolSalt, _poolNonce);\n emit DataBroadcast(_poolSalt, _poolNonce, _chainId, _dataReceiver, _bridgeSenderAdapter);\n }\n\n /// @inheritdoc IDataFeed\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external onlyStrategy validatePool(_poolSalt) {\n IOracleSidechain.ObservationData[] memory _observationsData;\n PoolState memory _lastPoolStateObserved = lastPoolStateObserved[_poolSalt];\n\n {\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _tickCumulatives, ) = _pool.observe(_secondsAgos);\n\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _secondsAgo;\n int56 _tickCumulative;\n int24 _arithmeticMeanTick;\n uint256 _secondsAgosLength = _secondsAgos.length;\n uint256 _i;\n\n // If first fetched observation\n if (_lastPoolStateObserved.blockTimestamp == 0) {\n if (_secondsAgosLength == 1) revert InvalidSecondsAgos();\n // Initializes timestamp and cumulative with first item\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength - 1);\n _secondsAgo = _secondsAgos[0];\n _tickCumulative = _tickCumulatives[0];\n // Skips first loop iteration\n // Cannot not calculate twap (there is no last tickCumulative)\n unchecked {\n ++_i;\n }\n } else {\n // Initializes timestamp and cumulative with cache\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength);\n _secondsAgo = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n _tickCumulative = _lastPoolStateObserved.tickCumulative;\n }\n\n uint32 _delta;\n int56 _tickCumulativesDelta;\n uint256 _observationsDataIndex;\n\n for (; _i < _secondsAgosLength; ) {\n // Twap is calculated using the last recorded tickCumulative and time\n _tickCumulativesDelta = _tickCumulatives[_i] - _tickCumulative;\n _delta = _secondsAgo - _secondsAgos[_i];\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n\n // Stores blockTimestamp and tick in observations array\n _observationsData[_observationsDataIndex++] = IOracleSidechain.ObservationData({\n blockTimestamp: _secondsNow - _secondsAgo,\n tick: _arithmeticMeanTick\n });\n\n // Updates state for next iteration calculation\n _secondsAgo = _secondsAgos[_i];\n _tickCumulative = _tickCumulatives[_i];\n\n unchecked {\n ++_i;\n }\n }\n\n _lastPoolStateObserved = PoolState({\n poolNonce: _lastPoolStateObserved.poolNonce + 1,\n blockTimestamp: _secondsNow - _secondsAgo,\n tickCumulative: _tickCumulative,\n arithmeticMeanTick: _arithmeticMeanTick\n });\n }\n\n // Stores last pool state in the contract cache\n lastPoolStateObserved[_poolSalt] = _lastPoolStateObserved;\n\n // Whitelists keccak256 to be broadcast to other chains\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData));\n _observedKeccak[_resultingKeccak] = true;\n\n // Emits event with data to be read off-chain and used as broadcast input parameters\n emit PoolObserved(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData);\n }\n\n /// @inheritdoc IDataFeed\n function setStrategy(IDataFeedStrategy _strategy) external onlyGovernor {\n _setStrategy(_strategy);\n }\n\n function _setStrategy(IDataFeedStrategy _strategy) private {\n strategy = _strategy;\n emit StrategySet(_strategy);\n }\n\n modifier onlyStrategy() {\n if (msg.sender != address(strategy)) revert OnlyStrategy();\n _;\n }\n}\n" - }, - "solidity/contracts/peripherals/PipelineManagement.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './Governable.sol';\nimport {IPipelineManagement, IBridgeSenderAdapter} from '../../interfaces/peripherals/IPipelineManagement.sol';\nimport {IDataFeed} from '../../interfaces/IDataFeed.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\n\nabstract contract PipelineManagement is IPipelineManagement, Governable {\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n EnumerableSet.Bytes32Set private _whitelistedPools;\n\n /// @inheritdoc IPipelineManagement\n mapping(uint32 => mapping(bytes32 => uint24)) public whitelistedNonces;\n\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => bool) public whitelistedAdapters;\n\n // adapter => chainId => destinationDomain\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => uint32)) public destinationDomainIds;\n\n // adapter => destinationDomainId => dataReceiver\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => address)) public receivers;\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external onlyGovernor {\n _whitelistPipeline(_chainId, _poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external onlyGovernor {\n uint256 _chainIdsLength = _chainIds.length;\n if (_chainIdsLength != _poolSalts.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _chainIdsLength; ++_i) {\n _whitelistPipeline(_chainIds[_i], _poolSalts[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _whitelistAdapter(_bridgeSenderAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external onlyGovernor {\n _setDestinationDomainId(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _chainIds,\n uint32[] calldata _destinationDomainIds\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _chainIds.length || _bridgeSenderAdapterLength != _destinationDomainIds.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setDestinationDomainId(_bridgeSenderAdapters[_i], _chainIds[_i], _destinationDomainIds[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external onlyGovernor {\n _setReceiver(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _destinationDomainIds.length || _bridgeSenderAdapterLength != _dataReceivers.length)\n revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setReceiver(_bridgeSenderAdapters[_i], _destinationDomainIds[_i], _dataReceivers[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistedPools() external view returns (bytes32[] memory) {\n return _whitelistedPools.values();\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return _whitelistedPools.contains(_poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return whitelistedNonces[_chainId][_poolSalt] != 0;\n }\n\n /// @inheritdoc IPipelineManagement\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n public\n view\n returns (uint32 _destinationDomainId, address _dataReceiver)\n {\n if (!whitelistedAdapters[_bridgeSenderAdapter]) revert UnallowedAdapter();\n\n _destinationDomainId = destinationDomainIds[_bridgeSenderAdapter][_chainId];\n if (_destinationDomainId == 0) revert DestinationDomainIdNotSet();\n\n _dataReceiver = receivers[_bridgeSenderAdapter][_destinationDomainId];\n if (_dataReceiver == address(0)) revert ReceiverNotSet();\n }\n\n function _whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) internal {\n (uint24 _lastPoolNonceObserved, , , ) = IDataFeed(address(this)).lastPoolStateObserved(_poolSalt);\n whitelistedNonces[_chainId][_poolSalt] = _lastPoolNonceObserved + 1;\n _whitelistedPools.add(_poolSalt);\n emit PipelineWhitelisted(_chainId, _poolSalt, _lastPoolNonceObserved + 1);\n }\n\n function _whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_bridgeSenderAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n function _setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) internal {\n destinationDomainIds[_bridgeSenderAdapter][_chainId] = _destinationDomainId;\n emit DestinationDomainIdSet(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n function _setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) internal {\n receivers[_bridgeSenderAdapter][_destinationDomainId] = _dataReceiver;\n emit ReceiverSet(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n modifier validatePool(bytes32 _poolSalt) {\n if (!_whitelistedPools.contains(_poolSalt)) revert UnallowedPool();\n _;\n }\n\n modifier validatePipeline(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) {\n uint24 _whitelistedNonce = whitelistedNonces[_chainId][_poolSalt];\n if (_whitelistedNonce == 0) revert UnallowedPipeline();\n if (_whitelistedNonce > _poolNonce) revert WrongNonce();\n _;\n }\n}\n" - }, - "solidity/interfaces/IDataFeed.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IPipelineManagement} from './peripherals/IPipelineManagement.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IConnextSenderAdapter} from './bridges/IConnextSenderAdapter.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IDataFeed is IPipelineManagement {\n // STRUCTS\n\n struct PoolState {\n uint24 poolNonce; // Nonce of the last observation\n uint32 blockTimestamp; // Last observed timestamp\n int56 tickCumulative; // Pool's tickCumulative at last observed timestamp\n int24 arithmeticMeanTick; // Last calculated twap\n }\n\n // STATE VARIABLES\n\n /// @return _strategy Address of the contract allowed to trigger an oracle update\n /// @dev The strategy should define when and with which timestamps the pool should be read\n function strategy() external view returns (IDataFeedStrategy _strategy);\n\n /// @notice Tracks the last observed pool state by salt\n /// @param _poolSalt The id of both the oracle and the pool\n /// @return _lastPoolNonceObserved Nonce of the last observation\n /// @return _lastBlockTimestampObserved Last observed timestamp\n /// @return _lastTickCumulativeObserved Pool's tickCumulative at last observed timestamp\n /// @return _lastArithmeticMeanTickObserved Last calculated twap\n function lastPoolStateObserved(bytes32 _poolSalt)\n external\n view\n returns (\n uint24 _lastPoolNonceObserved,\n uint32 _lastBlockTimestampObserved,\n int56 _lastTickCumulativeObserved,\n int24 _lastArithmeticMeanTickObserved\n );\n\n // EVENTS\n\n /// @notice Emitted when a data batch is broadcast\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _dataReceiver Address of the targetted contract receiving the data\n /// @param _chainId Identifier number of the targetted chain\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n event DataBroadcast(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n uint32 _chainId,\n address _dataReceiver,\n IBridgeSenderAdapter _bridgeSenderAdapter\n );\n\n /// @notice Emitted when a data batch is observed\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n /// @param _observationsData Timestamp and tick data of the broadcast nonce\n event PoolObserved(bytes32 indexed _poolSalt, uint24 _poolNonce, IOracleSidechain.ObservationData[] _observationsData);\n\n /// @notice Emitted when the Strategy contract is set\n /// @param _strategy Address of the new strategy\n event StrategySet(IDataFeedStrategy _strategy);\n\n // ERRORS\n\n /// @notice Throws if set of secondsAgos is invalid to update the oracle\n error InvalidSecondsAgos();\n\n /// @notice Throws if an unknown dataset is being broadcast\n error UnknownHash();\n\n /// @notice Throws if a contract other than Strategy calls an update\n error OnlyStrategy();\n\n // FUNCTIONS\n\n /// @notice Broadcasts a validated set of datapoints to a bridge adapter\n /// @dev Permisionless, input parameters are validated to ensure being correct\n /// @param _bridgeSenderAdapter Address of the bridge adapter\n /// @param _chainId Identifier of the receiving chain\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _poolNonce Nonce identifier of the dataset\n /// @param _observationsData Array of tuples representing broadcast dataset\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Triggers an update of the oracle state\n /// @dev Permisioned, callable only by Strategy\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _secondsAgos Set of time periods to consult the pool with\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external;\n\n /// @notice Updates the Strategy address\n /// @dev Permisioned, callable only by Governor\n /// @param _strategy Address of the new Strategy\n function setStrategy(IDataFeedStrategy _strategy) external;\n}\n" - }, - "solidity/libraries/Create2Address.sol": { - "content": "//SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.8 <0.9.0;\n\n/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee\nlibrary Create2Address {\n /// @notice Deterministically computes the pool address given the factory, salt and initCodeHash\n /// @param _factory The Uniswap V3 factory contract address\n /// @param _salt The PoolKey encoded bytes\n /// @param _initCodeHash The Init Code Hash of the target\n /// @return _pool The contract address of the target pool/oracle\n function computeAddress(\n address _factory,\n bytes32 _salt,\n bytes32 _initCodeHash\n ) internal pure returns (address _pool) {\n _pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', _factory, _salt, _initCodeHash)))));\n }\n}\n" - }, - "solidity/contracts/peripherals/Governable.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public governor;\n\n /// @inheritdoc IGovernable\n address public pendingGovernor;\n\n constructor(address _governor) {\n if (_governor == address(0)) revert ZeroAddress();\n governor = _governor;\n }\n\n /// @inheritdoc IGovernable\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\n _setPendingGovernor(_pendingGovernor);\n }\n\n /// @inheritdoc IGovernable\n function acceptPendingGovernor() external onlyPendingGovernor {\n _acceptPendingGovernor();\n }\n\n function _setPendingGovernor(address _pendingGovernor) internal {\n if (_pendingGovernor == address(0)) revert ZeroAddress();\n pendingGovernor = _pendingGovernor;\n emit PendingGovernorSet(governor, pendingGovernor);\n }\n\n function _acceptPendingGovernor() internal {\n governor = pendingGovernor;\n pendingGovernor = address(0);\n emit PendingGovernorAccepted(governor);\n }\n\n modifier onlyGovernor() {\n if (msg.sender != governor) revert OnlyGovernor();\n _;\n }\n\n modifier onlyPendingGovernor() {\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\n _;\n }\n}\n" - }, - "solidity/interfaces/peripherals/IPipelineManagement.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './IGovernable.sol';\nimport {IBridgeSenderAdapter} from '../bridges/IBridgeSenderAdapter.sol';\n\ninterface IPipelineManagement is IGovernable {\n // STATE VARIABLES\n\n function whitelistedNonces(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _whitelistedNonce);\n\n function whitelistedAdapters(IBridgeSenderAdapter _bridgeSenderAdapter) external view returns (bool _isWhitelisted);\n\n function destinationDomainIds(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId) external view returns (uint32 _destinationDomainId);\n\n function receivers(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId) external view returns (address _dataReceiver);\n\n // EVENTS\n\n event PipelineWhitelisted(uint32 _chainId, bytes32 indexed _poolSalt, uint24 _whitelistedNonce);\n\n event AdapterWhitelisted(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted);\n\n event DestinationDomainIdSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId, uint32 _destinationDomainId);\n\n event ReceiverSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId, address _dataReceiver);\n\n // ERRORS\n\n error UnallowedPool();\n\n error UnallowedPipeline();\n\n error WrongNonce();\n\n error UnallowedAdapter();\n\n error DestinationDomainIdNotSet();\n\n error ReceiverNotSet();\n\n error LengthMismatch();\n\n // FUNCTIONS\n\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external;\n\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external;\n\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external;\n\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external;\n\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external;\n\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapter,\n uint32[] calldata _chainId,\n uint32[] calldata _destinationDomainId\n ) external;\n\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external;\n\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external;\n\n function whitelistedPools() external view returns (bytes32[] memory);\n\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n external\n view\n returns (uint32 _destinationDomainId, address _dataReceiver);\n}\n" - }, - "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 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 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 => 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 return _values(set._inner);\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 on 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" - }, - "solidity/interfaces/peripherals/IGovernable.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\ninterface IGovernable {\n // STATE VARIABLES\n\n /// @return _governor Address of the current governor\n function governor() external view returns (address _governor);\n\n /// @return _pendingGovernor Address of the current pending governor\n function pendingGovernor() external view returns (address _pendingGovernor);\n\n // EVENTS\n\n /// @notice Emitted when a new pending governor is set\n /// @param _governor Address of the current governor\n /// @param _pendingGovernor Address of the proposed next governor\n event PendingGovernorSet(address _governor, address _pendingGovernor);\n\n /// @notice Emitted when a new governor is set\n /// @param _newGovernor Address of the new governor\n event PendingGovernorAccepted(address _newGovernor);\n\n // ERRORS\n\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n\n /// @notice Throws if a non-governor user tries to call a OnlyGovernor function\n error OnlyGovernor();\n\n /// @notice Throws if a non-pending-governor user tries to call a OnlyPendingGovernor function\n error OnlyPendingGovernor();\n\n // FUNCTIONS\n\n /// @notice Allows a governor to propose a new governor\n /// @param _pendingGovernor Address of the proposed new governor\n function setPendingGovernor(address _pendingGovernor) external;\n\n /// @notice Allows a proposed governor to accept the governance\n function acceptPendingGovernor() external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeSenderAdapter {\n // FUNCTIONS\n\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable;\n\n // ERRORS\n\n error OnlyDataFeed();\n}\n" - }, - "solidity/interfaces/IOracleSidechain.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleFactory} from './IOracleFactory.sol';\n\ninterface IOracleSidechain {\n // STRUCTS\n\n struct ObservationData {\n uint32 blockTimestamp;\n int24 tick;\n }\n\n // STATE VARIABLES\n\n // TODO: complete natspec\n\n /// @return _oracleFactory The address of the OracleFactory\n function factory() external view returns (IOracleFactory _oracleFactory);\n\n /// @return _token0 The mainnet address of the Token0 of the oracle\n function token0() external view returns (address _token0);\n\n /// @return _token1 The mainnet address of the Token1 of the oracle\n function token1() external view returns (address _token1);\n\n /// @return _fee The fee identifier of the pool\n function fee() external view returns (uint24 _fee);\n\n /// @return _poolSalt The identifier of both the pool and the oracle\n function poolSalt() external view returns (bytes32 _poolSalt);\n\n /// @return _poolNonce Last recorded nonce of the pool history\n function poolNonce() external view returns (uint24 _poolNonce);\n\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\n /// @return _tick Used to maintain compatibility with Uniswap V3\n /// @return _observationIndex The index of the last oracle observation that was written,\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\n /// @return _unlocked Used to track if a pool information was already verified\n function slot0()\n external\n view\n returns (\n uint160 _sqrtPriceX96,\n int24 _tick,\n uint16 _observationIndex,\n uint16 _observationCardinality,\n uint16 _observationCardinalityNext,\n uint8 _feeProtocol,\n bool _unlocked\n );\n\n /// @notice Returns data about a specific observation index\n /// @param _index The element of the observations array to fetch\n /// @return _blockTimestamp The timestamp of the observation,\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return _initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 _index)\n external\n view\n returns (\n uint32 _blockTimestamp,\n int56 _tickCumulative,\n uint160 _secondsPerLiquidityCumulativeX128,\n bool _initialized\n );\n\n // EVENTS\n\n /// @notice Emitted when the pool information is verified\n /// @param _poolSalt Identifier of the pool and the oracle\n /// @param _token0 The contract address of either token0 or token1\n /// @param _token1 The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\n\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param _tick The log base 1.0001 of price of the pool after the swap\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\n\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\n\n // ERRORS\n\n error AI();\n error InvalidPool();\n error OnlyDataReceiver();\n error OnlyFactory();\n\n // FUNCTIONS\n\n /// @notice Permisionless method to verify token0, token1 and fee\n /// @dev Before verified, token0 and token1 views will return address(0)\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external;\n\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\n\n /// @notice Permisioned method to push a dataset to update\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolNonce Nonce of the observation broadcast\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\n\n /// @notice Permisioned method to increase the cardinalityNext value\n /// @param _observationCardinalityNext The new next length of the observations array\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\n}\n" - }, - "solidity/interfaces/IOracleFactory.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IDataReceiver} from './IDataReceiver.sol';\n\ninterface IOracleFactory is IGovernable {\n // STRUCTS\n\n struct OracleParameters {\n bytes32 poolSalt; // Identifier of the pool and oracle\n uint24 poolNonce; // Initial nonce of the deployed pool\n uint16 cardinality; // Initial cardinality of the deployed pool\n }\n\n // STATE VARIABLES\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /// @return _poolSalt The id of both the oracle and the pool\n /// @return _poolNonce The initial nonce of the pool data\n /// @return _cardinality The size of the observations memory storage\n function oracleParameters()\n external\n view\n returns (\n bytes32 _poolSalt,\n uint24 _poolNonce,\n uint16 _cardinality\n );\n\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function initialCardinality() external view returns (uint16 _initialCardinality);\n\n // EVENTS\n\n /// @notice Emitted when a new oracle is deployed\n /// @param _poolSalt The id of both the oracle and the pool\n /// @param _oracle The address of the deployed oracle\n /// @param _initialNonce The initial nonce of the pool data\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\n\n /// @notice Emitted when a new DataReceiver is set\n /// @param _dataReceiver The address of the new DataReceiver\n event DataReceiverSet(IDataReceiver _dataReceiver);\n\n /// @notice Emitted when a new initial oracle cardinality is set\n /// @param _initialCardinality The initial length of the observationCardinality array\n event InitialCardinalitySet(uint16 _initialCardinality);\n\n // ERRORS\n\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\n error OnlyDataReceiver();\n\n // FUNCTIONS\n\n /// @notice Deploys a new oracle given an inputted salt\n /// @dev Requires that the salt has not been deployed before\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\n /// @return _oracle The address of the newly deployed oracle\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\n\n /// @notice Allows governor to set a new allowed dataReceiver\n /// @dev Will disallow the previous dataReceiver\n /// @param _dataReceiver The address of the new allowed dataReceiver\n function setDataReceiver(IDataReceiver _dataReceiver) external;\n\n /// @notice Allows governor to set a new initial cardinality for new oracles\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function setInitialCardinality(uint16 _initialCardinality) external;\n\n /// @notice Overrides UniV3Factory getPool mapping\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _oracle The oracle address\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle);\n\n /// @notice Tracks the addresses of the oracle by poolSalt\n /// @param _poolSalt Identifier of both the pool and the oracle\n /// @return _oracle The address (if deployed) of the correspondant oracle\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\n\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _poolSalt Pool salt for inquired parameters\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (bytes32 _poolSalt);\n}\n" - }, - "solidity/interfaces/IDataReceiver.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IOracleFactory} from './IOracleFactory.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\n\ninterface IDataReceiver is IGovernable {\n // STATE VARIABLES\n\n /// @return _oracleFactory The address of the OracleFactory\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\n\n /// @notice Tracks already deployed oracles\n /// @param _poolSalt The identifier of the oracle\n /// @return _deployedOracle The address of the correspondant Oracle\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\n\n /// @notice Tracks the whitelisting of bridge adapters\n /// @param _adapter Address of the bridge adapter to consult\n /// @return _isAllowed Whether a bridge adapter is whitelisted\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n // EVENTS\n\n /// @notice Emitted when a broadcast observation is succesfully processed\n /// @param _poolSalt Identifier of the pool to fetch\n /// @return _poolNonce Nonce of the observation broadcast\n /// @return _observationsData Array of tuples containing the dataset\n /// @return _receiverAdapter Handler of the broadcast\n event ObservationsAdded(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] _observationsData,\n address _receiverAdapter\n );\n\n /// @notice Emitted when a new adapter whitelisting rule is set\n /// @param _adapter Address of the adapter\n /// @param _isAllowed New whitelisting status\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\n\n // ERRORS\n\n /// @notice Thrown when the broadcast nonce is incorrect\n error ObservationsNotWritable();\n\n /// @notice Thrown when a not-whitelisted adapter triggers an update\n error UnallowedAdapter();\n\n /// @notice Thrown when mismatching lists length\n error LengthMismatch();\n\n // FUNCTIONS\n\n /// @notice Allows whitelisted bridge adapters to push a broadcast\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _poolNonce Nonce of the observation broadcast\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external;\n\n /// @notice Allows governance to set an adapter whitelisted state\n /// @param _receiverAdapter Address of the adapter\n /// @param _isWhitelisted New whitelisting status\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\n\n /// @notice Allows governance to batch set adapters whitelisted state\n /// @param _receiverAdapters Array of addresses of the adapter\n /// @param _isWhitelisted Array of whitelisting status for each address\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IDataReceiver} from '../IDataReceiver.sol';\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeReceiverAdapter {\n // FUNCTIONS\n\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /* NOTE: callback methods should be here declared */\n\n // ERRORS\n\n error UnauthorizedCaller();\n}\n" - }, - "solidity/interfaces/IDataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\n\ninterface IDataFeedStrategy is IGovernable {\n // ENUMS\n\n enum TriggerReason {\n NONE,\n TIME,\n TWAP\n }\n\n // STRUCTS\n\n struct StrategySettings {\n uint32 periodDuration; // Resolution of the oracle, target twap length\n uint32 cooldown; // Time since last update to wait to time-trigger update\n uint24 twapThreshold; // Twap difference, in ticks, to twap-trigger update\n uint32 twapLength; // Twap length, in seconds, used for twap-trigger update\n }\n\n // STATE VARIABLES\n\n /// @return _dataFeed The address of the DataFeed contract\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _strategyCooldown Time in seconds since last update required to time-trigger an update\n function strategyCooldown() external view returns (uint32 _strategyCooldown);\n\n /// @return _periodDuration The targetted amount of seconds between pool consultations\n /// @dev Defines the resolution of the oracle, averaging data between consultations\n function periodDuration() external view returns (uint32 _periodDuration);\n\n /// @return _twapThreshold Twap difference, in ticks, to twap-trigger an update\n function twapThreshold() external view returns (uint24 _twapThreshold);\n\n /// @return _twapLength The time length, in seconds, used to calculate twap-trigger\n function twapLength() external view returns (uint32 _twapLength);\n\n // EVENTS\n\n /// @notice Emitted when a data fetch is triggered\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier number of the reason that triggered the fetch request\n event StrategicFetch(bytes32 indexed _poolSalt, TriggerReason _reason);\n\n /// @notice Emitted when the owner updates the job cooldown\n /// @param _strategyCooldown The new job cooldown\n event StrategyCooldownSet(uint32 _strategyCooldown);\n\n /// @notice Emitted when the owner updates the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n event TwapLengthSet(uint32 _twapLength);\n\n /// @notice Emitted when the owner updates the job twap threshold percentage\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n event TwapThresholdSet(uint24 _twapThreshold);\n\n /// @notice Emitted when the owner updates the job period length\n /// @param _periodDuration The new length of reading resolution periods\n event PeriodDurationSet(uint32 _periodDuration);\n\n // ERRORS\n\n /// @notice Thrown if the tx is not strategic\n error NotStrategic();\n\n /// @notice Thrown if setting breaks strategyCooldown >= twapLength >= periodDuration\n error WrongSetting();\n\n // FUNCTIONS\n\n /// @notice Permisionless, used to update the oracle state\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier of trigger reason (time/twap)\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external;\n\n /// @notice Permisioned, used to update the oracle state from a given timestamp\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _fromTimestamp Timestamp to start backfilling from\n function forceFetchObservations(bytes32 _poolSalt, uint32 _fromTimestamp) external;\n\n /// @notice Sets the job cooldown\n /// @param _strategyCooldown The job cooldown to be set\n function setStrategyCooldown(uint32 _strategyCooldown) external;\n\n /// @notice Sets the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n function setTwapLength(uint32 _twapLength) external;\n\n /// @notice Sets the job twap threshold percentage\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n function setTwapThreshold(uint24 _twapThreshold) external;\n\n /// @notice Sets the job period length\n /// @param _periodDuration The new length of reading resolution periods\n function setPeriodDuration(uint32 _periodDuration) external;\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the strategy can be executed\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason);\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the strategy can be executed\n /// @return _isStrategic Whether the tx is strategic or not\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) external view returns (bool _isStrategic);\n\n /// @notice Builds the secondsAgos array with periodDuration between each datapoint\n /// @param _fromTimestamp Timestamp from which to backfill the oracle with\n /// @return _secondsAgos Array of secondsAgo that backfills the history from fromTimestamp\n function calculateSecondsAgos(uint32 _fromTimestamp) external view returns (uint32[] memory _secondsAgos);\n}\n" - }, - "solidity/interfaces/bridges/IConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeSenderAdapter, IOracleSidechain} from './IBridgeSenderAdapter.sol';\nimport {IDataFeed} from '../IDataFeed.sol';\n\ninterface IConnextSenderAdapter is IBridgeSenderAdapter {\n // STATE VARIABLES\n\n function connext() external view returns (IConnext _connext);\n\n function dataFeed() external view returns (IDataFeed _dataFeed);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport {IUniswapV3PoolImmutables} from './pool/IUniswapV3PoolImmutables.sol';\nimport {IUniswapV3PoolState} from './pool/IUniswapV3PoolState.sol';\nimport {IUniswapV3PoolDerivedState} from './pool/IUniswapV3PoolDerivedState.sol';\nimport {IUniswapV3PoolActions} from './pool/IUniswapV3PoolActions.sol';\nimport {IUniswapV3PoolOwnerActions} from './pool/IUniswapV3PoolOwnerActions.sol';\nimport {IUniswapV3PoolErrors} from './pool/IUniswapV3PoolErrors.sol';\nimport {IUniswapV3PoolEvents} from './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolErrors,\n IUniswapV3PoolEvents\n{\n\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// @return tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// @return observationIndex The index of the last oracle observation that was written,\n /// @return observationCardinality The current maximum number of observations stored in the pool,\n /// @return observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n /// @return The liquidity at the current price of the pool\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper\n /// @return liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// @return feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// @return feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// @return tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// @return secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// @return secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// @return initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return liquidity The amount of liquidity in the position,\n /// @return feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// @return feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// @return tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// @return tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// @return tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolErrors.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Errors emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolErrors {\n error LOK();\n error TLU();\n error TLM();\n error TUM();\n error AI();\n error M0();\n error M1();\n error AS();\n error IIA();\n error L();\n error F0();\n error F1();\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {ExecuteArgs, TransferInfo, TokenId, DestinationTransferStatus} from \"../libraries/LibConnextStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {SwapUtils} from \"../libraries/SwapUtils.sol\";\n\nimport {IStableSwap} from \"./IStableSwap.sol\";\n\nimport {IDiamondCut} from \"./IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\ninterface IConnext is IDiamondLoupe, IDiamondCut {\n // TokenFacet\n function canonicalToAdopted(bytes32 _key) external view returns (address);\n\n function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\n\n function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\n\n function canonicalToRepresentation(bytes32 _key) external view returns (address);\n\n function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\n\n function representationToCanonical(address _adopted) external view returns (TokenId memory);\n\n function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\n\n function approvedAssets(bytes32 _key) external view returns (bool);\n\n function approvedAssets(TokenId calldata _canonical) external view returns (bool);\n\n function adoptedToLocalPools(bytes32 _key) external view returns (IStableSwap);\n\n function adoptedToLocalPools(TokenId calldata _canonical) external view returns (IStableSwap);\n\n function getTokenId(address _candidate) external view returns (TokenId memory);\n\n function setupAsset(\n TokenId calldata _canonical,\n uint8 _canonicalDecimals,\n string memory _representationName,\n string memory _representationSymbol,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function setupAssetWithDeployedRepresentation(\n TokenId calldata _canonical,\n address _representation,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\n\n function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\n\n function removeAssetId(\n bytes32 _key,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function removeAssetId(\n TokenId calldata _canonical,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function updateDetails(\n TokenId calldata _canonical,\n string memory _name,\n string memory _symbol\n ) external;\n\n // BaseConnextFacet\n\n // BridgeFacet\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\n\n function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\n\n function remote(uint32 _domain) external view returns (address);\n\n function domain() external view returns (uint256);\n\n function nonce() external view returns (uint256);\n\n function approvedSequencers(address _sequencer) external view returns (bool);\n\n function xAppConnectionManager() external view returns (address);\n\n function addConnextion(uint32 _domain, address _connext) external;\n\n function addSequencer(address _sequencer) external;\n\n function removeSequencer(address _sequencer) external;\n\n function xcall(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function xcallIntoLocal(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\n\n function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\n\n function bumpTransfer(bytes32 _transferId) external payable;\n\n function setXAppConnectionManager(address _xAppConnectionManager) external;\n\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n function enrollCustom(\n uint32 _domain,\n bytes32 _id,\n address _custom\n ) external;\n\n // InboxFacet\n\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external;\n\n // ProposedOwnableFacet\n\n function owner() external view returns (address);\n\n function routerWhitelistRemoved() external view returns (bool);\n\n function assetWhitelistRemoved() external view returns (bool);\n\n function proposed() external view returns (address);\n\n function proposedTimestamp() external view returns (uint256);\n\n function routerWhitelistTimestamp() external view returns (uint256);\n\n function assetWhitelistTimestamp() external view returns (uint256);\n\n function delay() external view returns (uint256);\n\n function proposeRouterWhitelistRemoval() external;\n\n function removeRouterWhitelist() external;\n\n function proposeAssetWhitelistRemoval() external;\n\n function removeAssetWhitelist() external;\n\n function renounced() external view returns (bool);\n\n function proposeNewOwner(address newlyProposed) external;\n\n function renounceOwnership() external;\n\n function acceptProposedOwner() external;\n\n function pause() external;\n\n function unpause() external;\n\n // RelayerFacet\n function approvedRelayers(address _relayer) external view returns (bool);\n\n function relayerFeeVault() external view returns (address);\n\n function setRelayerFeeVault(address _relayerFeeVault) external;\n\n function addRelayer(address _relayer) external;\n\n function removeRelayer(address _relayer) external;\n\n // RoutersFacet\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\n\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\n\n function getRouterApproval(address _router) external view returns (bool);\n\n function getRouterRecipient(address _router) external view returns (address);\n\n function getRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\n\n function maxRoutersPerTransfer() external view returns (uint256);\n\n function routerBalances(address _router, address _asset) external view returns (uint256);\n\n function getRouterApprovalForPortal(address _router) external view returns (bool);\n\n function setupRouter(\n address router,\n address owner,\n address recipient\n ) external;\n\n function removeRouter(address router) external;\n\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\n\n function setLiquidityFeeNumerator(uint256 _numerator) external;\n\n function approveRouterForPortal(address _router) external;\n\n function unapproveRouterForPortal(address _router) external;\n\n function setRouterRecipient(address router, address recipient) external;\n\n function proposeRouterOwner(address router, address proposed) external;\n\n function acceptProposedRouterOwner(address router) external;\n\n function addRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address _router\n ) external payable;\n\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\n\n function removeRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address payable _to,\n address _router\n ) external;\n\n function removeRouterLiquidity(\n uint256 _amount,\n address _local,\n address payable _to\n ) external;\n\n // PortalFacet\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\n\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\n\n function aavePool() external view returns (address);\n\n function aavePortalFee() external view returns (uint256);\n\n function setAavePool(address _aavePool) external;\n\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\n\n function repayAavePortal(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount,\n uint256 _maxIn\n ) external;\n\n function repayAavePortalFor(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount\n ) external;\n\n // StableSwapFacet\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\n\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\n\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\n\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\n\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\n\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\n\n function calculateSwap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapTokenAmount(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n bool deposit\n ) external view returns (uint256);\n\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) external view returns (uint256);\n\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\n\n function swap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n bytes32 canonicalId,\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n bytes32 canonicalId,\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function addSwapLiquidity(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidity(\n bytes32 canonicalId,\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidityImbalance(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n\n // SwapAdminFacet\n\n function initializeSwap(\n bytes32 _canonicalId,\n IERC20[] memory _pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 _a,\n uint256 _fee,\n uint256 _adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\n\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\n\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\n\n function rampA(\n bytes32 canonicalId,\n uint256 futureA,\n uint256 futureTime\n ) external;\n\n function stopRampA(bytes32 canonicalId) external;\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= 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 > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\nimport {IConnectorManager} from \"../../../messaging/interfaces/IConnectorManager.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n// ============= Enum =============\n\n/// @notice Enum representing address role\n// Returns uint\n// None - 0\n// Router - 1\n// Watcher - 2\n// Admin - 3\nenum Role {\n None,\n Router,\n Watcher,\n Admin\n}\n\n/**\n * @notice Enum representing status of destination transfer\n * @dev Status is only assigned on the destination domain, will always be \"none\" for the\n * origin domains\n * @return uint - Index of value in enum\n */\nenum DestinationTransferStatus {\n None, // 0\n Reconciled, // 1\n Executed, // 2\n Completed // 3 - executed + reconciled\n}\n\n// ============= Structs =============\n\nstruct TokenId {\n uint32 domain;\n bytes32 id;\n}\n\n/**\n * @notice These are the parameters that will remain constant between the\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\n * @property to - The account that receives funds, in the event of a crosschain call,\n * will receive funds if the call fails.\n *\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\n * @param canonicalDomain - The canonical domain of the asset you are bridging\n * @param to - The address you are sending funds (and potentially data) to\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\n * a user takes 1% slippage, this is expressed as 1_000)\n * @param originSender - The msg.sender of the xcall\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\n */\nstruct TransferInfo {\n uint32 originDomain;\n uint32 destinationDomain;\n uint32 canonicalDomain;\n address to;\n address delegate;\n bool receiveLocal;\n bytes callData;\n uint256 slippage;\n address originSender;\n uint256 bridgedAmt;\n uint256 normalizedIn;\n uint256 nonce;\n bytes32 canonicalId;\n}\n\n/**\n * @notice\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\n * @param routers - The routers who you are sending the funds on behalf of.\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\n * for the signed transfer ID.\n * @param sequencer - The sequencer who assigned the router path to this transfer.\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\n * for the path that was signed.\n */\nstruct ExecuteArgs {\n TransferInfo params;\n address[] routers;\n bytes[] routerSignatures;\n address sequencer;\n bytes sequencerSignature;\n}\n\n/**\n * @notice Contains RouterFacet related state\n * @param approvedRouters - Mapping of whitelisted router addresses\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\n * (if configured) or the router itself\n * @param routerOwners - Mapping of router owners\n * If set, can update the routerRecipient\n * @param proposedRouterOwners - Mapping of proposed router owners\n * Must wait timeout to set the\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\n * When accepting a proposed owner, must wait for delay to elapse\n */\nstruct RouterPermissionsManagerInfo {\n mapping(address => bool) approvedRouters;\n mapping(address => bool) approvedForPortalRouters;\n mapping(address => address) routerRecipients;\n mapping(address => address) routerOwners;\n mapping(address => address) proposedRouterOwners;\n mapping(address => uint256) proposedRouterTimestamp;\n}\n\nstruct AppStorage {\n //\n // 0\n bool initialized;\n //\n // Connext\n //\n // 1\n uint256 LIQUIDITY_FEE_NUMERATOR;\n /**\n * @notice The local address that is custodying relayer fees\n */\n // 2\n address relayerFeeVault;\n /**\n * @notice Nonce for the contract, used to keep unique transfer ids.\n * @dev Assigned at first interaction (xcall on origin domain).\n */\n // 3\n uint256 nonce;\n /**\n * @notice The domain this contract exists on.\n * @dev Must match the nomad domain, which is distinct from the \"chainId\".\n */\n // 4\n uint32 domain;\n /**\n * @notice Mapping holding the AMMs for swapping in and out of local assets.\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon).\n * This mapping is keyed on the hash of the canonical id + domain for local asset.\n */\n // 6\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\n /**\n * @notice Mapping of whitelisted assets on same domain as contract.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => bool) approvedAssets;\n /**\n * @notice Mapping of liquidity caps of whitelisted assets. If 0, no cap is enforced.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => uint256) caps;\n /**\n * @notice Mapping of adopted to canonical asset information.\n * @dev If the adopted asset is the native asset, the keyed address will\n * be the wrapped asset address.\n */\n // 8\n mapping(address => TokenId) adoptedToCanonical;\n /**\n * @notice Mapping of representation to canonical asset information.\n */\n // 9\n mapping(address => TokenId) representationToCanonical;\n /**\n * @notice Mapping of hash(canonicalId, canonicalDomain) to adopted asset on this domain.\n * @dev If the adopted asset is the native asset, the stored address will be the\n * wrapped asset address.\n */\n // 10\n mapping(bytes32 => address) canonicalToAdopted;\n /**\n * @notice Mapping of canonical to representation asset information.\n * @dev If the token is of local origin (meaning it was originanlly deployed on this chain),\n * this MUST map to address(0).\n */\n // 11\n mapping(bytes32 => address) canonicalToRepresentation;\n /**\n * @notice Mapping to track transfer status on destination domain\n */\n // 12\n mapping(bytes32 => DestinationTransferStatus) transferStatus;\n /**\n * @notice Mapping holding router address that provided fast liquidity.\n */\n // 13\n mapping(bytes32 => address[]) routedTransfers;\n /**\n * @notice Mapping of router to available balance of an asset.\n * @dev Routers should always store liquidity that they can expect to receive via the bridge on\n * this domain (the nomad local asset).\n */\n // 14\n mapping(address => mapping(address => uint256)) routerBalances;\n /**\n * @notice Mapping of approved relayers\n * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\n */\n // 15\n mapping(address => bool) approvedRelayers;\n /**\n * @notice The max amount of routers a payment can be routed through.\n */\n // 18\n uint256 maxRoutersPerTransfer;\n /**\n * @notice Stores a mapping of transfer id to slippage overrides.\n */\n // 20\n mapping(bytes32 => uint256) slippage;\n /**\n * @notice Stores a mapping of remote routers keyed on domains.\n * @dev Addresses are cast to bytes32.\n * This mapping is required because the Connext now contains the BridgeRouter and must implement\n * the remotes interface.\n */\n // 21\n mapping(uint32 => bytes32) remotes;\n //\n // ProposedOwnable\n //\n // 22\n address _proposed;\n // 23\n uint256 _proposedOwnershipTimestamp;\n // 24\n bool _routerWhitelistRemoved;\n // 25\n uint256 _routerWhitelistTimestamp;\n // 26\n bool _assetWhitelistRemoved;\n // 27\n uint256 _assetWhitelistTimestamp;\n /**\n * @notice Stores a mapping of address to Roles\n * @dev returns uint representing the enum Role value\n */\n // 28\n mapping(address => Role) roles;\n //\n // RouterFacet\n //\n // 29\n RouterPermissionsManagerInfo routerPermissionInfo;\n //\n // ReentrancyGuard\n //\n // 30\n uint256 _status;\n //\n // StableSwap\n //\n /**\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\n * Struct storing data responsible for automatic market maker functionalities. In order to\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\n */\n // 31\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\n /**\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\n */\n // 32\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\n /**\n * @notice Stores whether or not bribing, AMMs, have been paused.\n */\n // 33\n bool _paused;\n //\n // AavePortals\n //\n /**\n * @notice Address of Aave Pool contract.\n */\n // 34\n address aavePool;\n /**\n * @notice Fee percentage numerator for using Portal liquidity.\n * @dev Assumes the same basis points as the liquidity fee.\n */\n // 35\n uint256 aavePortalFeeNumerator;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 36\n mapping(bytes32 => uint256) portalDebt;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 37\n mapping(bytes32 => uint256) portalFeeDebt;\n /**\n * @notice Mapping of approved sequencers\n * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\n * for the fast liquidity route.\n */\n // 38\n mapping(address => bool) approvedSequencers;\n /**\n * @notice Remote connection manager for xapp.\n */\n // 39\n IConnectorManager xAppConnectionManager;\n}\n\nlibrary LibConnextStorage {\n function connextStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n // hash of proposed facets => acceptance time\n mapping(bytes32 => uint256) acceptanceTimes;\n // acceptance delay for upgrading facets\n uint256 acceptanceDelay;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function acceptanceDelay() internal view returns (uint256) {\n return diamondStorage().acceptanceDelay;\n }\n\n function acceptanceTime(bytes32 _key) internal view returns (uint256) {\n return diamondStorage().acceptanceTimes[_key];\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, \"LibDiamond: !contract owner\");\n }\n\n event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n function proposeDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 acceptance = block.timestamp + ds.acceptanceDelay;\n ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\n emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\n }\n\n event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n function rescindDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\n // period or befor the delay elpases\n diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = 0;\n emit DiamondCutRescinded(_diamondCut, _init, _calldata);\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n if (ds.facetAddresses.length != 0) {\n uint256 time = ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\n require(time != 0 && time <= block.timestamp, \"LibDiamond: delay not elapsed\");\n } // Otherwise, this is the first instance of deployment and it can be set automatically\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress != _facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, \"LibDiamondCut: New facet has no code\");\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n require(_calldata.length == 0, \"LibDiamondCut: _init is address(0) but_calldata is not empty\");\n } else {\n require(_calldata.length != 0, \"LibDiamondCut: _calldata is empty but _init is not address(0)\");\n if (_init != address(this)) {\n enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");\n }\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length != 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize != 0, _errorMessage);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IStableSwap {\n /*** EVENTS ***/\n\n // events replicated from SwapUtils to make the ABI easier for dumb\n // clients\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\n event AddLiquidity(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(uint256 newAdminFee);\n event NewSwapFee(uint256 newSwapFee);\n event NewWithdrawFee(uint256 newWithdrawFee);\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n function swap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function getA() external view returns (uint256);\n\n function getToken(uint8 index) external view returns (IERC20);\n\n function getTokenIndex(address tokenAddress) external view returns (uint8);\n\n function getTokenBalance(uint8 index) external view returns (uint256);\n\n function getVirtualPrice() external view returns (uint256);\n\n // min return calculation functions\n function calculateSwap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapOut(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) external view returns (uint256);\n\n function calculateSwapFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountIn\n ) external view returns (uint256);\n\n function calculateSwapOutFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountOut\n ) external view returns (uint256);\n\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\n\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\n external\n view\n returns (uint256 availableTokenAmount);\n\n // state modifying functions\n function initialize(\n IERC20[] memory pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 a,\n uint256 fee,\n uint256 adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function addLiquidity(\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidity(\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeLiquidityOneToken(\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidityImbalance(\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function proposeDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function rescindDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20, IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {LPToken} from \"../helpers/LPToken.sol\";\n\nimport {AmplificationUtils} from \"./AmplificationUtils.sol\";\nimport {MathUtils} from \"./MathUtils.sol\";\n\n/**\n * @title SwapUtils library\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\n * Admin functions should be protected within contracts using this library.\n */\nlibrary SwapUtils {\n using SafeERC20 for IERC20;\n using MathUtils for uint256;\n\n /*** EVENTS ***/\n\n event TokenSwap(\n bytes32 indexed key,\n address indexed buyer,\n uint256 tokensSold,\n uint256 tokensBought,\n uint128 soldId,\n uint128 boughtId\n );\n event AddLiquidity(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n bytes32 indexed key,\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\n event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\n\n struct Swap {\n // variables around the ramp management of A,\n // the amplification coefficient * n * (n - 1)\n // see https://www.curve.fi/stableswap-paper.pdf for details\n bytes32 key;\n uint256 initialA;\n uint256 futureA;\n uint256 initialATime;\n uint256 futureATime;\n // fee calculation\n uint256 swapFee;\n uint256 adminFee;\n LPToken lpToken;\n // contract references for all tokens being pooled\n IERC20[] pooledTokens;\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\n uint256[] tokenPrecisionMultipliers;\n // the pool balance of each token, in the token's precision\n // the contract's actual token balance might differ\n uint256[] balances;\n // the admin fee balance of each token, in the token's precision\n uint256[] adminFees;\n }\n\n // Struct storing variables used in calculations in the\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\n struct CalculateWithdrawOneTokenDYInfo {\n uint256 d0;\n uint256 d1;\n uint256 newY;\n uint256 feePerToken;\n uint256 preciseA;\n }\n\n // Struct storing variables used in calculations in the\n // {add,remove}Liquidity functions to avoid stack too deep errors\n struct ManageLiquidityInfo {\n uint256 d0;\n uint256 d1;\n uint256 d2;\n uint256 preciseA;\n LPToken lpToken;\n uint256 totalSupply;\n uint256[] balances;\n uint256[] multipliers;\n }\n\n // the precision all pools tokens will be converted to\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\n\n // the denominator used to calculate admin and LP fees. For example, an\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\n uint256 internal constant FEE_DENOMINATOR = 1e10;\n\n // Max swap fee is 1% or 100bps of each swap\n uint256 internal constant MAX_SWAP_FEE = 1e8;\n\n // Max adminFee is 100% of the swapFee\n // adminFee does not add additional fee on top of swapFee\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\n // users but only on the earnings of LPs\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\n\n // Constant value used as max loop limit\n uint256 internal constant MAX_LOOP_LIMIT = 256;\n\n /*** VIEW & PURE FUNCTIONS ***/\n\n function _getAPrecise(Swap storage self) private view returns (uint256) {\n return AmplificationUtils._getAPrecise(self);\n }\n\n /**\n * @notice Calculate the dy, the amount of selected token that user receives and\n * the fee of withdrawing in one token\n * @param tokenAmount the amount to withdraw in the pool's precision\n * @param tokenIndex which token will be withdrawn\n * @param self Swap struct to read from\n * @return the amount of token user will receive\n */\n function calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) internal view returns (uint256) {\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\n self,\n tokenAmount,\n tokenIndex,\n self.lpToken.totalSupply()\n );\n return availableTokenAmount;\n }\n\n function _calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 totalSupply\n ) private view returns (uint256, uint256) {\n uint256 dy;\n uint256 newY;\n uint256 currentY;\n\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\n\n // dy_0 (without fees)\n // dy, dy_0 - dy\n\n uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\n\n return (dy, dySwapFee);\n }\n\n /**\n * @notice Calculate the dy of withdrawing in one token\n * @param self Swap struct to read from\n * @param tokenIndex which token will be withdrawn\n * @param tokenAmount the amount to withdraw in the pools precision\n * @return the d and the new y after withdrawing one token\n */\n function calculateWithdrawOneTokenDY(\n Swap storage self,\n uint8 tokenIndex,\n uint256 tokenAmount,\n uint256 totalSupply\n )\n internal\n view\n returns (\n uint256,\n uint256,\n uint256\n )\n {\n // Get the current D, then solve the stableswap invariant\n // y_i for D - tokenAmount\n uint256[] memory xp = _xp(self);\n\n require(tokenIndex < xp.length, \"index out of range\");\n\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\n v.preciseA = _getAPrecise(self);\n v.d0 = getD(xp, v.preciseA);\n v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\n\n require(tokenAmount <= xp[tokenIndex], \"exceeds available\");\n\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\n\n uint256[] memory xpReduced = new uint256[](xp.length);\n\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\n for (uint256 i; i < xp.length; ) {\n uint256 xpi = xp[i];\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\n xpReduced[i] =\n xpi -\n ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\n FEE_DENOMINATOR);\n\n unchecked {\n ++i;\n }\n }\n\n uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\n dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\n\n return (dy, v.newY, xp[tokenIndex]);\n }\n\n /**\n * @notice Calculate the price of a token in the pool with given\n * precision-adjusted balances and a particular D.\n *\n * @dev This is accomplished via solving the invariant iteratively.\n * See the StableSwap paper and Curve.fi implementation for further details.\n *\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\n * x_1**2 + b*x_1 = c\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\n *\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\n * @param tokenIndex Index of token we are calculating for.\n * @param xp a precision-adjusted set of pool balances. Array should be\n * the same cardinality as the pool.\n * @param d the stableswap invariant\n * @return the price of the token, in the same precision as in xp\n */\n function getYD(\n uint256 a,\n uint8 tokenIndex,\n uint256[] memory xp,\n uint256 d\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndex < numTokens, \"Token not found\");\n\n uint256 c = d;\n uint256 s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < numTokens; ) {\n if (i != tokenIndex) {\n s += xp[i];\n c = (c * d) / (xp[i] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n }\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\n * as the pool.\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\n * See the StableSwap paper for details\n * @return the invariant, at the precision of the pool\n */\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n uint256 s;\n for (uint256 i; i < numTokens; ) {\n s += xp[i];\n\n unchecked {\n ++i;\n }\n }\n if (s == 0) {\n return 0;\n }\n\n uint256 prevD;\n uint256 d = s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n uint256 dP = d;\n for (uint256 j; j < numTokens; ) {\n dP = (dP * d) / (xp[j] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // dP = dP * D * D * D * ... overflow!\n\n unchecked {\n ++j;\n }\n }\n prevD = d;\n d =\n (((nA * s) / AmplificationUtils.A_PRECISION + dP * numTokens) * d) /\n ((((nA - AmplificationUtils.A_PRECISION) * d) / AmplificationUtils.A_PRECISION + (numTokens + 1) * dP));\n if (d.within1(prevD)) {\n return d;\n }\n\n unchecked {\n ++i;\n }\n }\n\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\n // function which does not rely on D.\n revert(\"D does not converge\");\n }\n\n /**\n * @notice Given a set of balances and precision multipliers, return the\n * precision-adjusted balances.\n *\n * @param balances an array of token balances, in their native precisions.\n * These should generally correspond with pooled tokens.\n *\n * @param precisionMultipliers an array of multipliers, corresponding to\n * the amounts in the balances array. When multiplied together they\n * should yield amounts at the pool's precision.\n *\n * @return an array of amounts \"scaled\" to the pool's precision\n */\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\n internal\n pure\n returns (uint256[] memory)\n {\n uint256 numTokens = balances.length;\n require(numTokens == precisionMultipliers.length, \"mismatch multipliers\");\n uint256[] memory xp = new uint256[](numTokens);\n for (uint256 i; i < numTokens; ) {\n xp[i] = balances[i] * precisionMultipliers[i];\n\n unchecked {\n ++i;\n }\n }\n return xp;\n }\n\n /**\n * @notice Return the precision-adjusted balances of all tokens in the pool\n * @param self Swap struct to read from\n * @return the pool balances \"scaled\" to the pool's precision, allowing\n * them to be more easily compared.\n */\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\n return _xp(self.balances, self.tokenPrecisionMultipliers);\n }\n\n /**\n * @notice Get the virtual price, to help calculate profit\n * @param self Swap struct to read from\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\n */\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\n uint256 d = getD(_xp(self), _getAPrecise(self));\n LPToken lpToken = self.lpToken;\n uint256 supply = lpToken.totalSupply();\n if (supply != 0) {\n return (d * (10**uint256(POOL_PRECISION_DECIMALS))) / supply;\n }\n return 0;\n }\n\n /**\n * @notice Calculate the new balances of the tokens given the indexes of the token\n * that is swapped from (FROM) and the token that is swapped to (TO).\n * This function is used as a helper function to calculate how much TO token\n * the user should receive on swap.\n *\n * @param preciseA precise form of amplification coefficient\n * @param tokenIndexFrom index of FROM token\n * @param tokenIndexTo index of TO token\n * @param x the new total amount of FROM token\n * @param xp balances of the tokens in the pool\n * @return the amount of TO token that should remain in the pool\n */\n function getY(\n uint256 preciseA,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 x,\n uint256[] memory xp\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \"token not found\");\n\n uint256 d = getD(xp, preciseA);\n uint256 c = d;\n uint256 s;\n uint256 nA = numTokens * preciseA;\n\n uint256 _x;\n for (uint256 i; i < numTokens; ) {\n if (i == tokenIndexFrom) {\n _x = x;\n } else if (i != tokenIndexTo) {\n _x = xp[i];\n } else {\n unchecked {\n ++i;\n }\n continue;\n }\n s += _x;\n c = (c * d) / (_x * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n\n // iterative approximation\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get\n */\n function calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) internal view returns (uint256 dy) {\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy.\n * @return dx the number of tokens the user have to transfer + fee\n */\n function calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) internal view returns (uint256 dx) {\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\n * @return dyFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256[] memory balances\n ) internal view returns (uint256 dy, uint256 dyFee) {\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\n dy = xp[tokenIndexTo] - y - 1;\n dyFee = (dy * self.swapFee) / FEE_DENOMINATOR;\n dy = (dy - dyFee) / multipliers[tokenIndexTo];\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\n * @return dxFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256[] memory balances\n ) internal view returns (uint256 dx, uint256 dxFee) {\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n\n uint256 a = _getAPrecise(self);\n uint256 d0 = getD(xp, a);\n\n xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\n dx = x - xp[tokenIndexFrom] + 1;\n dxFee = (dx * self.swapFee) / FEE_DENOMINATOR;\n dx = (dx + dxFee) / multipliers[tokenIndexFrom];\n }\n\n /**\n * @notice A simple method to calculate amount of each underlying\n * tokens that is returned upon burning given amount of\n * LP tokens\n *\n * @param amount the amount of LP tokens that would to be burned on\n * withdrawal\n * @return array of amounts of tokens user will receive\n */\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\n }\n\n function _calculateRemoveLiquidity(\n uint256[] memory balances,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (uint256[] memory) {\n require(amount <= totalSupply, \"exceed total supply\");\n\n uint256 numBalances = balances.length;\n uint256[] memory amounts = new uint256[](numBalances);\n\n for (uint256 i; i < numBalances; ) {\n amounts[i] = (balances[i] * amount) / totalSupply;\n\n unchecked {\n ++i;\n }\n }\n return amounts;\n }\n\n /**\n * @notice A simple method to calculate prices from deposits or\n * withdrawals, excluding fees but including slippage. This is\n * helpful as an input into the various \"min\" parameters on calls\n * to fight front-running\n *\n * @dev This shouldn't be used outside frontends for user estimates.\n *\n * @param self Swap struct to read from\n * @param amounts an array of token amounts to deposit or withdrawal,\n * corresponding to pooledTokens. The amount should be in each\n * pooled token's native precision. If a token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @param deposit whether this is a deposit or a withdrawal\n * @return if deposit was true, total amount of lp token that will be minted and if\n * deposit was false, total amount of lp token that will be burned\n */\n function calculateTokenAmount(\n Swap storage self,\n uint256[] calldata amounts,\n bool deposit\n ) internal view returns (uint256) {\n uint256 a = _getAPrecise(self);\n uint256[] memory balances = self.balances;\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n\n uint256 numBalances = balances.length;\n uint256 d0 = getD(_xp(balances, multipliers), a);\n for (uint256 i; i < numBalances; ) {\n if (deposit) {\n balances[i] = balances[i] + amounts[i];\n } else {\n balances[i] = balances[i] - amounts[i];\n }\n\n unchecked {\n ++i;\n }\n }\n uint256 d1 = getD(_xp(balances, multipliers), a);\n uint256 totalSupply = self.lpToken.totalSupply();\n\n if (deposit) {\n return ((d1 - d0) * totalSupply) / d0;\n } else {\n return ((d0 - d1) * totalSupply) / d0;\n }\n }\n\n /**\n * @notice return accumulated amount of admin fees of the token with given index\n * @param self Swap struct to read from\n * @param index Index of the pooled token\n * @return admin balance in the token's precision\n */\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\n require(index < self.pooledTokens.length, \"index out of range\");\n return self.adminFees[index];\n }\n\n /**\n * @notice internal helper function to calculate fee per token multiplier used in\n * swap fee calculations\n * @param swapFee swap fee for the tokens\n * @param numTokens number of tokens pooled\n */\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\n return (swapFee * numTokens) / ((numTokens - 1) * 4);\n }\n\n /*** STATE MODIFYING FUNCTIONS ***/\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"swap more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"no fee token support\");\n }\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dy the amount of tokens the user wants to buy\n * @param maxDx the max amount the user would like to send.\n * @return amount of token user have to transfer on swap\n */\n function swapOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \">pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"not support fee token\");\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice swap two tokens in the pool internally\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swapInternal(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n require(dx <= self.balances[tokenIndexFrom], \"more than pool balance\");\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice Should get exact amount out of AMM for asset put in\n */\n function swapInternalOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \"more than pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice Add liquidity to the pool\n * @param self Swap struct to read from and write to\n * @param amounts the amounts of each token to add, in their native precision\n * @param minToMint the minimum LP tokens adding this amount of liquidity\n * should mint, otherwise revert. Handy for front-running mitigation\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\n * @return amount of LP token user received\n */\n function addLiquidity(\n Swap storage self,\n uint256[] memory amounts,\n uint256 minToMint\n ) internal returns (uint256) {\n uint256 numTokens = self.pooledTokens.length;\n require(amounts.length == numTokens, \"mismatch pooled tokens\");\n\n // current state\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n if (v.totalSupply != 0) {\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n }\n\n uint256[] memory newBalances = new uint256[](numTokens);\n\n for (uint256 i; i < numTokens; ) {\n require(v.totalSupply != 0 || amounts[i] != 0, \"!supply all tokens\");\n\n // Transfer tokens first to see if a fee was charged on transfer\n if (amounts[i] != 0) {\n IERC20 token = self.pooledTokens[i];\n uint256 beforeBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), amounts[i]);\n\n // Update the amounts[] with actual transfer amount\n amounts[i] = token.balanceOf(address(this)) - beforeBalance;\n }\n\n newBalances[i] = v.balances[i] + amounts[i];\n\n unchecked {\n ++i;\n }\n }\n\n // invariant after change\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n require(v.d1 > v.d0, \"D should increase\");\n\n // updated to reflect fees and calculate the user's LP tokens\n v.d2 = v.d1;\n uint256[] memory fees = new uint256[](numTokens);\n\n if (v.totalSupply != 0) {\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n for (uint256 i; i < numTokens; ) {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / FEE_DENOMINATOR;\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = newBalances[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n newBalances[i] = newBalances[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n } else {\n // the initial depositor doesn't pay fees\n self.balances = newBalances;\n }\n\n uint256 toMint;\n if (v.totalSupply == 0) {\n toMint = v.d1;\n } else {\n toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\n }\n\n require(toMint >= minToMint, \"mint < min\");\n\n // mint the user's LP tokens\n v.lpToken.mint(msg.sender, toMint);\n\n emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\n\n return toMint;\n }\n\n /**\n * @notice Burn LP tokens to remove liquidity from the pool.\n * @dev Liquidity can always be removed, even when the pool is paused.\n * @param self Swap struct to read from and write to\n * @param amount the amount of LP tokens to burn\n * @param minAmounts the minimum amounts of each token in the pool\n * acceptable for this burn. Useful as a front-running mitigation\n * @return amounts of tokens the user received\n */\n function removeLiquidity(\n Swap storage self,\n uint256 amount,\n uint256[] calldata minAmounts\n ) internal returns (uint256[] memory) {\n LPToken lpToken = self.lpToken;\n require(amount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(minAmounts.length == numTokens, \"mismatch poolTokens\");\n\n uint256[] memory balances = self.balances;\n uint256 totalSupply = lpToken.totalSupply();\n\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\n\n uint256 numAmounts = amounts.length;\n for (uint256 i; i < numAmounts; ) {\n require(amounts[i] >= minAmounts[i], \"amounts[i] < minAmounts[i]\");\n self.balances[i] = balances[i] - amounts[i];\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n lpToken.burnFrom(msg.sender, amount);\n\n emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\n\n return amounts;\n }\n\n /**\n * @notice Remove liquidity from the pool all in one token.\n * @param self Swap struct to read from and write to\n * @param tokenAmount the amount of the lp tokens to burn\n * @param tokenIndex the index of the token you want to receive\n * @param minAmount the minimum amount to withdraw, otherwise revert\n * @return amount chosen token that user received\n */\n function removeLiquidityOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount\n ) internal returns (uint256) {\n LPToken lpToken = self.lpToken;\n\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(tokenIndex < numTokens, \"not found\");\n\n uint256 totalSupply = lpToken.totalSupply();\n\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\n\n require(dy >= minAmount, \"dy < minAmount\");\n\n uint256 adminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR;\n self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\n if (adminFee != 0) {\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\n }\n lpToken.burnFrom(msg.sender, tokenAmount);\n self.pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\n\n emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\n\n return dy;\n }\n\n /**\n * @notice Remove liquidity from the pool, weighted differently than the\n * pool's current balances.\n *\n * @param self Swap struct to read from and write to\n * @param amounts how much of each token to withdraw\n * @param maxBurnAmount the max LP token provider is willing to pay to\n * remove liquidity. Useful as a front-running mitigation.\n * @return actual amount of LP tokens burned in the withdrawal\n */\n function removeLiquidityImbalance(\n Swap storage self,\n uint256[] memory amounts,\n uint256 maxBurnAmount\n ) internal returns (uint256) {\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n\n uint256 numTokens = self.pooledTokens.length;\n uint256 numAmounts = amounts.length;\n require(numAmounts == numTokens, \"mismatch pool tokens\");\n\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \">LP.balanceOf\");\n\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n uint256[] memory fees = new uint256[](numTokens);\n {\n uint256[] memory balances1 = new uint256[](numTokens);\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n for (uint256 i; i < numTokens; ) {\n require(v.balances[i] >= amounts[i], \"withdraw more than available\");\n\n unchecked {\n balances1[i] = v.balances[i] - amounts[i];\n ++i;\n }\n }\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\n\n for (uint256 i; i < numTokens; ) {\n {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n uint256 difference = idealBalance.difference(balances1[i]);\n fees[i] = (feePerToken * difference) / FEE_DENOMINATOR;\n }\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = balances1[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n balances1[i] = balances1[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\n }\n uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\n require(tokenAmount != 0, \"!zero amount\");\n tokenAmount = tokenAmount + 1;\n\n require(tokenAmount <= maxBurnAmount, \"tokenAmount > maxBurnAmount\");\n\n v.lpToken.burnFrom(msg.sender, tokenAmount);\n\n for (uint256 i; i < numTokens; ) {\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\n\n return tokenAmount;\n }\n\n /**\n * @notice withdraw all admin fees to a given address\n * @param self Swap struct to withdraw fees from\n * @param to Address to send the fees to\n */\n function withdrawAdminFees(Swap storage self, address to) internal {\n uint256 numTokens = self.pooledTokens.length;\n for (uint256 i; i < numTokens; ) {\n IERC20 token = self.pooledTokens[i];\n uint256 balance = self.adminFees[i];\n if (balance != 0) {\n self.adminFees[i] = 0;\n token.safeTransfer(to, balance);\n }\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Sets the admin fee\n * @dev adminFee cannot be higher than 100% of the swap fee\n * @param self Swap struct to update\n * @param newAdminFee new admin fee to be applied on future transactions\n */\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\n require(newAdminFee <= MAX_ADMIN_FEE, \"too high\");\n self.adminFee = newAdminFee;\n\n emit NewAdminFee(self.key, newAdminFee);\n }\n\n /**\n * @notice update the swap fee\n * @dev fee cannot be higher than 1% of each swap\n * @param self Swap struct to update\n * @param newSwapFee new swap fee to be applied on future transactions\n */\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\n require(newSwapFee <= MAX_SWAP_FEE, \"too high\");\n self.swapFee = newSwapFee;\n\n emit NewSwapFee(self.key, newSwapFee);\n }\n\n /**\n * @notice Check if this stableswap pool exists and is valid (i.e. has been\n * initialized and tokens have been added).\n * @return bool true if this stableswap pool is valid, false if not.\n */\n function exists(Swap storage self) internal view returns (bool) {\n return self.pooledTokens.length != 0;\n }\n}\n" - }, - "@openzeppelin/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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/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" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\nimport {IOutbox} from \"./IOutbox.sol\";\n\n/**\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\n * allows an admin to call `setXAppConnectionManager` to update the underlying\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\n *\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\n * will interface with.\n */\ninterface IConnectorManager {\n /**\n * @notice Get the local inbox contract from the xAppConnectionManager\n * @return The local inbox contract\n * @dev The local inbox contract is a SpokeConnector with AMBs, and a\n * Home contract with nomad\n */\n function home() external view returns (IOutbox);\n\n /**\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\n * @return True if _potentialReplica is an enrolled Replica\n */\n function isReplica(address _potentialReplica) external view returns (bool);\n\n /**\n * @notice Get the local domain from the xAppConnectionManager\n * @return The local domain\n */\n function localDomain() external view returns (uint32);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n/**\n * @title AmplificationUtils library\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\n * This library assumes the struct is fully validated.\n */\nlibrary AmplificationUtils {\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n // Constant values used in ramping A calculations\n uint256 public constant A_PRECISION = 100;\n uint256 public constant MAX_A = 10**6;\n uint256 private constant MAX_A_CHANGE = 2;\n uint256 private constant MIN_RAMP_TIME = 14 days;\n\n /**\n * @notice Return A, the amplification coefficient * n * (n - 1)\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter\n */\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self) / A_PRECISION;\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self);\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n uint256 t1 = self.futureATime; // time when ramp is finished\n uint256 a1 = self.futureA; // final A value when ramp is finished\n\n if (block.timestamp < t1) {\n uint256 t0 = self.initialATime; // time when ramp is started\n uint256 a0 = self.initialA; // initial A value when ramp is started\n if (a1 > a0) {\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\n return a0 + ((a1 - a0) * (block.timestamp - t0)) / (t1 - t0);\n } else {\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\n return a0 - ((a0 - a1) * (block.timestamp - t0)) / (t1 - t0);\n }\n } else {\n return a1;\n }\n }\n\n /**\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\n * Checks if the change is too rapid, and commits the new A value only when it falls under\n * the limit range.\n * @param self Swap struct to update\n * @param futureA_ the new A to ramp towards\n * @param futureTime_ timestamp when the new A should be reached\n */\n function rampA(\n SwapUtils.Swap storage self,\n uint256 futureA_,\n uint256 futureTime_\n ) internal {\n require(block.timestamp >= self.initialATime + 1 days, \"Wait 1 day before starting ramp\");\n require(futureTime_ >= block.timestamp + MIN_RAMP_TIME, \"Insufficient ramp time\");\n require(futureA_ != 0 && futureA_ < MAX_A, \"futureA_ must be > 0 and < MAX_A\");\n\n uint256 initialAPrecise = _getAPrecise(self);\n uint256 futureAPrecise = futureA_ * A_PRECISION;\n\n if (futureAPrecise < initialAPrecise) {\n require(futureAPrecise * MAX_A_CHANGE >= initialAPrecise, \"futureA_ is too small\");\n } else {\n require(futureAPrecise <= initialAPrecise * MAX_A_CHANGE, \"futureA_ is too large\");\n }\n\n self.initialA = initialAPrecise;\n self.futureA = futureAPrecise;\n self.initialATime = block.timestamp;\n self.futureATime = futureTime_;\n\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\n }\n\n /**\n * @notice Stops ramping A immediately. Once this function is called, rampA()\n * cannot be called for another 24 hours\n * @param self Swap struct to update\n */\n function stopRampA(SwapUtils.Swap storage self) internal {\n require(self.futureATime > block.timestamp, \"Ramp is already stopped\");\n\n uint256 currentA = _getAPrecise(self);\n self.initialA = currentA;\n self.futureA = currentA;\n self.initialATime = block.timestamp;\n self.futureATime = block.timestamp;\n\n emit StopRampA(currentA, block.timestamp);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title Liquidity Provider Token\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\n * It is used to represent user's shares when providing liquidity to swap contracts.\n * @dev Only Swap contracts should initialize and own LPToken contracts.\n */\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\n // ============ Upgrade Gap ============\n\n uint256[49] private __GAP; // gap for upgrade safety\n\n // ============ Storage ============\n\n /**\n * @notice Used to enforce proper token dilution\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\n * See audit recommendations here:\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\n * and uniswap v2 implementation here:\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\n */\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\n\n // ============ Initializer ============\n\n /**\n * @notice Initializes this LPToken contract with the given name and symbol\n * @dev The caller of this function will become the owner. A Swap contract should call this\n * in its initializer function.\n * @param name name of this token\n * @param symbol symbol of this token\n */\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\n __Context_init_unchained();\n __ERC20_init_unchained(name, symbol);\n __Ownable_init_unchained();\n return true;\n }\n\n // ============ External functions ============\n\n /**\n * @notice Mints the given amount of LPToken to the recipient.\n * @dev only owner can call this mint function\n * @param recipient address of account to receive the tokens\n * @param amount amount of tokens to mint\n */\n function mint(address recipient, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot mint 0\");\n if (totalSupply() == 0) {\n // NOTE: using the _mint function directly will error because it is going\n // to the 0 address. fix by using the address(1) here instead\n _mint(address(1), MINIMUM_LIQUIDITY);\n }\n _mint(recipient, amount);\n }\n\n /**\n * @notice Burns the given amount of LPToken from provided account\n * @dev only owner can call this burn function\n * @param account address of account from which to burn token\n * @param amount amount of tokens to mint\n */\n function burnFrom(address account, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot burn 0\");\n _burn(account, amount);\n }\n\n // ============ Internal functions ============\n\n /**\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\n * This assumes the owner is set to a Swap contract's address.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20Upgradeable) {\n super._beforeTokenTransfer(from, to, amount);\n require(to != address(this), \"LPToken: cannot send to itself\");\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\n/**\n * @title MathUtils library\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\n * differences between two uint256.\n */\nlibrary MathUtils {\n /**\n * @notice Compares a and b and returns true if the difference between a and b\n * is less than 1 or equal to each other.\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return True if the difference between a and b is less than 1 or equal,\n * otherwise return false\n */\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\n return (difference(a, b) <= 1);\n }\n\n /**\n * @notice Calculates absolute difference between a and b\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return Difference between a and b\n */\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a > b) {\n return a - b;\n }\n return b - a;\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.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 IERC20Upgradeable {\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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\n/**\n * @notice Interface for all contracts sending messages originating on their\n * current domain.\n *\n * @dev These are the Home.sol interface methods used by the `Router`\n * and exposed via `home()` on the `XAppConnectionClient`\n */\ninterface IOutbox {\n /**\n * @notice Emitted when a new message is added to an outbound message merkle root\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination << 32) & nonce)\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\n * @param committedRoot the latest notarized root submitted in the last signed Update\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes32 committedRoot,\n bytes message\n );\n\n /**\n * @notice Dispatch the message it to the destination domain & recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n * @return bytes32 The leaf added to the tree\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n bytes memory _messageBody\n ) external returns (bytes32);\n}\n" - }, - "solidity/for-test/DataReceiverForTest.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {DataReceiver} from '../contracts/DataReceiver.sol';\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\ncontract DataReceiverForTest is DataReceiver {\n constructor(address _governor, IOracleFactory _oracleFactory) DataReceiver(_governor, _oracleFactory) {}\n\n function internalAddObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "solidity/contracts/DataReceiver.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\n\n/// @title The DataReceiver contract\n/// @notice Handles reception of broadcast data and delivers it to correspondant oracle\ncontract DataReceiver is IDataReceiver, Governable {\n /// @inheritdoc IDataReceiver\n IOracleFactory public immutable oracleFactory;\n\n /// @inheritdoc IDataReceiver\n mapping(bytes32 => IOracleSidechain) public deployedOracles;\n\n /// @inheritdoc IDataReceiver\n mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters;\n\n /// @inheritdoc IDataReceiver\n bytes32 public constant ORACLE_INIT_CODE_HASH = 0x81a14d5bbd761f94f91b3251dcb81827627068b092edb305c98f3799dcf10da2;\n\n constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) {\n oracleFactory = _oracleFactory;\n }\n\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external onlyWhitelistedAdapters {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n // Read, store or deploy oracle given poolSalt\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.getPool(_poolSalt);\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.deployOracle(_poolSalt, _poolNonce);\n }\n deployedOracles[_poolSalt] = _oracle;\n }\n // Try to write observations data into oracle\n if (_oracle.write(_observationsData, _poolNonce)) {\n emit ObservationsAdded(_poolSalt, _poolNonce, _observationsData, msg.sender);\n } else {\n revert ObservationsNotWritable();\n }\n }\n\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_receiverAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IDataReceiver\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _receiverAdapterLength = _receiverAdapters.length;\n if (_receiverAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _receiverAdapterLength; ++_i) {\n _whitelistAdapter(_receiverAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n function _whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_receiverAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_receiverAdapter, _isWhitelisted);\n }\n\n modifier onlyWhitelistedAdapters() {\n if (!whitelistedAdapters[IBridgeReceiverAdapter(msg.sender)]) revert UnallowedAdapter();\n _;\n }\n}\n" - }, - "solidity/contracts/OracleSidechain.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\n\n/// @title The SidechainOracle contract\n/// @notice Computes and stores on-chain price data from Mainnet\ncontract OracleSidechain is IOracleSidechain {\n using Oracle for Oracle.Observation[65535];\n\n /// @inheritdoc IOracleSidechain\n IOracleFactory public immutable factory;\n\n struct Slot0 {\n // the current price\n uint160 sqrtPriceX96;\n // the current tick\n int24 tick;\n // the most-recently updated index of the observations array\n uint16 observationIndex;\n // the current maximum number of observations that are being stored\n uint16 observationCardinality;\n // the next maximum number of observations to store, triggered in observations.write\n uint16 observationCardinalityNext;\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\n // represented as an integer denominator (1/x)%\n uint8 feeProtocol;\n // whether the pool is locked\n bool unlocked;\n }\n /// @inheritdoc IOracleSidechain\n Slot0 public slot0;\n\n /// @inheritdoc IOracleSidechain\n Oracle.Observation[65535] public observations;\n\n /// @inheritdoc IOracleSidechain\n bytes32 public immutable poolSalt;\n\n uint24 public poolNonce;\n /// @inheritdoc IOracleSidechain\n address public token0;\n /// @inheritdoc IOracleSidechain\n address public token1;\n /// @inheritdoc IOracleSidechain\n uint24 public fee;\n\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\n function _getBlockTimestamp() internal view virtual returns (uint32) {\n return uint32(block.timestamp); // truncation is desired\n }\n\n constructor() {\n factory = IOracleFactory(msg.sender);\n uint16 _cardinality;\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\n\n slot0 = Slot0({\n sqrtPriceX96: 0,\n tick: 0,\n observationIndex: _cardinality - 1,\n observationCardinality: _cardinality,\n observationCardinalityNext: _cardinality,\n feeProtocol: 0,\n unlocked: true\n });\n }\n\n /// @inheritdoc IOracleSidechain\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external {\n if (!slot0.unlocked) revert AI();\n\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\n\n token0 = _token0;\n token1 = _token1;\n fee = _fee;\n slot0.unlocked = false;\n\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\n }\n\n /// @inheritdoc IOracleSidechain\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\n {\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\n }\n\n /// @inheritdoc IOracleSidechain\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\n if (_poolNonce != poolNonce++) return false;\n\n uint256 _observationsDataLength = _observationsData.length;\n for (uint256 _i; _i < _observationsDataLength; ) {\n _write(_observationsData[_i]);\n unchecked {\n ++_i;\n }\n }\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\n\n // emits UniV3 Swap event topic with minimal data\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\n return true;\n }\n\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\n if (_observationCardinalityNext <= _observationCardinalityNextOld) return;\n slot0.observationCardinalityNext = _observationCardinalityNext;\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\n }\n\n function _write(ObservationData memory _observationData) private {\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\n slot0.observationIndex,\n _observationData.blockTimestamp,\n slot0.tick,\n 0,\n slot0.observationCardinality,\n slot0.observationCardinalityNext\n );\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\n slot0.tick = _observationData.tick;\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\n _;\n }\n\n modifier onlyFactory() {\n if (msg.sender != address(factory)) revert OnlyFactory();\n _;\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/TickMath.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n error T();\n error R();\n\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n unchecked {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n if (absTick > uint256(int256(MAX_TICK))) revert T();\n\n uint256 ratio = absTick & 0x1 != 0\n ? 0xfffcb933bd6fad37aa2d162d1a594001\n : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\n /// ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n unchecked {\n // second inequality must be < because the price can never reach the price at the max tick\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/Oracle.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/// @title Oracle\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\n/// @dev Instances of stored oracle data, \"observations\", are collected in the oracle array\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\n/// Observations are overwritten when the full length of the oracle array is populated.\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\nlibrary Oracle {\n error I();\n error OLD();\n\n struct Observation {\n // the block timestamp of the observation\n uint32 blockTimestamp;\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\n int56 tickCumulative;\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\n uint160 secondsPerLiquidityCumulativeX128;\n // whether or not the observation is initialized\n bool initialized;\n }\n\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\n /// @param last The specified observation to be transformed\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @return Observation The newly populated observation\n function transform(\n Observation memory last,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity\n ) private pure returns (Observation memory) {\n unchecked {\n uint32 delta = blockTimestamp - last.blockTimestamp;\n return\n Observation({\n blockTimestamp: blockTimestamp,\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\n initialized: true\n });\n }\n }\n\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\n /// @param self The stored oracle array\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\n /// @return cardinality The number of populated elements in the oracle array\n /// @return cardinalityNext The new length of the oracle array, independent of population\n function initialize(Observation[65535] storage self, uint32 time)\n internal\n returns (uint16 cardinality, uint16 cardinalityNext)\n {\n self[0] = Observation({\n blockTimestamp: time,\n tickCumulative: 0,\n secondsPerLiquidityCumulativeX128: 0,\n initialized: true\n });\n return (1, 1);\n }\n\n /// @notice Writes an oracle observation to the array\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\n /// @param self The stored oracle array\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @param cardinality The number of populated elements in the oracle array\n /// @param cardinalityNext The new length of the oracle array, independent of population\n /// @return indexUpdated The new index of the most recently written element in the oracle array\n /// @return cardinalityUpdated The new cardinality of the oracle array\n function write(\n Observation[65535] storage self,\n uint16 index,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity,\n uint16 cardinality,\n uint16 cardinalityNext\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\n unchecked {\n Observation memory last = self[index];\n\n // early return if we've already written an observation this block\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\n\n // if the conditions are right, we can bump the cardinality\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\n cardinalityUpdated = cardinalityNext;\n } else {\n cardinalityUpdated = cardinality;\n }\n\n indexUpdated = (index + 1) % cardinalityUpdated;\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\n }\n }\n\n /// @notice Prepares the oracle array to store up to `next` observations\n /// @param self The stored oracle array\n /// @param current The current next cardinality of the oracle array\n /// @param next The proposed next cardinality which will be populated in the oracle array\n /// @return next The next cardinality which will be populated in the oracle array\n function grow(\n Observation[65535] storage self,\n uint16 current,\n uint16 next\n ) internal returns (uint16) {\n unchecked {\n if (current <= 0) revert I();\n // no-op if the passed next value isn't greater than the current next value\n if (next <= current) return current;\n // store in each slot to prevent fresh SSTOREs in swaps\n // this data will not be used because the initialized boolean is still false\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\n return next;\n }\n }\n\n /// @notice comparator for 32-bit timestamps\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\n /// @param time A timestamp truncated to 32 bits\n /// @param a A comparison timestamp from which to determine the relative position of `time`\n /// @param b From which to determine the relative position of `time`\n /// @return Whether `a` is chronologically <= `b`\n function lte(\n uint32 time,\n uint32 a,\n uint32 b\n ) private pure returns (bool) {\n unchecked {\n // if there hasn't been overflow, no need to adjust\n if (a <= time && b <= time) return a <= b;\n\n uint256 aAdjusted = a > time ? a : a + 2**32;\n uint256 bAdjusted = b > time ? b : b + 2**32;\n\n return aAdjusted <= bAdjusted;\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\n /// The result may be the same observation, or adjacent observations.\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation recorded before, or at, the target\n /// @return atOrAfter The observation recorded at, or after, the target\n function binarySearch(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n uint16 index,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n uint256 l = (index + 1) % cardinality; // oldest observation\n uint256 r = l + cardinality - 1; // newest observation\n uint256 i;\n while (true) {\n i = (l + r) / 2;\n\n beforeOrAt = self[i % cardinality];\n\n // we've landed on an uninitialized tick, keep searching higher (more recently)\n if (!beforeOrAt.initialized) {\n l = i + 1;\n continue;\n }\n\n atOrAfter = self[(i + 1) % cardinality];\n\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\n\n // check if we've found the answer!\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\n\n if (!targetAtOrAfter) r = i - 1;\n else l = i + 1;\n }\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\n /// @dev Assumes there is at least 1 initialized observation.\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param tick The active tick at the time of the returned or simulated observation\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The total pool liquidity at the time of the call\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\n function getSurroundingObservations(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n // optimistically set before to the newest observation\n beforeOrAt = self[index];\n\n // if the target is chronologically at or after the newest observation, we can early return\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\n if (beforeOrAt.blockTimestamp == target) {\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\n return (beforeOrAt, atOrAfter);\n } else {\n // otherwise, we need to transform\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\n }\n }\n\n // now, set before to the oldest observation\n beforeOrAt = self[(index + 1) % cardinality];\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\n\n // ensure that the target is chronologically at or after the oldest observation\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\n\n // if we've reached this point, we have to binary search\n return binarySearch(self, time, target, index, cardinality);\n }\n }\n\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\n /// at exactly the timestamp between the two observations.\n /// @param self The stored oracle array\n /// @param time The current block timestamp\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\n function observeSingle(\n Observation[65535] storage self,\n uint32 time,\n uint32 secondsAgo,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\n unchecked {\n if (secondsAgo == 0) {\n Observation memory last = self[index];\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\n }\n\n uint32 target = time - secondsAgo;\n\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\n self,\n time,\n target,\n tick,\n index,\n liquidity,\n cardinality\n );\n\n if (target == beforeOrAt.blockTimestamp) {\n // we're at the left boundary\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\n } else if (target == atOrAfter.blockTimestamp) {\n // we're at the right boundary\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\n } else {\n // we're in the middle\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\n return (\n beforeOrAt.tickCumulative +\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\n int56(uint56(targetDelta)),\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\n uint160(\n (uint256(\n atOrAfter.secondsPerLiquidityCumulativeX128 -\n beforeOrAt.secondsPerLiquidityCumulativeX128\n ) * targetDelta) / observationTimeDelta\n )\n );\n }\n }\n }\n\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\n /// @dev Reverts if `secondsAgos` > oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\n function observe(\n Observation[65535] storage self,\n uint32 time,\n uint32[] memory secondsAgos,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\n unchecked {\n if (cardinality <= 0) revert I();\n\n tickCumulatives = new int56[](secondsAgos.length);\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\n for (uint256 i = 0; i < secondsAgos.length; i++) {\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\n self,\n time,\n secondsAgos[i],\n tick,\n index,\n liquidity,\n cardinality\n );\n }\n }\n }\n}\n" - }, - "solidity/interfaces/bridges/IConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from './IBridgeReceiverAdapter.sol';\n\ninterface IConnextReceiverAdapter is IBridgeReceiverAdapter {\n // STATE VARIABLES\n\n function connext() external view returns (IConnext _connext);\n\n function source() external view returns (address _originContract);\n\n function originDomain() external view returns (uint32 _originDomain);\n}\n" - }, - "solidity/contracts/bridges/ConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {LibConnextStorage, TransferInfo} from '@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol';\nimport {IConnext, IConnextSenderAdapter, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../../interfaces/bridges/IConnextSenderAdapter.sol';\n\ncontract ConnextSenderAdapter is IConnextSenderAdapter {\n /// @inheritdoc IConnextSenderAdapter\n IConnext public immutable connext;\n\n /// @inheritdoc IConnextSenderAdapter\n IDataFeed public immutable dataFeed;\n\n constructor(IConnext _connext, IDataFeed _dataFeed) {\n connext = _connext;\n dataFeed = _dataFeed;\n }\n\n /// @inheritdoc IBridgeSenderAdapter\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce // TODO: review input parameters packing KMC-\n ) external payable onlyDataFeed {\n bytes memory _callData = abi.encode(_observationsData, _poolSalt, _poolNonce);\n\n connext.xcall({\n _destination: _destinationDomainId, // unique identifier for destination domain\n _to: _to, // recipient of funds, where calldata will be executed\n _asset: address(0), // asset being transferred\n _delegate: address(0), // permissioned address to recover in edgecases on destination domain\n _amount: 0, // amount being transferred\n _slippage: 0, // slippage in bps\n _callData: _callData // to be executed on _to on the destination domain\n });\n }\n\n modifier onlyDataFeed() {\n if (msg.sender != address(dataFeed)) revert OnlyDataFeed();\n _;\n }\n}\n" - }, - "solidity/interfaces/IStrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IKeep3rJob} from './peripherals/IKeep3rJob.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IStrategyJob is IKeep3rJob {\n // STATE VARIABLES\n\n /// @return _dataFeedStrategy The address of the current DataFeedStrategy\n function dataFeedStrategy() external view returns (IDataFeedStrategy _dataFeedStrategy);\n\n /// @return _dataFeed The address of the DataFeed\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _defaultBridgeSenderAdapter The address of the job bridge sender adapter\n function defaultBridgeSenderAdapter() external view returns (IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n /// @param _chainId The identifier of the chain\n /// @param _poolSalt The identifier of both the pool and oracle\n /// @return _lastPoolNonceBridged Last nonce of the oracle observed\n function lastPoolNonceBridged(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _lastPoolNonceBridged);\n\n // EVENTS\n\n /// @notice Emitted when a new default bridge sender adapter is set\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n event DefaultBridgeSenderAdapterSet(IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n // ERRORS\n\n /// @notice Thrown when the job is not workable\n error NotWorkable();\n\n // FUNCTIONS\n\n /// @notice Calls to send observations in the DataFeed contract\n /// @param _chainId The Ethereum chain identification\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Calls to fetch observations and update the oracle state in the DataFeed contract\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The identifier of the reason to trigger an update\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external;\n\n /// @notice Allows governor to set a new default bridge sender adapter\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external;\n\n /// @notice Returns if the job can be worked\n /// @param _chainId The destination chain ID\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n /// @return _isWorkable Whether the job is workable or not\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external view returns (bool _isWorkable);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the job can be worked\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the job can be worked\n /// @return _isWorkable Whether the job is workable or not\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external view returns (bool _isWorkable);\n}\n" - }, - "solidity/interfaces/peripherals/IKeep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './IGovernable.sol';\nimport {IKeep3r} from '@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol';\n\ninterface IKeep3rJob is IGovernable {\n // STATE VARIABLES\n\n /// @return _keep3r Address of the Keep3r contract\n function keep3r() external view returns (IKeep3r _keep3r);\n\n // EVENTS\n\n /// @notice Emitted when a new Keep3r contract is set\n /// @param _keep3r Address of the new Keep3r contract\n event Keep3rSet(IKeep3r _keep3r);\n\n // ERRORS\n\n /// @notice Throws when a keeper fails the validation\n error KeeperNotValid();\n\n // FUNCTIONS\n\n /// @notice Allows governor to set a new Keep3r contract\n /// @param _keep3r Address of the new Keep3r contract\n function setKeep3r(IKeep3r _keep3r) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rAccountance.sol';\nimport './peripherals/IKeep3rRoles.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rAccountance, IKeep3rRoles, IKeep3rParameters {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rRoles.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rKeepers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable, IKeep3rKeeperFundable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rAccountance.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rParameters.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\n\ninterface IKeep3rParameters is IBaseErrors {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rJobs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobOwnership, IKeep3rJobDisputable, IKeep3rJobMigration, IKeep3rJobManager, IKeep3rJobWorkable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IBaseErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" - }, - "solidity/contracts/OracleFactory.sol": { - "content": "//TODO: change license\n//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IOracleFactory, IOracleSidechain, IDataReceiver} from '../interfaces/IOracleFactory.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The OracleFactory contract\n/// @notice Handles the deployment of new OracleSidechains\ncontract OracleFactory is IOracleFactory, Governable {\n /// @inheritdoc IOracleFactory\n IDataReceiver public dataReceiver;\n\n /// @inheritdoc IOracleFactory\n OracleParameters public oracleParameters;\n\n /// @inheritdoc IOracleFactory\n uint16 public initialCardinality = 144;\n\n /// @inheritdoc IOracleFactory\n bytes32 public constant ORACLE_INIT_CODE_HASH = keccak256(type(OracleSidechain).creationCode);\n\n constructor(address _governor, IDataReceiver _dataReceiver) Governable(_governor) {\n dataReceiver = _dataReceiver;\n }\n\n /// @inheritdoc IOracleFactory\n function deployOracle(bytes32 _poolSalt, uint24 _initialNonce) external onlyDataReceiver returns (IOracleSidechain _oracle) {\n oracleParameters = OracleParameters({poolSalt: _poolSalt, poolNonce: _initialNonce, cardinality: initialCardinality});\n _oracle = new OracleSidechain{salt: _poolSalt}();\n\n delete oracleParameters;\n emit OracleDeployed(_poolSalt, address(_oracle), _initialNonce);\n }\n\n /// @inheritdoc IOracleFactory\n function setDataReceiver(IDataReceiver _dataReceiver) external onlyGovernor {\n dataReceiver = _dataReceiver;\n emit DataReceiverSet(_dataReceiver);\n }\n\n /// @inheritdoc IOracleFactory\n function setInitialCardinality(uint16 _initialCardinality) external onlyGovernor {\n initialCardinality = _initialCardinality;\n emit InitialCardinalitySet(_initialCardinality);\n }\n\n function increaseOracleCardinality(bytes32 _poolSalt, uint16 _observationCardinalityNext) external onlyGovernor {\n IOracleSidechain _oracle = getPool(_poolSalt);\n _oracle.increaseObservationCardinalityNext(_observationCardinalityNext);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle) {\n bytes32 _poolSalt = getPoolSalt(_tokenA, _tokenB, _fee);\n _oracle = getPool(_poolSalt);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(bytes32 _poolSalt) public view returns (IOracleSidechain _oracle) {\n _oracle = IOracleSidechain(Create2Address.computeAddress(address(this), _poolSalt, ORACLE_INIT_CODE_HASH));\n if (address(_oracle).code.length == 0) return IOracleSidechain(address(0));\n }\n\n /// @inheritdoc IOracleFactory\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) public pure returns (bytes32 _poolSalt) {\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n _poolSalt = keccak256(abi.encode(_token0, _token1, _fee));\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(dataReceiver)) revert OnlyDataReceiver();\n _;\n }\n}\n" - }, - "solidity/for-test/DummyAdapterForTest.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\nimport {IDataReceiver} from '../interfaces/IDataReceiver.sol';\n\ncontract DummyAdapterForTest {\n // TODO: factorize interfaces so that this adapter can use same as sender/receiver\n event SentData(IDataReceiver, IOracleSidechain.ObservationData[]);\n event Create2Hash(bytes32);\n\n bool public ignoreTxs;\n\n constructor() {\n /// @dev Emitted to validate correct calculation of ORACLE_INIT_CODE_HASH\n emit Create2Hash(keccak256(type(OracleSidechain).creationCode));\n }\n\n function bridgeObservations(\n IDataReceiver _to,\n uint32,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable {\n if (!ignoreTxs) {\n _to.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n emit SentData(_to, _observationsData);\n }\n\n function setIgnoreTxs(bool _ignoreTxs) external {\n ignoreTxs = _ignoreTxs;\n }\n}\n" - }, - "solidity/contracts/DataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {IDataFeedStrategy, IUniswapV3Pool, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeedStrategy.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The DataFeed Strategy contract\n/// @notice Handles when and how a history of a pool should be updated\ncontract DataFeedStrategy is IDataFeedStrategy, Governable {\n /// @inheritdoc IDataFeedStrategy\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public periodDuration;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public strategyCooldown;\n\n /// @inheritdoc IDataFeedStrategy\n uint24 public twapThreshold;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public twapLength;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(\n address _governor,\n IDataFeed _dataFeed,\n StrategySettings memory _params\n ) Governable(_governor) {\n dataFeed = _dataFeed;\n _setStrategyCooldown(_params.cooldown);\n _setTwapLength(_params.twapLength);\n _setTwapThreshold(_params.twapThreshold);\n _setPeriodDuration(_params.periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n if (!_isStrategic(_poolSalt, _lastPoolStateObserved, _reason)) revert NotStrategic();\n uint32[] memory _secondsAgos = calculateSecondsAgos(_lastPoolStateObserved.blockTimestamp);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n emit StrategicFetch(_poolSalt, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n /// @dev Allows governor to choose a timestamp from which to send data (overcome !OLD error)\n function forceFetchObservations(bytes32 _poolSalt, uint32 _fromTimestamp) external onlyGovernor {\n uint32[] memory _secondsAgos = calculateSecondsAgos(_fromTimestamp);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setStrategyCooldown(uint32 _strategyCooldown) external onlyGovernor {\n _setStrategyCooldown(_strategyCooldown);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapLength(uint32 _twapLength) external onlyGovernor {\n _setTwapLength(_twapLength);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapThreshold(uint24 _twapThreshold) external onlyGovernor {\n _setTwapThreshold(_twapThreshold);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setPeriodDuration(uint32 _periodDuration) external onlyGovernor {\n _setPeriodDuration(_periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason) {\n if (isStrategic(_poolSalt, TriggerReason.TIME)) return TriggerReason.TIME;\n if (isStrategic(_poolSalt, TriggerReason.TWAP)) return TriggerReason.TWAP;\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) public view returns (bool _strategic) {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n return _isStrategic(_poolSalt, _lastPoolStateObserved, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function calculateSecondsAgos(uint32 _fromTimestamp) public view returns (uint32[] memory _secondsAgos) {\n if (_fromTimestamp == 0) return _initializeSecondsAgos();\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _timeSinceLastObservation = _secondsNow - _fromTimestamp;\n uint32 _periodDuration = periodDuration;\n uint32 _periods = _timeSinceLastObservation / _periodDuration;\n uint32 _remainder = _timeSinceLastObservation % _periodDuration;\n uint32 _i;\n\n if (_remainder != 0) {\n _secondsAgos = new uint32[](++_periods);\n _timeSinceLastObservation -= _remainder;\n _secondsAgos[_i++] = _timeSinceLastObservation;\n } else {\n _secondsAgos = new uint32[](_periods);\n }\n\n while (_timeSinceLastObservation > 0) {\n _timeSinceLastObservation -= _periodDuration;\n _secondsAgos[_i++] = _timeSinceLastObservation;\n }\n }\n\n function _isStrategic(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n TriggerReason _reason\n ) internal view returns (bool _strategic) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n if (_reason == TriggerReason.TIME) {\n return _secondsNow >= _lastPoolStateObserved.blockTimestamp + strategyCooldown;\n } else if (_reason == TriggerReason.TWAP) {\n return _twapIsOutOfThresholds(_poolSalt, _lastPoolStateObserved, _secondsNow);\n }\n }\n\n function _twapIsOutOfThresholds(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n uint32 _secondsNow\n ) internal view returns (bool _isOutOfThresholds) {\n uint32 _twapLength = twapLength;\n\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[0] = _twapLength;\n _secondsAgos[1] = 0;\n\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _poolTickCumulatives, ) = _pool.observe(_secondsAgos);\n\n int24 _poolArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _poolTickCumulatives[1], _twapLength);\n\n uint32 _oracleDelta = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n int56 _oracleTickCumulative = _lastPoolStateObserved.tickCumulative + int56(_lastPoolStateObserved.arithmeticMeanTick) * int32(_oracleDelta);\n\n int24 _oracleArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _oracleTickCumulative, _twapLength);\n\n return\n _poolArithmeticMeanTick > _oracleArithmeticMeanTick + int24(twapThreshold) ||\n _poolArithmeticMeanTick < _oracleArithmeticMeanTick - int24(twapThreshold);\n }\n\n function _computeTwap(\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n uint32 _delta\n ) internal pure returns (int24 _arithmeticMeanTick) {\n int56 _tickCumulativesDelta = _tickCumulative2 - _tickCumulative1;\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n }\n\n function _initializeSecondsAgos() internal view returns (uint32[] memory _secondsAgos) {\n // TODO: define initialization of _secondsAgos\n _secondsAgos = new uint32[](2);\n _secondsAgos[0] = periodDuration;\n _secondsAgos[1] = 0; // as if _fromTimestamp = _secondsNow - (periodDuration + 1)\n }\n\n function _setStrategyCooldown(uint32 _strategyCooldown) private {\n if (_strategyCooldown < twapLength) revert WrongSetting();\n\n strategyCooldown = _strategyCooldown;\n emit StrategyCooldownSet(_strategyCooldown);\n }\n\n function _setTwapLength(uint32 _twapLength) private {\n if ((_twapLength > strategyCooldown) || (_twapLength < periodDuration)) revert WrongSetting();\n\n twapLength = _twapLength;\n emit TwapLengthSet(_twapLength);\n }\n\n function _setTwapThreshold(uint24 _twapThreshold) private {\n twapThreshold = _twapThreshold;\n emit TwapThresholdSet(_twapThreshold);\n }\n\n function _setPeriodDuration(uint32 _periodDuration) private {\n if (_periodDuration > twapLength) revert WrongSetting();\n\n periodDuration = _periodDuration;\n emit PeriodDurationSet(_periodDuration);\n }\n}\n" - }, - "solidity/contracts/peripherals/Keep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './Governable.sol';\nimport {IKeep3rJob, IKeep3r} from '../../interfaces/peripherals/IKeep3rJob.sol';\n\nabstract contract Keep3rJob is IKeep3rJob, Governable {\n /// @inheritdoc IKeep3rJob\n IKeep3r public keep3r = IKeep3r(0xeb02addCfD8B773A5FFA6B9d1FE99c566f8c44CC);\n\n /// @inheritdoc IKeep3rJob\n function setKeep3r(IKeep3r _keep3r) public onlyGovernor {\n _setKeep3r(_keep3r);\n }\n\n function _setKeep3r(IKeep3r _keep3r) internal {\n keep3r = _keep3r;\n emit Keep3rSet(_keep3r);\n }\n\n function _isValidKeeper(address _keeper) internal virtual {\n if (!keep3r.isKeeper(_keeper)) revert KeeperNotValid();\n }\n\n modifier upkeep() {\n _isValidKeeper(msg.sender);\n _;\n keep3r.worked(msg.sender);\n }\n}\n" - }, - "solidity/for-test/Keep3rJobForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from '../contracts/peripherals/Keep3rJob.sol';\n\ncontract Keep3rJobForTest is Keep3rJob {\n constructor(address _governor) Governable(_governor) {}\n\n function internalIsValidKeeper(address _keeper) external {\n _isValidKeeper(_keeper);\n }\n}\n" - }, - "solidity/contracts/StrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from './peripherals/Keep3rJob.sol';\nimport {IStrategyJob, IDataFeedStrategy, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IStrategyJob.sol';\n\n/// @title The StrategyJob contract\n/// @notice Adds a reward layer for triggering fetch and bridge transactions\ncontract StrategyJob is IStrategyJob, Keep3rJob {\n /// @inheritdoc IStrategyJob\n IDataFeedStrategy public immutable dataFeedStrategy;\n\n /// @inheritdoc IStrategyJob\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IStrategyJob\n IBridgeSenderAdapter public defaultBridgeSenderAdapter;\n\n /// @inheritdoc IStrategyJob\n mapping(uint32 => mapping(bytes32 => uint24)) public lastPoolNonceBridged;\n\n constructor(\n address _governor,\n IDataFeedStrategy _dataFeedStrategy,\n IDataFeed _dataFeed,\n IBridgeSenderAdapter _defaultBridgeSenderAdapter\n ) Governable(_governor) {\n dataFeedStrategy = _dataFeedStrategy;\n dataFeed = _dataFeed;\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external upkeep {\n // TODO: change criteria for workable (if there's a new nonce, bridge)\n if (!_workable(_chainId, _poolSalt, _poolNonce)) revert NotWorkable();\n lastPoolNonceBridged[_chainId][_poolSalt] = _poolNonce;\n dataFeed.sendObservations(defaultBridgeSenderAdapter, _chainId, _poolSalt, _poolNonce, _observationsData);\n }\n\n /// @inheritdoc IStrategyJob\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external upkeep {\n dataFeedStrategy.strategicFetchObservations(_poolSalt, _reason);\n }\n\n /// @inheritdoc IStrategyJob\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external onlyGovernor {\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) public view returns (bool _isWorkable) {\n uint24 _whitelistedNonce = dataFeed.whitelistedNonces(_chainId, _poolSalt);\n if (_whitelistedNonce != 0 && _whitelistedNonce <= _poolNonce) return _workable(_chainId, _poolSalt, _poolNonce);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) public view returns (bool _isWorkable) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt, _reason);\n }\n\n function _workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal view returns (bool _isWorkable) {\n uint24 _lastPoolNonceBridged = lastPoolNonceBridged[_chainId][_poolSalt];\n if (_lastPoolNonceBridged == 0) {\n (uint24 _lastPoolNonceObserved, , , ) = dataFeed.lastPoolStateObserved(_poolSalt);\n return _poolNonce == _lastPoolNonceObserved;\n } else {\n return _poolNonce == ++_lastPoolNonceBridged;\n }\n }\n\n function _setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) private {\n defaultBridgeSenderAdapter = _defaultBridgeSenderAdapter;\n emit DefaultBridgeSenderAdapterSet(_defaultBridgeSenderAdapter);\n }\n}\n" - }, - "solidity/contracts/bridges/ConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {BridgeReceiverAdapter} from './BridgeReceiverAdapter.sol';\nimport {IConnext, IConnextReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IConnextReceiverAdapter.sol';\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextReceiverAdapter is BridgeReceiverAdapter, IXReceiver, IConnextReceiverAdapter {\n // The connectHandler contract on this domain\n IConnext public immutable connext;\n // The origin domain ID\n uint32 public immutable originDomain;\n // The DAO that's expected as the xcaller\n address public immutable source;\n\n constructor(\n IDataReceiver _dataReceiver,\n address _source,\n uint32 _originDomain,\n IConnext _connext\n ) BridgeReceiverAdapter(_dataReceiver) {\n source = _source;\n originDomain = _originDomain;\n connext = _connext;\n }\n\n function xReceive(\n bytes32, // _transferId\n uint256, // _amount\n address, // _asset\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external onlyExecutor(_originSender, _origin) returns (bytes memory) {\n (IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, uint24 _poolNonce) = abi.decode(\n _callData,\n (IOracleSidechain.ObservationData[], bytes32, uint24)\n );\n\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n return bytes(abi.encode(''));\n }\n\n modifier onlyExecutor(address _originSender, uint32 _originDomain) {\n if (msg.sender != address(connext) || _originSender != source || _originDomain != originDomain) revert UnauthorizedCaller();\n _;\n }\n}\n" - }, - "solidity/contracts/bridges/BridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IBridgeReceiverAdapter.sol';\n\nabstract contract BridgeReceiverAdapter is IBridgeReceiverAdapter {\n /// @inheritdoc IBridgeReceiverAdapter\n IDataReceiver public immutable dataReceiver;\n\n constructor(IDataReceiver _dataReceiver) {\n dataReceiver = _dataReceiver;\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n dataReceiver.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface IXReceiver {\n function xReceive(\n bytes32 _transferId,\n uint256 _amount,\n address _asset,\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external returns (bytes memory);\n}\n" - }, - "solidity/for-test/ConnextHandlerForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextHandlerForTest {\n uint32 public origin;\n\n constructor() {\n // TODO: set in constructor\n origin = 1111;\n }\n\n function xcall(\n uint32, // _destination, unique identifier for destination domain\n address _to, // recipient of funds, where calldata will be executed\n address, // _asset, asset being transferred\n address, // _delegate, permissioned address to recover in edgecases on destination domain\n uint256, // _amount, amount being transferred\n uint256, // _slippage, slippage in bps\n bytes calldata _callData // to be executed on _to on the destination domain\n ) external payable returns (bytes32) {\n IXReceiver(_to).xReceive({_transferId: 0, _amount: 0, _asset: address(0), _originSender: msg.sender, _origin: origin, _callData: _callData});\n\n return bytes32(abi.encode('random'));\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file diff --git a/deployments/optimism/solcInputs/eef40425e50b109f1821184fab9444c8.json b/deployments/optimism/solcInputs/eef40425e50b109f1821184fab9444c8.json deleted file mode 100644 index 13fa902..0000000 --- a/deployments/optimism/solcInputs/eef40425e50b109f1821184fab9444c8.json +++ /dev/null @@ -1,278 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "solidity/contracts/DataFeed.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {PipelineManagement, Governable} from './peripherals/PipelineManagement.sol';\nimport {IDataFeed, IDataFeedStrategy, IUniswapV3Pool, IConnextSenderAdapter, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeed.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The DataFeed interface\n/// @notice Queries UniV3Pools, stores history proofs on chain, handles data broadcast\ncontract DataFeed is IDataFeed, PipelineManagement {\n /// @inheritdoc IDataFeed\n IDataFeedStrategy public strategy;\n\n /// @inheritdoc IDataFeed\n mapping(bytes32 => PoolState) public lastPoolStateObserved;\n\n mapping(bytes32 => bool) internal _observedKeccak;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(address _governor, IDataFeedStrategy _strategy) Governable(_governor) {\n _setStrategy(_strategy);\n }\n\n /// @inheritdoc IDataFeed\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external validatePipeline(_chainId, _poolSalt, _poolNonce) {\n (uint32 _destinationDomainId, address _dataReceiver) = validateSenderAdapter(_bridgeSenderAdapter, _chainId);\n\n {\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _poolNonce, _observationsData));\n if (!_observedKeccak[_resultingKeccak]) revert UnknownHash();\n }\n\n _bridgeSenderAdapter.bridgeObservations(_dataReceiver, _destinationDomainId, _observationsData, _poolSalt, _poolNonce);\n emit DataBroadcast(_poolSalt, _poolNonce, _chainId, _dataReceiver, _bridgeSenderAdapter);\n }\n\n /// @inheritdoc IDataFeed\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external onlyStrategy validatePool(_poolSalt) {\n IOracleSidechain.ObservationData[] memory _observationsData;\n PoolState memory _lastPoolStateObserved = lastPoolStateObserved[_poolSalt];\n\n {\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _tickCumulatives, ) = _pool.observe(_secondsAgos);\n\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _secondsAgo;\n int56 _tickCumulative;\n int24 _arithmeticMeanTick;\n uint256 _secondsAgosLength = _secondsAgos.length;\n uint256 _i;\n\n // If first fetched observation\n if (_lastPoolStateObserved.blockTimestamp == 0) {\n if (_secondsAgosLength == 1) revert InvalidSecondsAgos();\n // Initializes timestamp and cumulative with first item\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength - 1);\n _secondsAgo = _secondsAgos[0];\n _tickCumulative = _tickCumulatives[0];\n // Skips first loop iteration\n // Cannot not calculate twap (there is no last tickCumulative)\n unchecked {\n ++_i;\n }\n } else {\n // Initializes timestamp and cumulative with cache\n _observationsData = new IOracleSidechain.ObservationData[](_secondsAgosLength);\n _secondsAgo = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n _tickCumulative = _lastPoolStateObserved.tickCumulative;\n }\n\n uint32 _delta;\n int56 _tickCumulativesDelta;\n uint256 _observationsDataIndex;\n\n for (; _i < _secondsAgosLength; ) {\n // Twap is calculated using the last recorded tickCumulative and time\n _tickCumulativesDelta = _tickCumulatives[_i] - _tickCumulative;\n _delta = _secondsAgo - _secondsAgos[_i];\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n\n // Stores blockTimestamp and tick in observations array\n _observationsData[_observationsDataIndex++] = IOracleSidechain.ObservationData({\n blockTimestamp: _secondsNow - _secondsAgo,\n tick: _arithmeticMeanTick\n });\n\n // Updates state for next iteration calculation\n _secondsAgo = _secondsAgos[_i];\n _tickCumulative = _tickCumulatives[_i];\n\n unchecked {\n ++_i;\n }\n }\n\n _lastPoolStateObserved = PoolState({\n poolNonce: _lastPoolStateObserved.poolNonce + 1,\n blockTimestamp: _secondsNow - _secondsAgo,\n tickCumulative: _tickCumulative,\n arithmeticMeanTick: _arithmeticMeanTick\n });\n }\n\n // Stores last pool state in the contract cache\n lastPoolStateObserved[_poolSalt] = _lastPoolStateObserved;\n\n // Whitelists keccak256 to be broadcast to other chains\n bytes32 _resultingKeccak = keccak256(abi.encode(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData));\n _observedKeccak[_resultingKeccak] = true;\n\n // Emits event with data to be read off-chain and used as broadcast input parameters\n emit PoolObserved(_poolSalt, _lastPoolStateObserved.poolNonce, _observationsData);\n }\n\n /// @inheritdoc IDataFeed\n function setStrategy(IDataFeedStrategy _strategy) external onlyGovernor {\n _setStrategy(_strategy);\n }\n\n function _setStrategy(IDataFeedStrategy _strategy) private {\n strategy = _strategy;\n emit StrategySet(_strategy);\n }\n\n modifier onlyStrategy() {\n if (msg.sender != address(strategy)) revert OnlyStrategy();\n _;\n }\n}\n" - }, - "solidity/contracts/peripherals/PipelineManagement.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './Governable.sol';\nimport {IPipelineManagement, IBridgeSenderAdapter} from '../../interfaces/peripherals/IPipelineManagement.sol';\nimport {IDataFeed} from '../../interfaces/IDataFeed.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\n\nabstract contract PipelineManagement is IPipelineManagement, Governable {\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n EnumerableSet.Bytes32Set private _whitelistedPools;\n\n /// @inheritdoc IPipelineManagement\n mapping(uint32 => mapping(bytes32 => uint24)) public whitelistedNonces;\n\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => bool) public whitelistedAdapters;\n\n // adapter => chainId => destinationDomain\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => uint32)) public destinationDomainIds;\n\n // adapter => destinationDomainId => dataReceiver\n /// @inheritdoc IPipelineManagement\n mapping(IBridgeSenderAdapter => mapping(uint32 => address)) public receivers;\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external onlyGovernor {\n _whitelistPipeline(_chainId, _poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external onlyGovernor {\n uint256 _chainIdsLength = _chainIds.length;\n if (_chainIdsLength != _poolSalts.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _chainIdsLength; ++_i) {\n _whitelistPipeline(_chainIds[_i], _poolSalts[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _whitelistAdapter(_bridgeSenderAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external onlyGovernor {\n _setDestinationDomainId(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n /// @inheritdoc IPipelineManagement\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _chainIds,\n uint32[] calldata _destinationDomainIds\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _chainIds.length || _bridgeSenderAdapterLength != _destinationDomainIds.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setDestinationDomainId(_bridgeSenderAdapters[_i], _chainIds[_i], _destinationDomainIds[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external onlyGovernor {\n _setReceiver(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n /// @inheritdoc IPipelineManagement\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external onlyGovernor {\n uint256 _bridgeSenderAdapterLength = _bridgeSenderAdapters.length;\n if (_bridgeSenderAdapterLength != _destinationDomainIds.length || _bridgeSenderAdapterLength != _dataReceivers.length)\n revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _bridgeSenderAdapterLength; ++_i) {\n _setReceiver(_bridgeSenderAdapters[_i], _destinationDomainIds[_i], _dataReceivers[_i]);\n }\n }\n }\n\n /// @inheritdoc IPipelineManagement\n function whitelistedPools() external view returns (bytes32[] memory) {\n return _whitelistedPools.values();\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return _whitelistedPools.contains(_poolSalt);\n }\n\n /// @inheritdoc IPipelineManagement\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted) {\n return whitelistedNonces[_chainId][_poolSalt] != 0;\n }\n\n /// @inheritdoc IPipelineManagement\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n public\n view\n returns (uint32 _destinationDomainId, address _dataReceiver)\n {\n if (!whitelistedAdapters[_bridgeSenderAdapter]) revert UnallowedAdapter();\n\n _destinationDomainId = destinationDomainIds[_bridgeSenderAdapter][_chainId];\n if (_destinationDomainId == 0) revert DestinationDomainIdNotSet();\n\n _dataReceiver = receivers[_bridgeSenderAdapter][_destinationDomainId];\n if (_dataReceiver == address(0)) revert ReceiverNotSet();\n }\n\n function _whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) internal {\n (uint24 _lastPoolNonceObserved, , , ) = IDataFeed(address(this)).lastPoolStateObserved(_poolSalt);\n whitelistedNonces[_chainId][_poolSalt] = _lastPoolNonceObserved + 1;\n _whitelistedPools.add(_poolSalt);\n emit PipelineWhitelisted(_chainId, _poolSalt, _lastPoolNonceObserved + 1);\n }\n\n function _whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_bridgeSenderAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_bridgeSenderAdapter, _isWhitelisted);\n }\n\n function _setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) internal {\n destinationDomainIds[_bridgeSenderAdapter][_chainId] = _destinationDomainId;\n emit DestinationDomainIdSet(_bridgeSenderAdapter, _chainId, _destinationDomainId);\n }\n\n function _setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) internal {\n receivers[_bridgeSenderAdapter][_destinationDomainId] = _dataReceiver;\n emit ReceiverSet(_bridgeSenderAdapter, _destinationDomainId, _dataReceiver);\n }\n\n modifier validatePool(bytes32 _poolSalt) {\n if (!_whitelistedPools.contains(_poolSalt)) revert UnallowedPool();\n _;\n }\n\n modifier validatePipeline(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) {\n uint24 _whitelistedNonce = whitelistedNonces[_chainId][_poolSalt];\n if (_whitelistedNonce == 0) revert UnallowedPipeline();\n if (_whitelistedNonce > _poolNonce) revert WrongNonce();\n _;\n }\n}\n" - }, - "solidity/interfaces/IDataFeed.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IPipelineManagement} from './peripherals/IPipelineManagement.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IConnextSenderAdapter} from './bridges/IConnextSenderAdapter.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IDataFeed is IPipelineManagement {\n // STRUCTS\n\n struct PoolState {\n uint24 poolNonce; // Nonce of the last observation\n uint32 blockTimestamp; // Last observed timestamp\n int56 tickCumulative; // Pool's tickCumulative at last observed timestamp\n int24 arithmeticMeanTick; // Last calculated twap\n }\n\n // STATE VARIABLES\n\n /// @return _strategy Address of the contract allowed to trigger an oracle update\n /// @dev The strategy should define when and with which timestamps the pool should be read\n function strategy() external view returns (IDataFeedStrategy _strategy);\n\n /// @notice Tracks the last observed pool state by salt\n /// @param _poolSalt The id of both the oracle and the pool\n /// @return _lastPoolNonceObserved Nonce of the last observation\n /// @return _lastBlockTimestampObserved Last observed timestamp\n /// @return _lastTickCumulativeObserved Pool's tickCumulative at last observed timestamp\n /// @return _lastArithmeticMeanTickObserved Last calculated twap\n function lastPoolStateObserved(bytes32 _poolSalt)\n external\n view\n returns (\n uint24 _lastPoolNonceObserved,\n uint32 _lastBlockTimestampObserved,\n int56 _lastTickCumulativeObserved,\n int24 _lastArithmeticMeanTickObserved\n );\n\n // EVENTS\n\n /// @notice Emitted when a data batch is broadcast\n /// @param _bridgeSenderAdapter Address of the bridge sender adapter\n /// @param _dataReceiver Address of the targetted contract receiving the data\n /// @param _chainId Identifier number of the targetted chain\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n event DataBroadcast(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n uint32 _chainId,\n address _dataReceiver,\n IBridgeSenderAdapter _bridgeSenderAdapter\n );\n\n /// @notice Emitted when a data batch is observed\n /// @param _poolSalt Identifier of the pool to which the data corresponds\n /// @param _poolNonce Identifier number of time period to which the data corresponds\n /// @param _observationsData Timestamp and tick data of the broadcast nonce\n event PoolObserved(bytes32 indexed _poolSalt, uint24 _poolNonce, IOracleSidechain.ObservationData[] _observationsData);\n\n /// @notice Emitted when the Strategy contract is set\n /// @param _strategy Address of the new strategy\n event StrategySet(IDataFeedStrategy _strategy);\n\n // ERRORS\n\n /// @notice Throws if set of secondsAgos is invalid to update the oracle\n error InvalidSecondsAgos();\n\n /// @notice Throws if an unknown dataset is being broadcast\n error UnknownHash();\n\n /// @notice Throws if a contract other than Strategy calls an update\n error OnlyStrategy();\n\n // FUNCTIONS\n\n /// @notice Broadcasts a validated set of datapoints to a bridge adapter\n /// @dev Permisionless, input parameters are validated to ensure being correct\n /// @param _bridgeSenderAdapter Address of the bridge adapter\n /// @param _chainId Identifier of the receiving chain\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _poolNonce Nonce identifier of the dataset\n /// @param _observationsData Array of tuples representing broadcast dataset\n function sendObservations(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Triggers an update of the oracle state\n /// @dev Permisioned, callable only by Strategy\n /// @param _poolSalt Identifier of the pool of the data broadcast\n /// @param _secondsAgos Set of time periods to consult the pool with\n function fetchObservations(bytes32 _poolSalt, uint32[] calldata _secondsAgos) external;\n\n /// @notice Updates the Strategy address\n /// @dev Permisioned, callable only by Governor\n /// @param _strategy Address of the new Strategy\n function setStrategy(IDataFeedStrategy _strategy) external;\n}\n" - }, - "solidity/libraries/Create2Address.sol": { - "content": "//SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.8 <0.9.0;\n\n/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee\nlibrary Create2Address {\n /// @notice Deterministically computes the pool address given the factory, salt and initCodeHash\n /// @param _factory The Uniswap V3 factory contract address\n /// @param _salt The PoolKey encoded bytes\n /// @param _initCodeHash The Init Code Hash of the target\n /// @return _pool The contract address of the target pool/oracle\n function computeAddress(\n address _factory,\n bytes32 _salt,\n bytes32 _initCodeHash\n ) internal pure returns (address _pool) {\n _pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', _factory, _salt, _initCodeHash)))));\n }\n}\n" - }, - "solidity/contracts/peripherals/Governable.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public governor;\n\n /// @inheritdoc IGovernable\n address public pendingGovernor;\n\n constructor(address _governor) {\n if (_governor == address(0)) revert ZeroAddress();\n governor = _governor;\n }\n\n /// @inheritdoc IGovernable\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\n _setPendingGovernor(_pendingGovernor);\n }\n\n /// @inheritdoc IGovernable\n function acceptPendingGovernor() external onlyPendingGovernor {\n _acceptPendingGovernor();\n }\n\n function _setPendingGovernor(address _pendingGovernor) internal {\n if (_pendingGovernor == address(0)) revert ZeroAddress();\n pendingGovernor = _pendingGovernor;\n emit PendingGovernorSet(governor, pendingGovernor);\n }\n\n function _acceptPendingGovernor() internal {\n governor = pendingGovernor;\n pendingGovernor = address(0);\n emit PendingGovernorAccepted(governor);\n }\n\n modifier onlyGovernor() {\n if (msg.sender != governor) revert OnlyGovernor();\n _;\n }\n\n modifier onlyPendingGovernor() {\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\n _;\n }\n}\n" - }, - "solidity/interfaces/peripherals/IPipelineManagement.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './IGovernable.sol';\nimport {IBridgeSenderAdapter} from '../bridges/IBridgeSenderAdapter.sol';\n\ninterface IPipelineManagement is IGovernable {\n // STATE VARIABLES\n\n function whitelistedNonces(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _whitelistedNonce);\n\n function whitelistedAdapters(IBridgeSenderAdapter _bridgeSenderAdapter) external view returns (bool _isWhitelisted);\n\n function destinationDomainIds(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId) external view returns (uint32 _destinationDomainId);\n\n function receivers(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId) external view returns (address _dataReceiver);\n\n // EVENTS\n\n event PipelineWhitelisted(uint32 _chainId, bytes32 indexed _poolSalt, uint24 _whitelistedNonce);\n\n event AdapterWhitelisted(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted);\n\n event DestinationDomainIdSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId, uint32 _destinationDomainId);\n\n event ReceiverSet(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _destinationDomainId, address _dataReceiver);\n\n // ERRORS\n\n error UnallowedPool();\n\n error UnallowedPipeline();\n\n error WrongNonce();\n\n error UnallowedAdapter();\n\n error DestinationDomainIdNotSet();\n\n error ReceiverNotSet();\n\n error LengthMismatch();\n\n // FUNCTIONS\n\n function whitelistPipeline(uint32 _chainId, bytes32 _poolSalt) external;\n\n function whitelistPipelines(uint32[] calldata _chainIds, bytes32[] calldata _poolSalts) external;\n\n function whitelistAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, bool _isWhitelisted) external;\n\n function whitelistAdapters(IBridgeSenderAdapter[] calldata _bridgeSenderAdapters, bool[] calldata _isWhitelisted) external;\n\n function setDestinationDomainId(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _chainId,\n uint32 _destinationDomainId\n ) external;\n\n function setDestinationDomainIds(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapter,\n uint32[] calldata _chainId,\n uint32[] calldata _destinationDomainId\n ) external;\n\n function setReceiver(\n IBridgeSenderAdapter _bridgeSenderAdapter,\n uint32 _destinationDomainId,\n address _dataReceiver\n ) external;\n\n function setReceivers(\n IBridgeSenderAdapter[] calldata _bridgeSenderAdapters,\n uint32[] calldata _destinationDomainIds,\n address[] calldata _dataReceivers\n ) external;\n\n function whitelistedPools() external view returns (bytes32[] memory);\n\n function isWhitelistedPool(bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n function isWhitelistedPipeline(uint32 _chainId, bytes32 _poolSalt) external view returns (bool _isWhitelisted);\n\n function validateSenderAdapter(IBridgeSenderAdapter _bridgeSenderAdapter, uint32 _chainId)\n external\n view\n returns (uint32 _destinationDomainId, address _dataReceiver);\n}\n" - }, - "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 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 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 => 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 return _values(set._inner);\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 on 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" - }, - "solidity/interfaces/peripherals/IGovernable.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\ninterface IGovernable {\n // STATE VARIABLES\n\n /// @return _governor Address of the current governor\n function governor() external view returns (address _governor);\n\n /// @return _pendingGovernor Address of the current pending governor\n function pendingGovernor() external view returns (address _pendingGovernor);\n\n // EVENTS\n\n /// @notice Emitted when a new pending governor is set\n /// @param _governor Address of the current governor\n /// @param _pendingGovernor Address of the proposed next governor\n event PendingGovernorSet(address _governor, address _pendingGovernor);\n\n /// @notice Emitted when a new governor is set\n /// @param _newGovernor Address of the new governor\n event PendingGovernorAccepted(address _newGovernor);\n\n // ERRORS\n\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n\n /// @notice Throws if a non-governor user tries to call a OnlyGovernor function\n error OnlyGovernor();\n\n /// @notice Throws if a non-pending-governor user tries to call a OnlyPendingGovernor function\n error OnlyPendingGovernor();\n\n // FUNCTIONS\n\n /// @notice Allows a governor to propose a new governor\n /// @param _pendingGovernor Address of the proposed new governor\n function setPendingGovernor(address _pendingGovernor) external;\n\n /// @notice Allows a proposed governor to accept the governance\n function acceptPendingGovernor() external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeSenderAdapter {\n // FUNCTIONS\n\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable;\n\n // ERRORS\n\n error OnlyDataFeed();\n}\n" - }, - "solidity/interfaces/IOracleSidechain.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleFactory} from './IOracleFactory.sol';\n\ninterface IOracleSidechain {\n // STRUCTS\n\n struct ObservationData {\n uint32 blockTimestamp;\n int24 tick;\n }\n\n // STATE VARIABLES\n\n // TODO: complete natspec\n\n /// @return _oracleFactory The address of the OracleFactory\n function factory() external view returns (IOracleFactory _oracleFactory);\n\n /// @return _token0 The mainnet address of the Token0 of the oracle\n function token0() external view returns (address _token0);\n\n /// @return _token1 The mainnet address of the Token1 of the oracle\n function token1() external view returns (address _token1);\n\n /// @return _fee The fee identifier of the pool\n function fee() external view returns (uint24 _fee);\n\n /// @return _poolSalt The identifier of both the pool and the oracle\n function poolSalt() external view returns (bytes32 _poolSalt);\n\n /// @return _poolNonce Last recorded nonce of the pool history\n function poolNonce() external view returns (uint24 _poolNonce);\n\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\n /// @return _tick Used to maintain compatibility with Uniswap V3\n /// @return _observationIndex The index of the last oracle observation that was written,\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\n /// @return _unlocked Used to track if a pool information was already verified\n function slot0()\n external\n view\n returns (\n uint160 _sqrtPriceX96,\n int24 _tick,\n uint16 _observationIndex,\n uint16 _observationCardinality,\n uint16 _observationCardinalityNext,\n uint8 _feeProtocol,\n bool _unlocked\n );\n\n /// @notice Returns data about a specific observation index\n /// @param _index The element of the observations array to fetch\n /// @return _blockTimestamp The timestamp of the observation,\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return _initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 _index)\n external\n view\n returns (\n uint32 _blockTimestamp,\n int56 _tickCumulative,\n uint160 _secondsPerLiquidityCumulativeX128,\n bool _initialized\n );\n\n // EVENTS\n\n /// @notice Emitted when the pool information is verified\n /// @param _poolSalt Identifier of the pool and the oracle\n /// @param _token0 The contract address of either token0 or token1\n /// @param _token1 The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\n\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param _tick The log base 1.0001 of price of the pool after the swap\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\n\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\n\n // ERRORS\n\n error AI();\n error InvalidPool();\n error OnlyDataReceiver();\n error OnlyFactory();\n\n // FUNCTIONS\n\n /// @notice Permisionless method to verify token0, token1 and fee\n /// @dev Before verified, token0 and token1 views will return address(0)\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external;\n\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\n\n /// @notice Permisioned method to push a dataset to update\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolNonce Nonce of the observation broadcast\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\n\n /// @notice Permisioned method to increase the cardinalityNext value\n /// @param _observationCardinalityNext The new next length of the observations array\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\n}\n" - }, - "solidity/interfaces/IOracleFactory.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IDataReceiver} from './IDataReceiver.sol';\n\ninterface IOracleFactory is IGovernable {\n // STRUCTS\n\n struct OracleParameters {\n bytes32 poolSalt; // Identifier of the pool and oracle\n uint24 poolNonce; // Initial nonce of the deployed pool\n uint16 cardinality; // Initial cardinality of the deployed pool\n }\n\n // STATE VARIABLES\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /// @return _poolSalt The id of both the oracle and the pool\n /// @return _poolNonce The initial nonce of the pool data\n /// @return _cardinality The size of the observations memory storage\n function oracleParameters()\n external\n view\n returns (\n bytes32 _poolSalt,\n uint24 _poolNonce,\n uint16 _cardinality\n );\n\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function initialCardinality() external view returns (uint16 _initialCardinality);\n\n // EVENTS\n\n /// @notice Emitted when a new oracle is deployed\n /// @param _poolSalt The id of both the oracle and the pool\n /// @param _oracle The address of the deployed oracle\n /// @param _initialNonce The initial nonce of the pool data\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\n\n /// @notice Emitted when a new DataReceiver is set\n /// @param _dataReceiver The address of the new DataReceiver\n event DataReceiverSet(IDataReceiver _dataReceiver);\n\n /// @notice Emitted when a new initial oracle cardinality is set\n /// @param _initialCardinality The initial length of the observationCardinality array\n event InitialCardinalitySet(uint16 _initialCardinality);\n\n // ERRORS\n\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\n error OnlyDataReceiver();\n\n // FUNCTIONS\n\n /// @notice Deploys a new oracle given an inputted salt\n /// @dev Requires that the salt has not been deployed before\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\n /// @return _oracle The address of the newly deployed oracle\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\n\n /// @notice Allows governor to set a new allowed dataReceiver\n /// @dev Will disallow the previous dataReceiver\n /// @param _dataReceiver The address of the new allowed dataReceiver\n function setDataReceiver(IDataReceiver _dataReceiver) external;\n\n /// @notice Allows governor to set a new initial cardinality for new oracles\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\n function setInitialCardinality(uint16 _initialCardinality) external;\n\n /// @notice Overrides UniV3Factory getPool mapping\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _oracle The oracle address\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle);\n\n /// @notice Tracks the addresses of the oracle by poolSalt\n /// @param _poolSalt Identifier of both the pool and the oracle\n /// @return _oracle The address (if deployed) of the correspondant oracle\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\n\n /// @param _tokenA The contract address of either token0 or token1\n /// @param _tokenB The contract address of the other token\n /// @param _fee The fee denominated in hundredths of a bip\n /// @return _poolSalt Pool salt for inquired parameters\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (bytes32 _poolSalt);\n}\n" - }, - "solidity/interfaces/IDataReceiver.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IOracleFactory} from './IOracleFactory.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\n\ninterface IDataReceiver is IGovernable {\n // STATE VARIABLES\n\n /// @return _oracleFactory The address of the OracleFactory\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\n\n /// @notice Tracks already deployed oracles\n /// @param _poolSalt The identifier of the oracle\n /// @return _deployedOracle The address of the correspondant Oracle\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\n\n /// @notice Tracks the whitelisting of bridge adapters\n /// @param _adapter Address of the bridge adapter to consult\n /// @return _isAllowed Whether a bridge adapter is whitelisted\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\n\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\n //solhint-disable-next-line func-name-mixedcase\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\n\n // EVENTS\n\n /// @notice Emitted when a broadcast observation is succesfully processed\n /// @param _poolSalt Identifier of the pool to fetch\n /// @return _poolNonce Nonce of the observation broadcast\n /// @return _observationsData Array of tuples containing the dataset\n /// @return _receiverAdapter Handler of the broadcast\n event ObservationsAdded(\n bytes32 indexed _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] _observationsData,\n address _receiverAdapter\n );\n\n /// @notice Emitted when a new adapter whitelisting rule is set\n /// @param _adapter Address of the adapter\n /// @param _isAllowed New whitelisting status\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\n\n // ERRORS\n\n /// @notice Thrown when the broadcast nonce is incorrect\n error ObservationsNotWritable();\n\n /// @notice Thrown when a not-whitelisted adapter triggers an update\n error UnallowedAdapter();\n\n /// @notice Thrown when mismatching lists length\n error LengthMismatch();\n\n // FUNCTIONS\n\n /// @notice Allows whitelisted bridge adapters to push a broadcast\n /// @param _observationsData Array of tuples containing the dataset\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _poolNonce Nonce of the observation broadcast\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external;\n\n /// @notice Allows governance to set an adapter whitelisted state\n /// @param _receiverAdapter Address of the adapter\n /// @param _isWhitelisted New whitelisting status\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\n\n /// @notice Allows governance to batch set adapters whitelisted state\n /// @param _receiverAdapters Array of addresses of the adapter\n /// @param _isWhitelisted Array of whitelisting status for each address\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\n}\n" - }, - "solidity/interfaces/bridges/IBridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IDataReceiver} from '../IDataReceiver.sol';\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\n\ninterface IBridgeReceiverAdapter {\n // FUNCTIONS\n\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\n\n /* NOTE: callback methods should be here declared */\n\n // ERRORS\n\n error UnauthorizedCaller();\n}\n" - }, - "solidity/interfaces/IDataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './peripherals/IGovernable.sol';\nimport {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\n\ninterface IDataFeedStrategy is IGovernable {\n // ENUMS\n\n enum TriggerReason {\n NONE,\n TIME,\n TWAP\n }\n\n // STRUCTS\n\n struct StrategySettings {\n uint32 periodDuration; // Resolution of the oracle, target twap length\n uint32 cooldown; // Time since last update to wait to time-trigger update\n uint24 twapThreshold; // Twap difference, in ticks, to twap-trigger update\n uint32 twapLength; // Twap length, in seconds, used for twap-trigger update\n }\n\n // STATE VARIABLES\n\n /// @return _dataFeed The address of the DataFeed contract\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _strategyCooldown Time in seconds since last update required to time-trigger an update\n function strategyCooldown() external view returns (uint32 _strategyCooldown);\n\n /// @return _periodDuration The targetted amount of seconds between pool consultations\n /// @dev Defines the resolution of the oracle, averaging data between consultations\n function periodDuration() external view returns (uint32 _periodDuration);\n\n /// @return _twapThreshold Twap difference, in ticks, to twap-trigger an update\n function twapThreshold() external view returns (uint24 _twapThreshold);\n\n /// @return _twapLength The time length, in seconds, used to calculate twap-trigger\n function twapLength() external view returns (uint32 _twapLength);\n\n // EVENTS\n\n /// @notice Emitted when a data fetch is triggered\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier number of the reason that triggered the fetch request\n event StrategicFetch(bytes32 indexed _poolSalt, TriggerReason _reason);\n\n /// @notice Emitted when the owner updates the job cooldown\n /// @param _strategyCooldown The new job cooldown\n event StrategyCooldownSet(uint32 _strategyCooldown);\n\n /// @notice Emitted when the owner updates the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n event TwapLengthSet(uint32 _twapLength);\n\n /// @notice Emitted when the owner updates the job twap threshold percentage\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n event TwapThresholdSet(uint24 _twapThreshold);\n\n /// @notice Emitted when the owner updates the job period length\n /// @param _periodDuration The new length of reading resolution periods\n event PeriodDurationSet(uint32 _periodDuration);\n\n // ERRORS\n\n /// @notice Thrown if the tx is not strategic\n error NotStrategic();\n\n /// @notice Thrown if setting breaks strategyCooldown >= twapLength >= periodDuration\n error WrongSetting();\n\n // FUNCTIONS\n\n /// @notice Permisionless, used to update the oracle state\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _reason Identifier of trigger reason (time/twap)\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external;\n\n /// @notice Permisioned, used to update the oracle state from a given timestamp\n /// @param _poolSalt Identifier of the pool to fetch\n /// @param _fromTimestamp Timestamp to start backfilling from\n function forceFetchObservations(bytes32 _poolSalt, uint32 _fromTimestamp) external;\n\n /// @notice Sets the job cooldown\n /// @param _strategyCooldown The job cooldown to be set\n function setStrategyCooldown(uint32 _strategyCooldown) external;\n\n /// @notice Sets the job twap length\n /// @param _twapLength The new length of the twap used to trigger an update of the oracle\n function setTwapLength(uint32 _twapLength) external;\n\n /// @notice Sets the job twap threshold percentage\n /// @param _twapThreshold The twap difference threshold used to trigger an update of the oracle\n function setTwapThreshold(uint24 _twapThreshold) external;\n\n /// @notice Sets the job period length\n /// @param _periodDuration The new length of reading resolution periods\n function setPeriodDuration(uint32 _periodDuration) external;\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the strategy can be executed\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason);\n\n /// @notice Returns if the strategy can be executed\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the strategy can be executed\n /// @return _isStrategic Whether the tx is strategic or not\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) external view returns (bool _isStrategic);\n\n /// @notice Builds the secondsAgos array with periodDuration between each datapoint\n /// @param _fromTimestamp Timestamp from which to backfill the oracle with\n /// @return _secondsAgos Array of secondsAgo that backfills the history from fromTimestamp\n function calculateSecondsAgos(uint32 _fromTimestamp) external view returns (uint32[] memory _secondsAgos);\n}\n" - }, - "solidity/interfaces/bridges/IConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeSenderAdapter, IOracleSidechain} from './IBridgeSenderAdapter.sol';\nimport {IDataFeed} from '../IDataFeed.sol';\n\ninterface IConnextSenderAdapter is IBridgeSenderAdapter {\n // STATE VARIABLES\n\n function connext() external view returns (IConnext _connext);\n\n function dataFeed() external view returns (IDataFeed _dataFeed);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport {IUniswapV3PoolImmutables} from './pool/IUniswapV3PoolImmutables.sol';\nimport {IUniswapV3PoolState} from './pool/IUniswapV3PoolState.sol';\nimport {IUniswapV3PoolDerivedState} from './pool/IUniswapV3PoolDerivedState.sol';\nimport {IUniswapV3PoolActions} from './pool/IUniswapV3PoolActions.sol';\nimport {IUniswapV3PoolOwnerActions} from './pool/IUniswapV3PoolOwnerActions.sol';\nimport {IUniswapV3PoolErrors} from './pool/IUniswapV3PoolErrors.sol';\nimport {IUniswapV3PoolEvents} from './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolErrors,\n IUniswapV3PoolEvents\n{\n\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// @return tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// @return observationIndex The index of the last oracle observation that was written,\n /// @return observationCardinality The current maximum number of observations stored in the pool,\n /// @return observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// @return feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n /// @return The liquidity at the current price of the pool\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper\n /// @return liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// @return feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// @return feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// @return tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// @return secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// @return secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// @return initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return liquidity The amount of liquidity in the position,\n /// @return feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// @return feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// @return tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// @return tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// @return tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// @return secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// @return initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolErrors.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Errors emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolErrors {\n error LOK();\n error TLU();\n error TLM();\n error TUM();\n error AI();\n error M0();\n error M1();\n error AS();\n error IIA();\n error L();\n error F0();\n error F1();\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {ExecuteArgs, TransferInfo, TokenId, DestinationTransferStatus} from \"../libraries/LibConnextStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {SwapUtils} from \"../libraries/SwapUtils.sol\";\n\nimport {IStableSwap} from \"./IStableSwap.sol\";\n\nimport {IDiamondCut} from \"./IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\ninterface IConnext is IDiamondLoupe, IDiamondCut {\n // TokenFacet\n function canonicalToAdopted(bytes32 _key) external view returns (address);\n\n function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\n\n function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\n\n function canonicalToRepresentation(bytes32 _key) external view returns (address);\n\n function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\n\n function representationToCanonical(address _adopted) external view returns (TokenId memory);\n\n function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\n\n function approvedAssets(bytes32 _key) external view returns (bool);\n\n function approvedAssets(TokenId calldata _canonical) external view returns (bool);\n\n function adoptedToLocalPools(bytes32 _key) external view returns (IStableSwap);\n\n function adoptedToLocalPools(TokenId calldata _canonical) external view returns (IStableSwap);\n\n function getTokenId(address _candidate) external view returns (TokenId memory);\n\n function setupAsset(\n TokenId calldata _canonical,\n uint8 _canonicalDecimals,\n string memory _representationName,\n string memory _representationSymbol,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function setupAssetWithDeployedRepresentation(\n TokenId calldata _canonical,\n address _representation,\n address _adoptedAssetId,\n address _stableSwapPool,\n uint256 _cap\n ) external returns (address);\n\n function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\n\n function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\n\n function removeAssetId(\n bytes32 _key,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function removeAssetId(\n TokenId calldata _canonical,\n address _adoptedAssetId,\n address _representation\n ) external;\n\n function updateDetails(\n TokenId calldata _canonical,\n string memory _name,\n string memory _symbol\n ) external;\n\n // BaseConnextFacet\n\n // BridgeFacet\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\n\n function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\n\n function remote(uint32 _domain) external view returns (address);\n\n function domain() external view returns (uint256);\n\n function nonce() external view returns (uint256);\n\n function approvedSequencers(address _sequencer) external view returns (bool);\n\n function xAppConnectionManager() external view returns (address);\n\n function addConnextion(uint32 _domain, address _connext) external;\n\n function addSequencer(address _sequencer) external;\n\n function removeSequencer(address _sequencer) external;\n\n function xcall(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function xcallIntoLocal(\n uint32 _destination,\n address _to,\n address _asset,\n address _delegate,\n uint256 _amount,\n uint256 _slippage,\n bytes calldata _callData\n ) external payable returns (bytes32);\n\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\n\n function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\n\n function bumpTransfer(bytes32 _transferId) external payable;\n\n function setXAppConnectionManager(address _xAppConnectionManager) external;\n\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n function enrollCustom(\n uint32 _domain,\n bytes32 _id,\n address _custom\n ) external;\n\n // InboxFacet\n\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external;\n\n // ProposedOwnableFacet\n\n function owner() external view returns (address);\n\n function routerWhitelistRemoved() external view returns (bool);\n\n function assetWhitelistRemoved() external view returns (bool);\n\n function proposed() external view returns (address);\n\n function proposedTimestamp() external view returns (uint256);\n\n function routerWhitelistTimestamp() external view returns (uint256);\n\n function assetWhitelistTimestamp() external view returns (uint256);\n\n function delay() external view returns (uint256);\n\n function proposeRouterWhitelistRemoval() external;\n\n function removeRouterWhitelist() external;\n\n function proposeAssetWhitelistRemoval() external;\n\n function removeAssetWhitelist() external;\n\n function renounced() external view returns (bool);\n\n function proposeNewOwner(address newlyProposed) external;\n\n function renounceOwnership() external;\n\n function acceptProposedOwner() external;\n\n function pause() external;\n\n function unpause() external;\n\n // RelayerFacet\n function approvedRelayers(address _relayer) external view returns (bool);\n\n function relayerFeeVault() external view returns (address);\n\n function setRelayerFeeVault(address _relayerFeeVault) external;\n\n function addRelayer(address _relayer) external;\n\n function removeRelayer(address _relayer) external;\n\n // RoutersFacet\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\n\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\n\n function getRouterApproval(address _router) external view returns (bool);\n\n function getRouterRecipient(address _router) external view returns (address);\n\n function getRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwner(address _router) external view returns (address);\n\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\n\n function maxRoutersPerTransfer() external view returns (uint256);\n\n function routerBalances(address _router, address _asset) external view returns (uint256);\n\n function getRouterApprovalForPortal(address _router) external view returns (bool);\n\n function setupRouter(\n address router,\n address owner,\n address recipient\n ) external;\n\n function removeRouter(address router) external;\n\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\n\n function setLiquidityFeeNumerator(uint256 _numerator) external;\n\n function approveRouterForPortal(address _router) external;\n\n function unapproveRouterForPortal(address _router) external;\n\n function setRouterRecipient(address router, address recipient) external;\n\n function proposeRouterOwner(address router, address proposed) external;\n\n function acceptProposedRouterOwner(address router) external;\n\n function addRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address _router\n ) external payable;\n\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\n\n function removeRouterLiquidityFor(\n uint256 _amount,\n address _local,\n address payable _to,\n address _router\n ) external;\n\n function removeRouterLiquidity(\n uint256 _amount,\n address _local,\n address payable _to\n ) external;\n\n // PortalFacet\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\n\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\n\n function aavePool() external view returns (address);\n\n function aavePortalFee() external view returns (uint256);\n\n function setAavePool(address _aavePool) external;\n\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\n\n function repayAavePortal(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount,\n uint256 _maxIn\n ) external;\n\n function repayAavePortalFor(\n TransferInfo calldata _params,\n uint256 _backingAmount,\n uint256 _feeAmount\n ) external;\n\n // StableSwapFacet\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\n\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\n\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\n\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\n\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\n\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\n\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\n\n function calculateSwap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapTokenAmount(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n bool deposit\n ) external view returns (uint256);\n\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) external view returns (uint256);\n\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\n\n function swap(\n bytes32 canonicalId,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n bytes32 canonicalId,\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n bytes32 canonicalId,\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function addSwapLiquidity(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidity(\n bytes32 canonicalId,\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeSwapLiquidityOneToken(\n bytes32 canonicalId,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeSwapLiquidityImbalance(\n bytes32 canonicalId,\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n\n // SwapAdminFacet\n\n function initializeSwap(\n bytes32 _canonicalId,\n IERC20[] memory _pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 _a,\n uint256 _fee,\n uint256 _adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\n\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\n\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\n\n function rampA(\n bytes32 canonicalId,\n uint256 futureA,\n uint256 futureTime\n ) external;\n\n function stopRampA(bytes32 canonicalId) external;\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\nimport {IConnectorManager} from \"../../../messaging/interfaces/IConnectorManager.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n// ============= Enum =============\n\n/// @notice Enum representing address role\n// Returns uint\n// None - 0\n// Router - 1\n// Watcher - 2\n// Admin - 3\nenum Role {\n None,\n Router,\n Watcher,\n Admin\n}\n\n/**\n * @notice Enum representing status of destination transfer\n * @dev Status is only assigned on the destination domain, will always be \"none\" for the\n * origin domains\n * @return uint - Index of value in enum\n */\nenum DestinationTransferStatus {\n None, // 0\n Reconciled, // 1\n Executed, // 2\n Completed // 3 - executed + reconciled\n}\n\n// ============= Structs =============\n\nstruct TokenId {\n uint32 domain;\n bytes32 id;\n}\n\n/**\n * @notice These are the parameters that will remain constant between the\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\n * @property to - The account that receives funds, in the event of a crosschain call,\n * will receive funds if the call fails.\n *\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\n * @param canonicalDomain - The canonical domain of the asset you are bridging\n * @param to - The address you are sending funds (and potentially data) to\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\n * a user takes 1% slippage, this is expressed as 1_000)\n * @param originSender - The msg.sender of the xcall\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\n */\nstruct TransferInfo {\n uint32 originDomain;\n uint32 destinationDomain;\n uint32 canonicalDomain;\n address to;\n address delegate;\n bool receiveLocal;\n bytes callData;\n uint256 slippage;\n address originSender;\n uint256 bridgedAmt;\n uint256 normalizedIn;\n uint256 nonce;\n bytes32 canonicalId;\n}\n\n/**\n * @notice\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\n * @param routers - The routers who you are sending the funds on behalf of.\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\n * for the signed transfer ID.\n * @param sequencer - The sequencer who assigned the router path to this transfer.\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\n * for the path that was signed.\n */\nstruct ExecuteArgs {\n TransferInfo params;\n address[] routers;\n bytes[] routerSignatures;\n address sequencer;\n bytes sequencerSignature;\n}\n\n/**\n * @notice Contains RouterFacet related state\n * @param approvedRouters - Mapping of whitelisted router addresses\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\n * (if configured) or the router itself\n * @param routerOwners - Mapping of router owners\n * If set, can update the routerRecipient\n * @param proposedRouterOwners - Mapping of proposed router owners\n * Must wait timeout to set the\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\n * When accepting a proposed owner, must wait for delay to elapse\n */\nstruct RouterPermissionsManagerInfo {\n mapping(address => bool) approvedRouters;\n mapping(address => bool) approvedForPortalRouters;\n mapping(address => address) routerRecipients;\n mapping(address => address) routerOwners;\n mapping(address => address) proposedRouterOwners;\n mapping(address => uint256) proposedRouterTimestamp;\n}\n\nstruct AppStorage {\n //\n // 0\n bool initialized;\n //\n // Connext\n //\n // 1\n uint256 LIQUIDITY_FEE_NUMERATOR;\n /**\n * @notice The local address that is custodying relayer fees\n */\n // 2\n address relayerFeeVault;\n /**\n * @notice Nonce for the contract, used to keep unique transfer ids.\n * @dev Assigned at first interaction (xcall on origin domain).\n */\n // 3\n uint256 nonce;\n /**\n * @notice The domain this contract exists on.\n * @dev Must match the nomad domain, which is distinct from the \"chainId\".\n */\n // 4\n uint32 domain;\n /**\n * @notice Mapping holding the AMMs for swapping in and out of local assets.\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon).\n * This mapping is keyed on the hash of the canonical id + domain for local asset.\n */\n // 6\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\n /**\n * @notice Mapping of whitelisted assets on same domain as contract.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => bool) approvedAssets;\n /**\n * @notice Mapping of liquidity caps of whitelisted assets. If 0, no cap is enforced.\n * @dev Mapping is keyed on the hash of the canonical id and domain\n */\n // 7\n mapping(bytes32 => uint256) caps;\n /**\n * @notice Mapping of adopted to canonical asset information.\n * @dev If the adopted asset is the native asset, the keyed address will\n * be the wrapped asset address.\n */\n // 8\n mapping(address => TokenId) adoptedToCanonical;\n /**\n * @notice Mapping of representation to canonical asset information.\n */\n // 9\n mapping(address => TokenId) representationToCanonical;\n /**\n * @notice Mapping of hash(canonicalId, canonicalDomain) to adopted asset on this domain.\n * @dev If the adopted asset is the native asset, the stored address will be the\n * wrapped asset address.\n */\n // 10\n mapping(bytes32 => address) canonicalToAdopted;\n /**\n * @notice Mapping of canonical to representation asset information.\n * @dev If the token is of local origin (meaning it was originanlly deployed on this chain),\n * this MUST map to address(0).\n */\n // 11\n mapping(bytes32 => address) canonicalToRepresentation;\n /**\n * @notice Mapping to track transfer status on destination domain\n */\n // 12\n mapping(bytes32 => DestinationTransferStatus) transferStatus;\n /**\n * @notice Mapping holding router address that provided fast liquidity.\n */\n // 13\n mapping(bytes32 => address[]) routedTransfers;\n /**\n * @notice Mapping of router to available balance of an asset.\n * @dev Routers should always store liquidity that they can expect to receive via the bridge on\n * this domain (the nomad local asset).\n */\n // 14\n mapping(address => mapping(address => uint256)) routerBalances;\n /**\n * @notice Mapping of approved relayers\n * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\n */\n // 15\n mapping(address => bool) approvedRelayers;\n /**\n * @notice The max amount of routers a payment can be routed through.\n */\n // 18\n uint256 maxRoutersPerTransfer;\n /**\n * @notice Stores a mapping of transfer id to slippage overrides.\n */\n // 20\n mapping(bytes32 => uint256) slippage;\n /**\n * @notice Stores a mapping of remote routers keyed on domains.\n * @dev Addresses are cast to bytes32.\n * This mapping is required because the Connext now contains the BridgeRouter and must implement\n * the remotes interface.\n */\n // 21\n mapping(uint32 => bytes32) remotes;\n //\n // ProposedOwnable\n //\n // 22\n address _proposed;\n // 23\n uint256 _proposedOwnershipTimestamp;\n // 24\n bool _routerWhitelistRemoved;\n // 25\n uint256 _routerWhitelistTimestamp;\n // 26\n bool _assetWhitelistRemoved;\n // 27\n uint256 _assetWhitelistTimestamp;\n /**\n * @notice Stores a mapping of address to Roles\n * @dev returns uint representing the enum Role value\n */\n // 28\n mapping(address => Role) roles;\n //\n // RouterFacet\n //\n // 29\n RouterPermissionsManagerInfo routerPermissionInfo;\n //\n // ReentrancyGuard\n //\n // 30\n uint256 _status;\n //\n // StableSwap\n //\n /**\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\n * Struct storing data responsible for automatic market maker functionalities. In order to\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\n */\n // 31\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\n /**\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\n */\n // 32\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\n /**\n * @notice Stores whether or not bribing, AMMs, have been paused.\n */\n // 33\n bool _paused;\n //\n // AavePortals\n //\n /**\n * @notice Address of Aave Pool contract.\n */\n // 34\n address aavePool;\n /**\n * @notice Fee percentage numerator for using Portal liquidity.\n * @dev Assumes the same basis points as the liquidity fee.\n */\n // 35\n uint256 aavePortalFeeNumerator;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 36\n mapping(bytes32 => uint256) portalDebt;\n /**\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n */\n // 37\n mapping(bytes32 => uint256) portalFeeDebt;\n /**\n * @notice Mapping of approved sequencers\n * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\n * for the fast liquidity route.\n */\n // 38\n mapping(address => bool) approvedSequencers;\n /**\n * @notice Remote connection manager for xapp.\n */\n // 39\n IConnectorManager xAppConnectionManager;\n}\n\nlibrary LibConnextStorage {\n function connextStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= 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 > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n // hash of proposed facets => acceptance time\n mapping(bytes32 => uint256) acceptanceTimes;\n // acceptance delay for upgrading facets\n uint256 acceptanceDelay;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function acceptanceDelay() internal view returns (uint256) {\n return diamondStorage().acceptanceDelay;\n }\n\n function acceptanceTime(bytes32 _key) internal view returns (uint256) {\n return diamondStorage().acceptanceTimes[_key];\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, \"LibDiamond: !contract owner\");\n }\n\n event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n function proposeDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 acceptance = block.timestamp + ds.acceptanceDelay;\n ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\n emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\n }\n\n event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n function rescindDiamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\n // period or befor the delay elpases\n diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = 0;\n emit DiamondCutRescinded(_diamondCut, _init, _calldata);\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n if (ds.facetAddresses.length != 0) {\n uint256 time = ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\n require(time != 0 && time <= block.timestamp, \"LibDiamond: delay not elapsed\");\n } // Otherwise, this is the first instance of deployment and it can be set automatically\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress != _facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, \"LibDiamondCut: New facet has no code\");\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n require(_calldata.length == 0, \"LibDiamondCut: _init is address(0) but_calldata is not empty\");\n } else {\n require(_calldata.length != 0, \"LibDiamondCut: _calldata is empty but _init is not address(0)\");\n if (_init != address(this)) {\n enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");\n }\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length != 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize != 0, _errorMessage);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20, IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {LPToken} from \"../helpers/LPToken.sol\";\n\nimport {AmplificationUtils} from \"./AmplificationUtils.sol\";\nimport {MathUtils} from \"./MathUtils.sol\";\n\n/**\n * @title SwapUtils library\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\n * Admin functions should be protected within contracts using this library.\n */\nlibrary SwapUtils {\n using SafeERC20 for IERC20;\n using MathUtils for uint256;\n\n /*** EVENTS ***/\n\n event TokenSwap(\n bytes32 indexed key,\n address indexed buyer,\n uint256 tokensSold,\n uint256 tokensBought,\n uint128 soldId,\n uint128 boughtId\n );\n event AddLiquidity(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n bytes32 indexed key,\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n bytes32 indexed key,\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\n event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\n\n struct Swap {\n // variables around the ramp management of A,\n // the amplification coefficient * n * (n - 1)\n // see https://www.curve.fi/stableswap-paper.pdf for details\n bytes32 key;\n uint256 initialA;\n uint256 futureA;\n uint256 initialATime;\n uint256 futureATime;\n // fee calculation\n uint256 swapFee;\n uint256 adminFee;\n LPToken lpToken;\n // contract references for all tokens being pooled\n IERC20[] pooledTokens;\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\n uint256[] tokenPrecisionMultipliers;\n // the pool balance of each token, in the token's precision\n // the contract's actual token balance might differ\n uint256[] balances;\n // the admin fee balance of each token, in the token's precision\n uint256[] adminFees;\n }\n\n // Struct storing variables used in calculations in the\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\n struct CalculateWithdrawOneTokenDYInfo {\n uint256 d0;\n uint256 d1;\n uint256 newY;\n uint256 feePerToken;\n uint256 preciseA;\n }\n\n // Struct storing variables used in calculations in the\n // {add,remove}Liquidity functions to avoid stack too deep errors\n struct ManageLiquidityInfo {\n uint256 d0;\n uint256 d1;\n uint256 d2;\n uint256 preciseA;\n LPToken lpToken;\n uint256 totalSupply;\n uint256[] balances;\n uint256[] multipliers;\n }\n\n // the precision all pools tokens will be converted to\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\n\n // the denominator used to calculate admin and LP fees. For example, an\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\n uint256 internal constant FEE_DENOMINATOR = 1e10;\n\n // Max swap fee is 1% or 100bps of each swap\n uint256 internal constant MAX_SWAP_FEE = 1e8;\n\n // Max adminFee is 100% of the swapFee\n // adminFee does not add additional fee on top of swapFee\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\n // users but only on the earnings of LPs\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\n\n // Constant value used as max loop limit\n uint256 internal constant MAX_LOOP_LIMIT = 256;\n\n /*** VIEW & PURE FUNCTIONS ***/\n\n function _getAPrecise(Swap storage self) private view returns (uint256) {\n return AmplificationUtils._getAPrecise(self);\n }\n\n /**\n * @notice Calculate the dy, the amount of selected token that user receives and\n * the fee of withdrawing in one token\n * @param tokenAmount the amount to withdraw in the pool's precision\n * @param tokenIndex which token will be withdrawn\n * @param self Swap struct to read from\n * @return the amount of token user will receive\n */\n function calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex\n ) internal view returns (uint256) {\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\n self,\n tokenAmount,\n tokenIndex,\n self.lpToken.totalSupply()\n );\n return availableTokenAmount;\n }\n\n function _calculateWithdrawOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 totalSupply\n ) private view returns (uint256, uint256) {\n uint256 dy;\n uint256 newY;\n uint256 currentY;\n\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\n\n // dy_0 (without fees)\n // dy, dy_0 - dy\n\n uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\n\n return (dy, dySwapFee);\n }\n\n /**\n * @notice Calculate the dy of withdrawing in one token\n * @param self Swap struct to read from\n * @param tokenIndex which token will be withdrawn\n * @param tokenAmount the amount to withdraw in the pools precision\n * @return the d and the new y after withdrawing one token\n */\n function calculateWithdrawOneTokenDY(\n Swap storage self,\n uint8 tokenIndex,\n uint256 tokenAmount,\n uint256 totalSupply\n )\n internal\n view\n returns (\n uint256,\n uint256,\n uint256\n )\n {\n // Get the current D, then solve the stableswap invariant\n // y_i for D - tokenAmount\n uint256[] memory xp = _xp(self);\n\n require(tokenIndex < xp.length, \"index out of range\");\n\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\n v.preciseA = _getAPrecise(self);\n v.d0 = getD(xp, v.preciseA);\n v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\n\n require(tokenAmount <= xp[tokenIndex], \"exceeds available\");\n\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\n\n uint256[] memory xpReduced = new uint256[](xp.length);\n\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\n for (uint256 i; i < xp.length; ) {\n uint256 xpi = xp[i];\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\n xpReduced[i] =\n xpi -\n ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\n FEE_DENOMINATOR);\n\n unchecked {\n ++i;\n }\n }\n\n uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\n dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\n\n return (dy, v.newY, xp[tokenIndex]);\n }\n\n /**\n * @notice Calculate the price of a token in the pool with given\n * precision-adjusted balances and a particular D.\n *\n * @dev This is accomplished via solving the invariant iteratively.\n * See the StableSwap paper and Curve.fi implementation for further details.\n *\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\n * x_1**2 + b*x_1 = c\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\n *\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\n * @param tokenIndex Index of token we are calculating for.\n * @param xp a precision-adjusted set of pool balances. Array should be\n * the same cardinality as the pool.\n * @param d the stableswap invariant\n * @return the price of the token, in the same precision as in xp\n */\n function getYD(\n uint256 a,\n uint8 tokenIndex,\n uint256[] memory xp,\n uint256 d\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndex < numTokens, \"Token not found\");\n\n uint256 c = d;\n uint256 s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < numTokens; ) {\n if (i != tokenIndex) {\n s += xp[i];\n c = (c * d) / (xp[i] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n }\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\n * as the pool.\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\n * See the StableSwap paper for details\n * @return the invariant, at the precision of the pool\n */\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n uint256 s;\n for (uint256 i; i < numTokens; ) {\n s += xp[i];\n\n unchecked {\n ++i;\n }\n }\n if (s == 0) {\n return 0;\n }\n\n uint256 prevD;\n uint256 d = s;\n uint256 nA = a * numTokens;\n\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n uint256 dP = d;\n for (uint256 j; j < numTokens; ) {\n dP = (dP * d) / (xp[j] * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // dP = dP * D * D * D * ... overflow!\n\n unchecked {\n ++j;\n }\n }\n prevD = d;\n d =\n (((nA * s) / AmplificationUtils.A_PRECISION + dP * numTokens) * d) /\n ((((nA - AmplificationUtils.A_PRECISION) * d) / AmplificationUtils.A_PRECISION + (numTokens + 1) * dP));\n if (d.within1(prevD)) {\n return d;\n }\n\n unchecked {\n ++i;\n }\n }\n\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\n // function which does not rely on D.\n revert(\"D does not converge\");\n }\n\n /**\n * @notice Given a set of balances and precision multipliers, return the\n * precision-adjusted balances.\n *\n * @param balances an array of token balances, in their native precisions.\n * These should generally correspond with pooled tokens.\n *\n * @param precisionMultipliers an array of multipliers, corresponding to\n * the amounts in the balances array. When multiplied together they\n * should yield amounts at the pool's precision.\n *\n * @return an array of amounts \"scaled\" to the pool's precision\n */\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\n internal\n pure\n returns (uint256[] memory)\n {\n uint256 numTokens = balances.length;\n require(numTokens == precisionMultipliers.length, \"mismatch multipliers\");\n uint256[] memory xp = new uint256[](numTokens);\n for (uint256 i; i < numTokens; ) {\n xp[i] = balances[i] * precisionMultipliers[i];\n\n unchecked {\n ++i;\n }\n }\n return xp;\n }\n\n /**\n * @notice Return the precision-adjusted balances of all tokens in the pool\n * @param self Swap struct to read from\n * @return the pool balances \"scaled\" to the pool's precision, allowing\n * them to be more easily compared.\n */\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\n return _xp(self.balances, self.tokenPrecisionMultipliers);\n }\n\n /**\n * @notice Get the virtual price, to help calculate profit\n * @param self Swap struct to read from\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\n */\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\n uint256 d = getD(_xp(self), _getAPrecise(self));\n LPToken lpToken = self.lpToken;\n uint256 supply = lpToken.totalSupply();\n if (supply != 0) {\n return (d * (10**uint256(POOL_PRECISION_DECIMALS))) / supply;\n }\n return 0;\n }\n\n /**\n * @notice Calculate the new balances of the tokens given the indexes of the token\n * that is swapped from (FROM) and the token that is swapped to (TO).\n * This function is used as a helper function to calculate how much TO token\n * the user should receive on swap.\n *\n * @param preciseA precise form of amplification coefficient\n * @param tokenIndexFrom index of FROM token\n * @param tokenIndexTo index of TO token\n * @param x the new total amount of FROM token\n * @param xp balances of the tokens in the pool\n * @return the amount of TO token that should remain in the pool\n */\n function getY(\n uint256 preciseA,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 x,\n uint256[] memory xp\n ) internal pure returns (uint256) {\n uint256 numTokens = xp.length;\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \"token not found\");\n\n uint256 d = getD(xp, preciseA);\n uint256 c = d;\n uint256 s;\n uint256 nA = numTokens * preciseA;\n\n uint256 _x;\n for (uint256 i; i < numTokens; ) {\n if (i == tokenIndexFrom) {\n _x = x;\n } else if (i != tokenIndexTo) {\n _x = xp[i];\n } else {\n unchecked {\n ++i;\n }\n continue;\n }\n s += _x;\n c = (c * d) / (_x * numTokens);\n // If we were to protect the division loss we would have to keep the denominator separate\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\n // c = c * D * D * D * ... overflow!\n\n unchecked {\n ++i;\n }\n }\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\n uint256 yPrev;\n uint256 y = d;\n\n // iterative approximation\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\n yPrev = y;\n y = ((y * y) + c) / ((y * 2) + b - d);\n if (y.within1(yPrev)) {\n return y;\n }\n\n unchecked {\n ++i;\n }\n }\n revert(\"Approximation did not converge\");\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get\n */\n function calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) internal view returns (uint256 dy) {\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\n }\n\n /**\n * @notice Externally calculates a swap between two tokens.\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy.\n * @return dx the number of tokens the user have to transfer + fee\n */\n function calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) internal view returns (uint256 dx) {\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\n * @return dyFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256[] memory balances\n ) internal view returns (uint256 dy, uint256 dyFee) {\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\n dy = xp[tokenIndexTo] - y - 1;\n dyFee = (dy * self.swapFee) / FEE_DENOMINATOR;\n dy = (dy - dyFee) / multipliers[tokenIndexTo];\n }\n\n /**\n * @notice Internally calculates a swap between two tokens.\n *\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\n * using the token contracts.\n *\n * @param self Swap struct to read from\n * @param tokenIndexFrom the token to sell\n * @param tokenIndexTo the token to buy\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\n * @return dxFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\n */\n function _calculateSwapInv(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256[] memory balances\n ) internal view returns (uint256 dx, uint256 dxFee) {\n require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n uint256[] memory xp = _xp(balances, multipliers);\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n\n uint256 a = _getAPrecise(self);\n uint256 d0 = getD(xp, a);\n\n xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\n dx = x - xp[tokenIndexFrom] + 1;\n dxFee = (dx * self.swapFee) / FEE_DENOMINATOR;\n dx = (dx + dxFee) / multipliers[tokenIndexFrom];\n }\n\n /**\n * @notice A simple method to calculate amount of each underlying\n * tokens that is returned upon burning given amount of\n * LP tokens\n *\n * @param amount the amount of LP tokens that would to be burned on\n * withdrawal\n * @return array of amounts of tokens user will receive\n */\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\n }\n\n function _calculateRemoveLiquidity(\n uint256[] memory balances,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (uint256[] memory) {\n require(amount <= totalSupply, \"exceed total supply\");\n\n uint256 numBalances = balances.length;\n uint256[] memory amounts = new uint256[](numBalances);\n\n for (uint256 i; i < numBalances; ) {\n amounts[i] = (balances[i] * amount) / totalSupply;\n\n unchecked {\n ++i;\n }\n }\n return amounts;\n }\n\n /**\n * @notice A simple method to calculate prices from deposits or\n * withdrawals, excluding fees but including slippage. This is\n * helpful as an input into the various \"min\" parameters on calls\n * to fight front-running\n *\n * @dev This shouldn't be used outside frontends for user estimates.\n *\n * @param self Swap struct to read from\n * @param amounts an array of token amounts to deposit or withdrawal,\n * corresponding to pooledTokens. The amount should be in each\n * pooled token's native precision. If a token charges a fee on transfers,\n * use the amount that gets transferred after the fee.\n * @param deposit whether this is a deposit or a withdrawal\n * @return if deposit was true, total amount of lp token that will be minted and if\n * deposit was false, total amount of lp token that will be burned\n */\n function calculateTokenAmount(\n Swap storage self,\n uint256[] calldata amounts,\n bool deposit\n ) internal view returns (uint256) {\n uint256 a = _getAPrecise(self);\n uint256[] memory balances = self.balances;\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n\n uint256 numBalances = balances.length;\n uint256 d0 = getD(_xp(balances, multipliers), a);\n for (uint256 i; i < numBalances; ) {\n if (deposit) {\n balances[i] = balances[i] + amounts[i];\n } else {\n balances[i] = balances[i] - amounts[i];\n }\n\n unchecked {\n ++i;\n }\n }\n uint256 d1 = getD(_xp(balances, multipliers), a);\n uint256 totalSupply = self.lpToken.totalSupply();\n\n if (deposit) {\n return ((d1 - d0) * totalSupply) / d0;\n } else {\n return ((d0 - d1) * totalSupply) / d0;\n }\n }\n\n /**\n * @notice return accumulated amount of admin fees of the token with given index\n * @param self Swap struct to read from\n * @param index Index of the pooled token\n * @return admin balance in the token's precision\n */\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\n require(index < self.pooledTokens.length, \"index out of range\");\n return self.adminFees[index];\n }\n\n /**\n * @notice internal helper function to calculate fee per token multiplier used in\n * swap fee calculations\n * @param swapFee swap fee for the tokens\n * @param numTokens number of tokens pooled\n */\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\n return (swapFee * numTokens) / ((numTokens - 1) * 4);\n }\n\n /*** STATE MODIFYING FUNCTIONS ***/\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swap(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"swap more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"no fee token support\");\n }\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice swap two tokens in the pool\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dy the amount of tokens the user wants to buy\n * @param maxDx the max amount the user would like to send.\n * @return amount of token user have to transfer on swap\n */\n function swapOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \">pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n {\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n require(dx <= tokenFrom.balanceOf(msg.sender), \"more than you own\");\n // Transfer tokens first to see if a fee was charged on transfer\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\n\n // Use the actual transferred amount for AMM math\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \"not support fee token\");\n }\n\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice swap two tokens in the pool internally\n * @param self Swap struct to read from and write to\n * @param tokenIndexFrom the token the user wants to sell\n * @param tokenIndexTo the token the user wants to buy\n * @param dx the amount of tokens the user wants to sell\n * @param minDy the min amount the user would like to receive, or revert.\n * @return amount of token user received on swap\n */\n function swapInternal(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy\n ) internal returns (uint256) {\n require(dx <= self.balances[tokenIndexFrom], \"more than pool balance\");\n\n uint256 dy;\n uint256 dyFee;\n uint256[] memory balances = self.balances;\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n require(dy >= minDy, \"dy < minDy\");\n\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n\n if (dyAdminFee != 0) {\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dy;\n }\n\n /**\n * @notice Should get exact amount out of AMM for asset put in\n */\n function swapInternalOut(\n Swap storage self,\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy,\n uint256 maxDx\n ) internal returns (uint256) {\n require(dy <= self.balances[tokenIndexTo], \"more than pool balance\");\n\n uint256 dx;\n uint256 dxFee;\n uint256[] memory balances = self.balances;\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n require(dx <= maxDx, \"dx > maxDx\");\n\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n\n if (dxAdminFee != 0) {\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n }\n\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n return dx;\n }\n\n /**\n * @notice Add liquidity to the pool\n * @param self Swap struct to read from and write to\n * @param amounts the amounts of each token to add, in their native precision\n * @param minToMint the minimum LP tokens adding this amount of liquidity\n * should mint, otherwise revert. Handy for front-running mitigation\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\n * @return amount of LP token user received\n */\n function addLiquidity(\n Swap storage self,\n uint256[] memory amounts,\n uint256 minToMint\n ) internal returns (uint256) {\n uint256 numTokens = self.pooledTokens.length;\n require(amounts.length == numTokens, \"mismatch pooled tokens\");\n\n // current state\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n if (v.totalSupply != 0) {\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n }\n\n uint256[] memory newBalances = new uint256[](numTokens);\n\n for (uint256 i; i < numTokens; ) {\n require(v.totalSupply != 0 || amounts[i] != 0, \"!supply all tokens\");\n\n // Transfer tokens first to see if a fee was charged on transfer\n if (amounts[i] != 0) {\n IERC20 token = self.pooledTokens[i];\n uint256 beforeBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), amounts[i]);\n\n // Update the amounts[] with actual transfer amount\n amounts[i] = token.balanceOf(address(this)) - beforeBalance;\n }\n\n newBalances[i] = v.balances[i] + amounts[i];\n\n unchecked {\n ++i;\n }\n }\n\n // invariant after change\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n require(v.d1 > v.d0, \"D should increase\");\n\n // updated to reflect fees and calculate the user's LP tokens\n v.d2 = v.d1;\n uint256[] memory fees = new uint256[](numTokens);\n\n if (v.totalSupply != 0) {\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n for (uint256 i; i < numTokens; ) {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / FEE_DENOMINATOR;\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = newBalances[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n newBalances[i] = newBalances[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n } else {\n // the initial depositor doesn't pay fees\n self.balances = newBalances;\n }\n\n uint256 toMint;\n if (v.totalSupply == 0) {\n toMint = v.d1;\n } else {\n toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\n }\n\n require(toMint >= minToMint, \"mint < min\");\n\n // mint the user's LP tokens\n v.lpToken.mint(msg.sender, toMint);\n\n emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\n\n return toMint;\n }\n\n /**\n * @notice Burn LP tokens to remove liquidity from the pool.\n * @dev Liquidity can always be removed, even when the pool is paused.\n * @param self Swap struct to read from and write to\n * @param amount the amount of LP tokens to burn\n * @param minAmounts the minimum amounts of each token in the pool\n * acceptable for this burn. Useful as a front-running mitigation\n * @return amounts of tokens the user received\n */\n function removeLiquidity(\n Swap storage self,\n uint256 amount,\n uint256[] calldata minAmounts\n ) internal returns (uint256[] memory) {\n LPToken lpToken = self.lpToken;\n require(amount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(minAmounts.length == numTokens, \"mismatch poolTokens\");\n\n uint256[] memory balances = self.balances;\n uint256 totalSupply = lpToken.totalSupply();\n\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\n\n uint256 numAmounts = amounts.length;\n for (uint256 i; i < numAmounts; ) {\n require(amounts[i] >= minAmounts[i], \"amounts[i] < minAmounts[i]\");\n self.balances[i] = balances[i] - amounts[i];\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n lpToken.burnFrom(msg.sender, amount);\n\n emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\n\n return amounts;\n }\n\n /**\n * @notice Remove liquidity from the pool all in one token.\n * @param self Swap struct to read from and write to\n * @param tokenAmount the amount of the lp tokens to burn\n * @param tokenIndex the index of the token you want to receive\n * @param minAmount the minimum amount to withdraw, otherwise revert\n * @return amount chosen token that user received\n */\n function removeLiquidityOneToken(\n Swap storage self,\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount\n ) internal returns (uint256) {\n LPToken lpToken = self.lpToken;\n\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n uint256 numTokens = self.pooledTokens.length;\n require(tokenIndex < numTokens, \"not found\");\n\n uint256 totalSupply = lpToken.totalSupply();\n\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\n\n require(dy >= minAmount, \"dy < minAmount\");\n\n uint256 adminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR;\n self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\n if (adminFee != 0) {\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\n }\n lpToken.burnFrom(msg.sender, tokenAmount);\n self.pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\n\n emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\n\n return dy;\n }\n\n /**\n * @notice Remove liquidity from the pool, weighted differently than the\n * pool's current balances.\n *\n * @param self Swap struct to read from and write to\n * @param amounts how much of each token to withdraw\n * @param maxBurnAmount the max LP token provider is willing to pay to\n * remove liquidity. Useful as a front-running mitigation.\n * @return actual amount of LP tokens burned in the withdrawal\n */\n function removeLiquidityImbalance(\n Swap storage self,\n uint256[] memory amounts,\n uint256 maxBurnAmount\n ) internal returns (uint256) {\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\n 0,\n 0,\n 0,\n _getAPrecise(self),\n self.lpToken,\n 0,\n self.balances,\n self.tokenPrecisionMultipliers\n );\n v.totalSupply = v.lpToken.totalSupply();\n\n uint256 numTokens = self.pooledTokens.length;\n uint256 numAmounts = amounts.length;\n require(numAmounts == numTokens, \"mismatch pool tokens\");\n\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \">LP.balanceOf\");\n\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n uint256[] memory fees = new uint256[](numTokens);\n {\n uint256[] memory balances1 = new uint256[](numTokens);\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n for (uint256 i; i < numTokens; ) {\n require(v.balances[i] >= amounts[i], \"withdraw more than available\");\n\n unchecked {\n balances1[i] = v.balances[i] - amounts[i];\n ++i;\n }\n }\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\n\n for (uint256 i; i < numTokens; ) {\n {\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n uint256 difference = idealBalance.difference(balances1[i]);\n fees[i] = (feePerToken * difference) / FEE_DENOMINATOR;\n }\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\n self.balances[i] = balances1[i] - adminFee;\n self.adminFees[i] = self.adminFees[i] + adminFee;\n balances1[i] = balances1[i] - fees[i];\n\n unchecked {\n ++i;\n }\n }\n\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\n }\n uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\n require(tokenAmount != 0, \"!zero amount\");\n tokenAmount = tokenAmount + 1;\n\n require(tokenAmount <= maxBurnAmount, \"tokenAmount > maxBurnAmount\");\n\n v.lpToken.burnFrom(msg.sender, tokenAmount);\n\n for (uint256 i; i < numTokens; ) {\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\n\n unchecked {\n ++i;\n }\n }\n\n emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\n\n return tokenAmount;\n }\n\n /**\n * @notice withdraw all admin fees to a given address\n * @param self Swap struct to withdraw fees from\n * @param to Address to send the fees to\n */\n function withdrawAdminFees(Swap storage self, address to) internal {\n uint256 numTokens = self.pooledTokens.length;\n for (uint256 i; i < numTokens; ) {\n IERC20 token = self.pooledTokens[i];\n uint256 balance = self.adminFees[i];\n if (balance != 0) {\n self.adminFees[i] = 0;\n token.safeTransfer(to, balance);\n }\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Sets the admin fee\n * @dev adminFee cannot be higher than 100% of the swap fee\n * @param self Swap struct to update\n * @param newAdminFee new admin fee to be applied on future transactions\n */\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\n require(newAdminFee <= MAX_ADMIN_FEE, \"too high\");\n self.adminFee = newAdminFee;\n\n emit NewAdminFee(self.key, newAdminFee);\n }\n\n /**\n * @notice update the swap fee\n * @dev fee cannot be higher than 1% of each swap\n * @param self Swap struct to update\n * @param newSwapFee new swap fee to be applied on future transactions\n */\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\n require(newSwapFee <= MAX_SWAP_FEE, \"too high\");\n self.swapFee = newSwapFee;\n\n emit NewSwapFee(self.key, newSwapFee);\n }\n\n /**\n * @notice Check if this stableswap pool exists and is valid (i.e. has been\n * initialized and tokens have been added).\n * @return bool true if this stableswap pool is valid, false if not.\n */\n function exists(Swap storage self) internal view returns (bool) {\n return self.pooledTokens.length != 0;\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IStableSwap {\n /*** EVENTS ***/\n\n // events replicated from SwapUtils to make the ABI easier for dumb\n // clients\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\n event AddLiquidity(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n event RemoveLiquidityOne(\n address indexed provider,\n uint256 lpTokenAmount,\n uint256 lpTokenSupply,\n uint256 boughtId,\n uint256 tokensBought\n );\n event RemoveLiquidityImbalance(\n address indexed provider,\n uint256[] tokenAmounts,\n uint256[] fees,\n uint256 invariant,\n uint256 lpTokenSupply\n );\n event NewAdminFee(uint256 newAdminFee);\n event NewSwapFee(uint256 newSwapFee);\n event NewWithdrawFee(uint256 newWithdrawFee);\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n function swap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n\n function swapExact(\n uint256 amountIn,\n address assetIn,\n address assetOut,\n uint256 minAmountOut,\n uint256 deadline\n ) external payable returns (uint256);\n\n function swapExactOut(\n uint256 amountOut,\n address assetIn,\n address assetOut,\n uint256 maxAmountIn,\n uint256 deadline\n ) external payable returns (uint256);\n\n function getA() external view returns (uint256);\n\n function getToken(uint8 index) external view returns (IERC20);\n\n function getTokenIndex(address tokenAddress) external view returns (uint8);\n\n function getTokenBalance(uint8 index) external view returns (uint256);\n\n function getVirtualPrice() external view returns (uint256);\n\n // min return calculation functions\n function calculateSwap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx\n ) external view returns (uint256);\n\n function calculateSwapOut(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dy\n ) external view returns (uint256);\n\n function calculateSwapFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountIn\n ) external view returns (uint256);\n\n function calculateSwapOutFromAddress(\n address assetIn,\n address assetOut,\n uint256 amountOut\n ) external view returns (uint256);\n\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\n\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\n\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\n external\n view\n returns (uint256 availableTokenAmount);\n\n // state modifying functions\n function initialize(\n IERC20[] memory pooledTokens,\n uint8[] memory decimals,\n string memory lpTokenName,\n string memory lpTokenSymbol,\n uint256 a,\n uint256 fee,\n uint256 adminFee,\n address lpTokenTargetAddress\n ) external;\n\n function addLiquidity(\n uint256[] calldata amounts,\n uint256 minToMint,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidity(\n uint256 amount,\n uint256[] calldata minAmounts,\n uint256 deadline\n ) external returns (uint256[] memory);\n\n function removeLiquidityOneToken(\n uint256 tokenAmount,\n uint8 tokenIndex,\n uint256 minAmount,\n uint256 deadline\n ) external returns (uint256);\n\n function removeLiquidityImbalance(\n uint256[] calldata amounts,\n uint256 maxBurnAmount,\n uint256 deadline\n ) external returns (uint256);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function proposeDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function rescindDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\nimport {IOutbox} from \"./IOutbox.sol\";\n\n/**\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\n * allows an admin to call `setXAppConnectionManager` to update the underlying\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\n *\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\n * will interface with.\n */\ninterface IConnectorManager {\n /**\n * @notice Get the local inbox contract from the xAppConnectionManager\n * @return The local inbox contract\n * @dev The local inbox contract is a SpokeConnector with AMBs, and a\n * Home contract with nomad\n */\n function home() external view returns (IOutbox);\n\n /**\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\n * @return True if _potentialReplica is an enrolled Replica\n */\n function isReplica(address _potentialReplica) external view returns (bool);\n\n /**\n * @notice Get the local domain from the xAppConnectionManager\n * @return The local domain\n */\n function localDomain() external view returns (uint32);\n}\n" - }, - "@openzeppelin/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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol": { - "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.15;\n\n/**\n * @notice Interface for all contracts sending messages originating on their\n * current domain.\n *\n * @dev These are the Home.sol interface methods used by the `Router`\n * and exposed via `home()` on the `XAppConnectionClient`\n */\ninterface IOutbox {\n /**\n * @notice Emitted when a new message is added to an outbound message merkle root\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination << 32) & nonce)\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\n * @param committedRoot the latest notarized root submitted in the last signed Update\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes32 committedRoot,\n bytes message\n );\n\n /**\n * @notice Dispatch the message it to the destination domain & recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n * @return bytes32 The leaf added to the tree\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n bytes memory _messageBody\n ) external returns (bytes32);\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\n/**\n * @title MathUtils library\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\n * differences between two uint256.\n */\nlibrary MathUtils {\n /**\n * @notice Compares a and b and returns true if the difference between a and b\n * is less than 1 or equal to each other.\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return True if the difference between a and b is less than 1 or equal,\n * otherwise return false\n */\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\n return (difference(a, b) <= 1);\n }\n\n /**\n * @notice Calculates absolute difference between a and b\n * @param a uint256 to compare with\n * @param b uint256 to compare with\n * @return Difference between a and b\n */\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a > b) {\n return a - b;\n }\n return b - a;\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title Liquidity Provider Token\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\n * It is used to represent user's shares when providing liquidity to swap contracts.\n * @dev Only Swap contracts should initialize and own LPToken contracts.\n */\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\n // ============ Upgrade Gap ============\n\n uint256[49] private __GAP; // gap for upgrade safety\n\n // ============ Storage ============\n\n /**\n * @notice Used to enforce proper token dilution\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\n * See audit recommendations here:\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\n * and uniswap v2 implementation here:\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\n */\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\n\n // ============ Initializer ============\n\n /**\n * @notice Initializes this LPToken contract with the given name and symbol\n * @dev The caller of this function will become the owner. A Swap contract should call this\n * in its initializer function.\n * @param name name of this token\n * @param symbol symbol of this token\n */\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\n __Context_init_unchained();\n __ERC20_init_unchained(name, symbol);\n __Ownable_init_unchained();\n return true;\n }\n\n // ============ External functions ============\n\n /**\n * @notice Mints the given amount of LPToken to the recipient.\n * @dev only owner can call this mint function\n * @param recipient address of account to receive the tokens\n * @param amount amount of tokens to mint\n */\n function mint(address recipient, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot mint 0\");\n if (totalSupply() == 0) {\n // NOTE: using the _mint function directly will error because it is going\n // to the 0 address. fix by using the address(1) here instead\n _mint(address(1), MINIMUM_LIQUIDITY);\n }\n _mint(recipient, amount);\n }\n\n /**\n * @notice Burns the given amount of LPToken from provided account\n * @dev only owner can call this burn function\n * @param account address of account from which to burn token\n * @param amount amount of tokens to mint\n */\n function burnFrom(address account, uint256 amount) external onlyOwner {\n require(amount != 0, \"LPToken: cannot burn 0\");\n _burn(account, amount);\n }\n\n // ============ Internal functions ============\n\n /**\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\n * This assumes the owner is set to a Swap contract's address.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20Upgradeable) {\n super._beforeTokenTransfer(from, to, amount);\n require(to != address(this), \"LPToken: cannot send to itself\");\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n/**\n * @title AmplificationUtils library\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\n * This library assumes the struct is fully validated.\n */\nlibrary AmplificationUtils {\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n event StopRampA(uint256 currentA, uint256 time);\n\n // Constant values used in ramping A calculations\n uint256 public constant A_PRECISION = 100;\n uint256 public constant MAX_A = 10**6;\n uint256 private constant MAX_A_CHANGE = 2;\n uint256 private constant MIN_RAMP_TIME = 14 days;\n\n /**\n * @notice Return A, the amplification coefficient * n * (n - 1)\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter\n */\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self) / A_PRECISION;\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n return _getAPrecise(self);\n }\n\n /**\n * @notice Return A in its raw precision\n * @dev See the StableSwap paper for details\n * @param self Swap struct to read from\n * @return A parameter in its raw precision form\n */\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n uint256 t1 = self.futureATime; // time when ramp is finished\n uint256 a1 = self.futureA; // final A value when ramp is finished\n\n if (block.timestamp < t1) {\n uint256 t0 = self.initialATime; // time when ramp is started\n uint256 a0 = self.initialA; // initial A value when ramp is started\n if (a1 > a0) {\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\n return a0 + ((a1 - a0) * (block.timestamp - t0)) / (t1 - t0);\n } else {\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\n return a0 - ((a0 - a1) * (block.timestamp - t0)) / (t1 - t0);\n }\n } else {\n return a1;\n }\n }\n\n /**\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\n * Checks if the change is too rapid, and commits the new A value only when it falls under\n * the limit range.\n * @param self Swap struct to update\n * @param futureA_ the new A to ramp towards\n * @param futureTime_ timestamp when the new A should be reached\n */\n function rampA(\n SwapUtils.Swap storage self,\n uint256 futureA_,\n uint256 futureTime_\n ) internal {\n require(block.timestamp >= self.initialATime + 1 days, \"Wait 1 day before starting ramp\");\n require(futureTime_ >= block.timestamp + MIN_RAMP_TIME, \"Insufficient ramp time\");\n require(futureA_ != 0 && futureA_ < MAX_A, \"futureA_ must be > 0 and < MAX_A\");\n\n uint256 initialAPrecise = _getAPrecise(self);\n uint256 futureAPrecise = futureA_ * A_PRECISION;\n\n if (futureAPrecise < initialAPrecise) {\n require(futureAPrecise * MAX_A_CHANGE >= initialAPrecise, \"futureA_ is too small\");\n } else {\n require(futureAPrecise <= initialAPrecise * MAX_A_CHANGE, \"futureA_ is too large\");\n }\n\n self.initialA = initialAPrecise;\n self.futureA = futureAPrecise;\n self.initialATime = block.timestamp;\n self.futureATime = futureTime_;\n\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\n }\n\n /**\n * @notice Stops ramping A immediately. Once this function is called, rampA()\n * cannot be called for another 24 hours\n * @param self Swap struct to update\n */\n function stopRampA(SwapUtils.Swap storage self) internal {\n require(self.futureATime > block.timestamp, \"Ramp is already stopped\");\n\n uint256 currentA = _getAPrecise(self);\n self.initialA = currentA;\n self.futureA = currentA;\n self.initialATime = block.timestamp;\n self.futureATime = block.timestamp;\n\n emit StopRampA(currentA, block.timestamp);\n }\n}\n" - }, - "@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/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" - }, - "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 > 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 >= 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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // Look for revert reason and bubble it up if present\n if (returndata.length > 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}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.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 IERC20Upgradeable {\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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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" - }, - "solidity/for-test/DataReceiverForTest.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {DataReceiver} from '../contracts/DataReceiver.sol';\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\ncontract DataReceiverForTest is DataReceiver {\n constructor(address _governor, IOracleFactory _oracleFactory) DataReceiver(_governor, _oracleFactory) {}\n\n function internalAddObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "solidity/contracts/DataReceiver.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\n\n/// @title The DataReceiver contract\n/// @notice Handles reception of broadcast data and delivers it to correspondant oracle\ncontract DataReceiver is IDataReceiver, Governable {\n /// @inheritdoc IDataReceiver\n IOracleFactory public immutable oracleFactory;\n\n /// @inheritdoc IDataReceiver\n mapping(bytes32 => IOracleSidechain) public deployedOracles;\n\n /// @inheritdoc IDataReceiver\n mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters;\n\n /// @inheritdoc IDataReceiver\n bytes32 public constant ORACLE_INIT_CODE_HASH = 0x81a14d5bbd761f94f91b3251dcb81827627068b092edb305c98f3799dcf10da2;\n\n constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) {\n oracleFactory = _oracleFactory;\n }\n\n function addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external onlyWhitelistedAdapters {\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n // Read, store or deploy oracle given poolSalt\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.getPool(_poolSalt);\n if (address(_oracle) == address(0)) {\n _oracle = oracleFactory.deployOracle(_poolSalt, _poolNonce);\n }\n deployedOracles[_poolSalt] = _oracle;\n }\n // Try to write observations data into oracle\n if (_oracle.write(_observationsData, _poolNonce)) {\n emit ObservationsAdded(_poolSalt, _poolNonce, _observationsData, msg.sender);\n } else {\n revert ObservationsNotWritable();\n }\n }\n\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor {\n _whitelistAdapter(_receiverAdapter, _isWhitelisted);\n }\n\n /// @inheritdoc IDataReceiver\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\n uint256 _receiverAdapterLength = _receiverAdapters.length;\n if (_receiverAdapterLength != _isWhitelisted.length) revert LengthMismatch();\n unchecked {\n for (uint256 _i; _i < _receiverAdapterLength; ++_i) {\n _whitelistAdapter(_receiverAdapters[_i], _isWhitelisted[_i]);\n }\n }\n }\n\n function _whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) internal {\n whitelistedAdapters[_receiverAdapter] = _isWhitelisted;\n emit AdapterWhitelisted(_receiverAdapter, _isWhitelisted);\n }\n\n modifier onlyWhitelistedAdapters() {\n if (!whitelistedAdapters[IBridgeReceiverAdapter(msg.sender)]) revert UnallowedAdapter();\n _;\n }\n}\n" - }, - "solidity/contracts/OracleSidechain.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\n\n/// @title The SidechainOracle contract\n/// @notice Computes and stores on-chain price data from Mainnet\ncontract OracleSidechain is IOracleSidechain {\n using Oracle for Oracle.Observation[65535];\n\n /// @inheritdoc IOracleSidechain\n IOracleFactory public immutable factory;\n\n struct Slot0 {\n // the current price\n uint160 sqrtPriceX96;\n // the current tick\n int24 tick;\n // the most-recently updated index of the observations array\n uint16 observationIndex;\n // the current maximum number of observations that are being stored\n uint16 observationCardinality;\n // the next maximum number of observations to store, triggered in observations.write\n uint16 observationCardinalityNext;\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\n // represented as an integer denominator (1/x)%\n uint8 feeProtocol;\n // whether the pool is locked\n bool unlocked;\n }\n /// @inheritdoc IOracleSidechain\n Slot0 public slot0;\n\n /// @inheritdoc IOracleSidechain\n Oracle.Observation[65535] public observations;\n\n /// @inheritdoc IOracleSidechain\n bytes32 public immutable poolSalt;\n\n uint24 public poolNonce;\n /// @inheritdoc IOracleSidechain\n address public token0;\n /// @inheritdoc IOracleSidechain\n address public token1;\n /// @inheritdoc IOracleSidechain\n uint24 public fee;\n\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\n function _getBlockTimestamp() internal view virtual returns (uint32) {\n return uint32(block.timestamp); // truncation is desired\n }\n\n constructor() {\n factory = IOracleFactory(msg.sender);\n uint16 _cardinality;\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\n\n slot0 = Slot0({\n sqrtPriceX96: 0,\n tick: 0,\n observationIndex: _cardinality - 1,\n observationCardinality: _cardinality,\n observationCardinalityNext: _cardinality,\n feeProtocol: 0,\n unlocked: true\n });\n }\n\n /// @inheritdoc IOracleSidechain\n function initializePoolInfo(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external {\n if (!slot0.unlocked) revert AI();\n\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\n\n token0 = _token0;\n token1 = _token1;\n fee = _fee;\n slot0.unlocked = false;\n\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\n }\n\n /// @inheritdoc IOracleSidechain\n function observe(uint32[] calldata _secondsAgos)\n external\n view\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\n {\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\n }\n\n /// @inheritdoc IOracleSidechain\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\n if (_poolNonce != poolNonce++) return false;\n\n uint256 _observationsDataLength = _observationsData.length;\n for (uint256 _i; _i < _observationsDataLength; ) {\n _write(_observationsData[_i]);\n unchecked {\n ++_i;\n }\n }\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\n\n // emits UniV3 Swap event topic with minimal data\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\n return true;\n }\n\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\n if (_observationCardinalityNext <= _observationCardinalityNextOld) return;\n slot0.observationCardinalityNext = _observationCardinalityNext;\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\n }\n\n function _write(ObservationData memory _observationData) private {\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\n slot0.observationIndex,\n _observationData.blockTimestamp,\n slot0.tick,\n 0,\n slot0.observationCardinality,\n slot0.observationCardinalityNext\n );\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\n slot0.tick = _observationData.tick;\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\n _;\n }\n\n modifier onlyFactory() {\n if (msg.sender != address(factory)) revert OnlyFactory();\n _;\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/TickMath.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n error T();\n error R();\n\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n unchecked {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n if (absTick > uint256(int256(MAX_TICK))) revert T();\n\n uint256 ratio = absTick & 0x1 != 0\n ? 0xfffcb933bd6fad37aa2d162d1a594001\n : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\n /// ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n unchecked {\n // second inequality must be < because the price can never reach the price at the max tick\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n }\n}\n" - }, - "@uniswap/v3-core/contracts/libraries/Oracle.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/// @title Oracle\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\n/// @dev Instances of stored oracle data, \"observations\", are collected in the oracle array\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\n/// Observations are overwritten when the full length of the oracle array is populated.\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\nlibrary Oracle {\n error I();\n error OLD();\n\n struct Observation {\n // the block timestamp of the observation\n uint32 blockTimestamp;\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\n int56 tickCumulative;\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\n uint160 secondsPerLiquidityCumulativeX128;\n // whether or not the observation is initialized\n bool initialized;\n }\n\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\n /// @param last The specified observation to be transformed\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @return Observation The newly populated observation\n function transform(\n Observation memory last,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity\n ) private pure returns (Observation memory) {\n unchecked {\n uint32 delta = blockTimestamp - last.blockTimestamp;\n return\n Observation({\n blockTimestamp: blockTimestamp,\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\n initialized: true\n });\n }\n }\n\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\n /// @param self The stored oracle array\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\n /// @return cardinality The number of populated elements in the oracle array\n /// @return cardinalityNext The new length of the oracle array, independent of population\n function initialize(Observation[65535] storage self, uint32 time)\n internal\n returns (uint16 cardinality, uint16 cardinalityNext)\n {\n self[0] = Observation({\n blockTimestamp: time,\n tickCumulative: 0,\n secondsPerLiquidityCumulativeX128: 0,\n initialized: true\n });\n return (1, 1);\n }\n\n /// @notice Writes an oracle observation to the array\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\n /// @param self The stored oracle array\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param blockTimestamp The timestamp of the new observation\n /// @param tick The active tick at the time of the new observation\n /// @param liquidity The total in-range liquidity at the time of the new observation\n /// @param cardinality The number of populated elements in the oracle array\n /// @param cardinalityNext The new length of the oracle array, independent of population\n /// @return indexUpdated The new index of the most recently written element in the oracle array\n /// @return cardinalityUpdated The new cardinality of the oracle array\n function write(\n Observation[65535] storage self,\n uint16 index,\n uint32 blockTimestamp,\n int24 tick,\n uint128 liquidity,\n uint16 cardinality,\n uint16 cardinalityNext\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\n unchecked {\n Observation memory last = self[index];\n\n // early return if we've already written an observation this block\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\n\n // if the conditions are right, we can bump the cardinality\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\n cardinalityUpdated = cardinalityNext;\n } else {\n cardinalityUpdated = cardinality;\n }\n\n indexUpdated = (index + 1) % cardinalityUpdated;\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\n }\n }\n\n /// @notice Prepares the oracle array to store up to `next` observations\n /// @param self The stored oracle array\n /// @param current The current next cardinality of the oracle array\n /// @param next The proposed next cardinality which will be populated in the oracle array\n /// @return next The next cardinality which will be populated in the oracle array\n function grow(\n Observation[65535] storage self,\n uint16 current,\n uint16 next\n ) internal returns (uint16) {\n unchecked {\n if (current <= 0) revert I();\n // no-op if the passed next value isn't greater than the current next value\n if (next <= current) return current;\n // store in each slot to prevent fresh SSTOREs in swaps\n // this data will not be used because the initialized boolean is still false\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\n return next;\n }\n }\n\n /// @notice comparator for 32-bit timestamps\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\n /// @param time A timestamp truncated to 32 bits\n /// @param a A comparison timestamp from which to determine the relative position of `time`\n /// @param b From which to determine the relative position of `time`\n /// @return Whether `a` is chronologically <= `b`\n function lte(\n uint32 time,\n uint32 a,\n uint32 b\n ) private pure returns (bool) {\n unchecked {\n // if there hasn't been overflow, no need to adjust\n if (a <= time && b <= time) return a <= b;\n\n uint256 aAdjusted = a > time ? a : a + 2**32;\n uint256 bAdjusted = b > time ? b : b + 2**32;\n\n return aAdjusted <= bAdjusted;\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\n /// The result may be the same observation, or adjacent observations.\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation recorded before, or at, the target\n /// @return atOrAfter The observation recorded at, or after, the target\n function binarySearch(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n uint16 index,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n uint256 l = (index + 1) % cardinality; // oldest observation\n uint256 r = l + cardinality - 1; // newest observation\n uint256 i;\n while (true) {\n i = (l + r) / 2;\n\n beforeOrAt = self[i % cardinality];\n\n // we've landed on an uninitialized tick, keep searching higher (more recently)\n if (!beforeOrAt.initialized) {\n l = i + 1;\n continue;\n }\n\n atOrAfter = self[(i + 1) % cardinality];\n\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\n\n // check if we've found the answer!\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\n\n if (!targetAtOrAfter) r = i - 1;\n else l = i + 1;\n }\n }\n }\n\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\n /// @dev Assumes there is at least 1 initialized observation.\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param target The timestamp at which the reserved observation should be for\n /// @param tick The active tick at the time of the returned or simulated observation\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The total pool liquidity at the time of the call\n /// @param cardinality The number of populated elements in the oracle array\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\n function getSurroundingObservations(\n Observation[65535] storage self,\n uint32 time,\n uint32 target,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n unchecked {\n // optimistically set before to the newest observation\n beforeOrAt = self[index];\n\n // if the target is chronologically at or after the newest observation, we can early return\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\n if (beforeOrAt.blockTimestamp == target) {\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\n return (beforeOrAt, atOrAfter);\n } else {\n // otherwise, we need to transform\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\n }\n }\n\n // now, set before to the oldest observation\n beforeOrAt = self[(index + 1) % cardinality];\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\n\n // ensure that the target is chronologically at or after the oldest observation\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\n\n // if we've reached this point, we have to binary search\n return binarySearch(self, time, target, index, cardinality);\n }\n }\n\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\n /// at exactly the timestamp between the two observations.\n /// @param self The stored oracle array\n /// @param time The current block timestamp\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\n function observeSingle(\n Observation[65535] storage self,\n uint32 time,\n uint32 secondsAgo,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\n unchecked {\n if (secondsAgo == 0) {\n Observation memory last = self[index];\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\n }\n\n uint32 target = time - secondsAgo;\n\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\n self,\n time,\n target,\n tick,\n index,\n liquidity,\n cardinality\n );\n\n if (target == beforeOrAt.blockTimestamp) {\n // we're at the left boundary\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\n } else if (target == atOrAfter.blockTimestamp) {\n // we're at the right boundary\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\n } else {\n // we're in the middle\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\n return (\n beforeOrAt.tickCumulative +\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\n int56(uint56(targetDelta)),\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\n uint160(\n (uint256(\n atOrAfter.secondsPerLiquidityCumulativeX128 -\n beforeOrAt.secondsPerLiquidityCumulativeX128\n ) * targetDelta) / observationTimeDelta\n )\n );\n }\n }\n }\n\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\n /// @dev Reverts if `secondsAgos` > oldest observation\n /// @param self The stored oracle array\n /// @param time The current block.timestamp\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\n /// @param tick The current tick\n /// @param index The index of the observation that was most recently written to the observations array\n /// @param liquidity The current in-range pool liquidity\n /// @param cardinality The number of populated elements in the oracle array\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\n function observe(\n Observation[65535] storage self,\n uint32 time,\n uint32[] memory secondsAgos,\n int24 tick,\n uint16 index,\n uint128 liquidity,\n uint16 cardinality\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\n unchecked {\n if (cardinality <= 0) revert I();\n\n tickCumulatives = new int56[](secondsAgos.length);\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\n for (uint256 i = 0; i < secondsAgos.length; i++) {\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\n self,\n time,\n secondsAgos[i],\n tick,\n index,\n liquidity,\n cardinality\n );\n }\n }\n }\n}\n" - }, - "solidity/interfaces/bridges/IConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from './IBridgeReceiverAdapter.sol';\n\ninterface IConnextReceiverAdapter is IBridgeReceiverAdapter {\n // STATE VARIABLES\n\n function connext() external view returns (IConnext _connext);\n\n function source() external view returns (address _originContract);\n\n function originDomain() external view returns (uint32 _originDomain);\n}\n" - }, - "solidity/contracts/bridges/ConnextSenderAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {LibConnextStorage, TransferInfo} from '@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol';\nimport {IConnext, IConnextSenderAdapter, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../../interfaces/bridges/IConnextSenderAdapter.sol';\n\ncontract ConnextSenderAdapter is IConnextSenderAdapter {\n /// @inheritdoc IConnextSenderAdapter\n IConnext public immutable connext;\n\n /// @inheritdoc IConnextSenderAdapter\n IDataFeed public immutable dataFeed;\n\n constructor(IConnext _connext, IDataFeed _dataFeed) {\n connext = _connext;\n dataFeed = _dataFeed;\n }\n\n /// @inheritdoc IBridgeSenderAdapter\n function bridgeObservations(\n address _to,\n uint32 _destinationDomainId,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce // TODO: review input parameters packing KMC-\n ) external payable onlyDataFeed {\n bytes memory _callData = abi.encode(_observationsData, _poolSalt, _poolNonce);\n\n connext.xcall({\n _destination: _destinationDomainId, // unique identifier for destination domain\n _to: _to, // recipient of funds, where calldata will be executed\n _asset: address(0), // asset being transferred\n _delegate: address(0), // permissioned address to recover in edgecases on destination domain\n _amount: 0, // amount being transferred\n _slippage: 0, // slippage in bps\n _callData: _callData // to be executed on _to on the destination domain\n });\n }\n\n modifier onlyDataFeed() {\n if (msg.sender != address(dataFeed)) revert OnlyDataFeed();\n _;\n }\n}\n" - }, - "solidity/interfaces/peripherals/IKeep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './IGovernable.sol';\nimport {IKeep3r} from '@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol';\n\ninterface IKeep3rJob is IGovernable {\n // STATE VARIABLES\n\n /// @return _keep3r Address of the Keep3r contract\n function keep3r() external view returns (IKeep3r _keep3r);\n\n // EVENTS\n\n /// @notice Emitted when a new Keep3r contract is set\n /// @param _keep3r Address of the new Keep3r contract\n event Keep3rSet(IKeep3r _keep3r);\n\n // ERRORS\n\n /// @notice Throws when a keeper fails the validation\n error KeeperNotValid();\n\n // FUNCTIONS\n\n /// @notice Allows governor to set a new Keep3r contract\n /// @param _keep3r Address of the new Keep3r contract\n function setKeep3r(IKeep3r _keep3r) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/IKeep3r.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rAccountance.sol';\nimport './peripherals/IKeep3rRoles.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rAccountance, IKeep3rRoles, IKeep3rParameters {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rKeepers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable, IKeep3rKeeperFundable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rJobs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobOwnership, IKeep3rJobDisputable, IKeep3rJobMigration, IKeep3rJobManager, IKeep3rJobWorkable {\n\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rAccountance.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rRoles.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IKeep3rParameters.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\n\ninterface IKeep3rParameters is IBaseErrors {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" - }, - "@defi-wonderland/keep3r-v2/solidity/interfaces/peripherals/IBaseErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" - }, - "solidity/interfaces/IStrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IKeep3rJob} from './peripherals/IKeep3rJob.sol';\nimport {IDataFeedStrategy} from './IDataFeedStrategy.sol';\nimport {IDataFeed} from './IDataFeed.sol';\nimport {IBridgeSenderAdapter} from './bridges/IBridgeSenderAdapter.sol';\nimport {IOracleSidechain} from './IOracleSidechain.sol';\n\ninterface IStrategyJob is IKeep3rJob {\n // STATE VARIABLES\n\n /// @return _dataFeedStrategy The address of the current DataFeedStrategy\n function dataFeedStrategy() external view returns (IDataFeedStrategy _dataFeedStrategy);\n\n /// @return _dataFeed The address of the DataFeed\n function dataFeed() external view returns (IDataFeed _dataFeed);\n\n /// @return _defaultBridgeSenderAdapter The address of the job bridge sender adapter\n function defaultBridgeSenderAdapter() external view returns (IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n /// @param _chainId The identifier of the chain\n /// @param _poolSalt The identifier of both the pool and oracle\n /// @return _lastPoolNonceBridged Last nonce of the oracle observed\n function lastPoolNonceBridged(uint32 _chainId, bytes32 _poolSalt) external view returns (uint24 _lastPoolNonceBridged);\n\n // EVENTS\n\n /// @notice Emitted when a new default bridge sender adapter is set\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n event DefaultBridgeSenderAdapterSet(IBridgeSenderAdapter _defaultBridgeSenderAdapter);\n\n // ERRORS\n\n /// @notice Thrown when the job is not workable\n error NotWorkable();\n\n // FUNCTIONS\n\n /// @notice Calls to send observations in the DataFeed contract\n /// @param _chainId The Ethereum chain identification\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external;\n\n /// @notice Calls to fetch observations and update the oracle state in the DataFeed contract\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The identifier of the reason to trigger an update\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external;\n\n /// @notice Allows governor to set a new default bridge sender adapter\n /// @param _defaultBridgeSenderAdapter Address of the new default bridge sender adapter\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external;\n\n /// @notice Returns if the job can be worked\n /// @param _chainId The destination chain ID\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _poolNonce The nonce of the observations fetched by pool\n /// @return _isWorkable Whether the job is workable or not\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external view returns (bool _isWorkable);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @return _reason The reason why the job can be worked\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason);\n\n /// @notice Returns if the job can be worked\n /// @param _poolSalt The pool salt defined by token0 token1 and fee\n /// @param _reason The reason why the job can be worked\n /// @return _isWorkable Whether the job is workable or not\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external view returns (bool _isWorkable);\n}\n" - }, - "solidity/contracts/OracleFactory.sol": { - "content": "//TODO: change license\n//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {OracleSidechain} from './OracleSidechain.sol';\nimport {IOracleFactory, IOracleSidechain, IDataReceiver} from '../interfaces/IOracleFactory.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The OracleFactory contract\n/// @notice Handles the deployment of new OracleSidechains\ncontract OracleFactory is IOracleFactory, Governable {\n /// @inheritdoc IOracleFactory\n IDataReceiver public dataReceiver;\n\n /// @inheritdoc IOracleFactory\n OracleParameters public oracleParameters;\n\n /// @inheritdoc IOracleFactory\n uint16 public initialCardinality = 144;\n\n /// @inheritdoc IOracleFactory\n bytes32 public constant ORACLE_INIT_CODE_HASH = keccak256(type(OracleSidechain).creationCode);\n\n constructor(address _governor, IDataReceiver _dataReceiver) Governable(_governor) {\n dataReceiver = _dataReceiver;\n }\n\n /// @inheritdoc IOracleFactory\n function deployOracle(bytes32 _poolSalt, uint24 _initialNonce) external onlyDataReceiver returns (IOracleSidechain _oracle) {\n oracleParameters = OracleParameters({poolSalt: _poolSalt, poolNonce: _initialNonce, cardinality: initialCardinality});\n _oracle = new OracleSidechain{salt: _poolSalt}();\n\n delete oracleParameters;\n emit OracleDeployed(_poolSalt, address(_oracle), _initialNonce);\n }\n\n /// @inheritdoc IOracleFactory\n function setDataReceiver(IDataReceiver _dataReceiver) external onlyGovernor {\n dataReceiver = _dataReceiver;\n emit DataReceiverSet(_dataReceiver);\n }\n\n /// @inheritdoc IOracleFactory\n function setInitialCardinality(uint16 _initialCardinality) external onlyGovernor {\n initialCardinality = _initialCardinality;\n emit InitialCardinalitySet(_initialCardinality);\n }\n\n function increaseOracleCardinality(bytes32 _poolSalt, uint16 _observationCardinalityNext) external onlyGovernor {\n IOracleSidechain _oracle = getPool(_poolSalt);\n _oracle.increaseObservationCardinalityNext(_observationCardinalityNext);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) external view returns (IOracleSidechain _oracle) {\n bytes32 _poolSalt = getPoolSalt(_tokenA, _tokenB, _fee);\n _oracle = getPool(_poolSalt);\n }\n\n /// @inheritdoc IOracleFactory\n function getPool(bytes32 _poolSalt) public view returns (IOracleSidechain _oracle) {\n _oracle = IOracleSidechain(Create2Address.computeAddress(address(this), _poolSalt, ORACLE_INIT_CODE_HASH));\n if (address(_oracle).code.length == 0) return IOracleSidechain(address(0));\n }\n\n /// @inheritdoc IOracleFactory\n function getPoolSalt(\n address _tokenA,\n address _tokenB,\n uint24 _fee\n ) public pure returns (bytes32 _poolSalt) {\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\n _poolSalt = keccak256(abi.encode(_token0, _token1, _fee));\n }\n\n modifier onlyDataReceiver() {\n if (msg.sender != address(dataReceiver)) revert OnlyDataReceiver();\n _;\n }\n}\n" - }, - "solidity/for-test/DummyAdapterForTest.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {OracleSidechain} from '../contracts/OracleSidechain.sol';\nimport {IOracleSidechain} from '../interfaces/IOracleSidechain.sol';\nimport {IDataReceiver} from '../interfaces/IDataReceiver.sol';\n\ncontract DummyAdapterForTest {\n // TODO: factorize interfaces so that this adapter can use same as sender/receiver\n event SentData(IDataReceiver, IOracleSidechain.ObservationData[]);\n event Create2Hash(bytes32);\n\n bool public ignoreTxs;\n\n constructor() {\n /// @dev Emitted to validate correct calculation of ORACLE_INIT_CODE_HASH\n emit Create2Hash(keccak256(type(OracleSidechain).creationCode));\n }\n\n function bridgeObservations(\n IDataReceiver _to,\n uint32,\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) external payable {\n if (!ignoreTxs) {\n _to.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n emit SentData(_to, _observationsData);\n }\n\n function setIgnoreTxs(bool _ignoreTxs) external {\n ignoreTxs = _ignoreTxs;\n }\n}\n" - }, - "solidity/for-test/GovernableForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from '../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" - }, - "solidity/contracts/DataFeedStrategy.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './peripherals/Governable.sol';\nimport {IDataFeedStrategy, IUniswapV3Pool, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IDataFeedStrategy.sol';\nimport {Create2Address} from '../libraries/Create2Address.sol';\n\n/// @title The DataFeed Strategy contract\n/// @notice Handles when and how a history of a pool should be updated\ncontract DataFeedStrategy is IDataFeedStrategy, Governable {\n /// @inheritdoc IDataFeedStrategy\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public periodDuration;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public strategyCooldown;\n\n /// @inheritdoc IDataFeedStrategy\n uint24 public twapThreshold;\n\n /// @inheritdoc IDataFeedStrategy\n uint32 public twapLength;\n\n address internal constant _UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n bytes32 internal constant _POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;\n\n constructor(\n address _governor,\n IDataFeed _dataFeed,\n StrategySettings memory _params\n ) Governable(_governor) {\n dataFeed = _dataFeed;\n _setStrategyCooldown(_params.cooldown);\n _setTwapLength(_params.twapLength);\n _setTwapThreshold(_params.twapThreshold);\n _setPeriodDuration(_params.periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function strategicFetchObservations(bytes32 _poolSalt, TriggerReason _reason) external {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n if (!_isStrategic(_poolSalt, _lastPoolStateObserved, _reason)) revert NotStrategic();\n uint32[] memory _secondsAgos = calculateSecondsAgos(_lastPoolStateObserved.blockTimestamp);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n emit StrategicFetch(_poolSalt, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n /// @dev Allows governor to choose a timestamp from which to send data (overcome !OLD error)\n function forceFetchObservations(bytes32 _poolSalt, uint32 _fromTimestamp) external onlyGovernor {\n uint32[] memory _secondsAgos = calculateSecondsAgos(_fromTimestamp);\n dataFeed.fetchObservations(_poolSalt, _secondsAgos);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setStrategyCooldown(uint32 _strategyCooldown) external onlyGovernor {\n _setStrategyCooldown(_strategyCooldown);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapLength(uint32 _twapLength) external onlyGovernor {\n _setTwapLength(_twapLength);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setTwapThreshold(uint24 _twapThreshold) external onlyGovernor {\n _setTwapThreshold(_twapThreshold);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function setPeriodDuration(uint32 _periodDuration) external onlyGovernor {\n _setPeriodDuration(_periodDuration);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt) external view returns (TriggerReason _reason) {\n if (isStrategic(_poolSalt, TriggerReason.TIME)) return TriggerReason.TIME;\n if (isStrategic(_poolSalt, TriggerReason.TWAP)) return TriggerReason.TWAP;\n }\n\n /// @inheritdoc IDataFeedStrategy\n function isStrategic(bytes32 _poolSalt, TriggerReason _reason) public view returns (bool _strategic) {\n IDataFeed.PoolState memory _lastPoolStateObserved;\n (, _lastPoolStateObserved.blockTimestamp, _lastPoolStateObserved.tickCumulative, _lastPoolStateObserved.arithmeticMeanTick) = dataFeed\n .lastPoolStateObserved(_poolSalt);\n return _isStrategic(_poolSalt, _lastPoolStateObserved, _reason);\n }\n\n /// @inheritdoc IDataFeedStrategy\n function calculateSecondsAgos(uint32 _fromTimestamp) public view returns (uint32[] memory _secondsAgos) {\n if (_fromTimestamp == 0) return _initializeSecondsAgos();\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n uint32 _timeSinceLastObservation = _secondsNow - _fromTimestamp;\n uint32 _periodDuration = periodDuration;\n uint32 _periods = _timeSinceLastObservation / _periodDuration;\n uint32 _remainder = _timeSinceLastObservation % _periodDuration;\n uint32 _i;\n\n if (_remainder != 0) {\n _secondsAgos = new uint32[](++_periods);\n _timeSinceLastObservation -= _remainder;\n _secondsAgos[_i++] = _timeSinceLastObservation;\n } else {\n _secondsAgos = new uint32[](_periods);\n }\n\n while (_timeSinceLastObservation > 0) {\n _timeSinceLastObservation -= _periodDuration;\n _secondsAgos[_i++] = _timeSinceLastObservation;\n }\n }\n\n function _isStrategic(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n TriggerReason _reason\n ) internal view returns (bool _strategic) {\n uint32 _secondsNow = uint32(block.timestamp); // truncation is desired\n if (_reason == TriggerReason.TIME) {\n return _secondsNow >= _lastPoolStateObserved.blockTimestamp + strategyCooldown;\n } else if (_reason == TriggerReason.TWAP) {\n return _twapIsOutOfThresholds(_poolSalt, _lastPoolStateObserved, _secondsNow);\n }\n }\n\n function _twapIsOutOfThresholds(\n bytes32 _poolSalt,\n IDataFeed.PoolState memory _lastPoolStateObserved,\n uint32 _secondsNow\n ) internal view returns (bool _isOutOfThresholds) {\n uint32 _twapLength = twapLength;\n\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[0] = _twapLength;\n _secondsAgos[1] = 0;\n\n IUniswapV3Pool _pool = IUniswapV3Pool(Create2Address.computeAddress(_UNISWAP_FACTORY, _poolSalt, _POOL_INIT_CODE_HASH));\n (int56[] memory _poolTickCumulatives, ) = _pool.observe(_secondsAgos);\n\n int24 _poolArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _poolTickCumulatives[1], _twapLength);\n\n uint32 _oracleDelta = _secondsNow - _lastPoolStateObserved.blockTimestamp;\n int56 _oracleTickCumulative = _lastPoolStateObserved.tickCumulative + int56(_lastPoolStateObserved.arithmeticMeanTick) * int32(_oracleDelta);\n\n int24 _oracleArithmeticMeanTick = _computeTwap(_poolTickCumulatives[0], _oracleTickCumulative, _twapLength);\n\n return\n _poolArithmeticMeanTick > _oracleArithmeticMeanTick + int24(twapThreshold) ||\n _poolArithmeticMeanTick < _oracleArithmeticMeanTick - int24(twapThreshold);\n }\n\n function _computeTwap(\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n uint32 _delta\n ) internal pure returns (int24 _arithmeticMeanTick) {\n int56 _tickCumulativesDelta = _tickCumulative2 - _tickCumulative1;\n _arithmeticMeanTick = int24(_tickCumulativesDelta / int32(_delta));\n // Always round to negative infinity\n if (_tickCumulativesDelta < 0 && (_tickCumulativesDelta % int32(_delta) != 0)) --_arithmeticMeanTick;\n }\n\n function _initializeSecondsAgos() internal view returns (uint32[] memory _secondsAgos) {\n // TODO: define initialization of _secondsAgos\n _secondsAgos = new uint32[](2);\n _secondsAgos[0] = periodDuration;\n _secondsAgos[1] = 0; // as if _fromTimestamp = _secondsNow - (periodDuration + 1)\n }\n\n function _setStrategyCooldown(uint32 _strategyCooldown) private {\n if (_strategyCooldown < twapLength) revert WrongSetting();\n\n strategyCooldown = _strategyCooldown;\n emit StrategyCooldownSet(_strategyCooldown);\n }\n\n function _setTwapLength(uint32 _twapLength) private {\n if ((_twapLength > strategyCooldown) || (_twapLength < periodDuration)) revert WrongSetting();\n\n twapLength = _twapLength;\n emit TwapLengthSet(_twapLength);\n }\n\n function _setTwapThreshold(uint24 _twapThreshold) private {\n twapThreshold = _twapThreshold;\n emit TwapThresholdSet(_twapThreshold);\n }\n\n function _setPeriodDuration(uint32 _periodDuration) private {\n if (_periodDuration > twapLength) revert WrongSetting();\n\n periodDuration = _periodDuration;\n emit PeriodDurationSet(_periodDuration);\n }\n}\n" - }, - "solidity/contracts/peripherals/Keep3rJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './Governable.sol';\nimport {IKeep3rJob, IKeep3r} from '../../interfaces/peripherals/IKeep3rJob.sol';\n\nabstract contract Keep3rJob is IKeep3rJob, Governable {\n /// @inheritdoc IKeep3rJob\n IKeep3r public keep3r = IKeep3r(0xeb02addCfD8B773A5FFA6B9d1FE99c566f8c44CC);\n\n /// @inheritdoc IKeep3rJob\n function setKeep3r(IKeep3r _keep3r) public onlyGovernor {\n _setKeep3r(_keep3r);\n }\n\n function _setKeep3r(IKeep3r _keep3r) internal {\n keep3r = _keep3r;\n emit Keep3rSet(_keep3r);\n }\n\n function _isValidKeeper(address _keeper) internal virtual {\n if (!keep3r.isKeeper(_keeper)) revert KeeperNotValid();\n }\n\n modifier upkeep() {\n _isValidKeeper(msg.sender);\n _;\n keep3r.worked(msg.sender);\n }\n}\n" - }, - "solidity/for-test/Keep3rJobForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from '../contracts/peripherals/Keep3rJob.sol';\n\ncontract Keep3rJobForTest is Keep3rJob {\n constructor(address _governor) Governable(_governor) {}\n\n function internalIsValidKeeper(address _keeper) external {\n _isValidKeeper(_keeper);\n }\n}\n" - }, - "solidity/contracts/StrategyJob.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Keep3rJob, Governable} from './peripherals/Keep3rJob.sol';\nimport {IStrategyJob, IDataFeedStrategy, IDataFeed, IBridgeSenderAdapter, IOracleSidechain} from '../interfaces/IStrategyJob.sol';\n\n/// @title The StrategyJob contract\n/// @notice Adds a reward layer for triggering fetch and bridge transactions\ncontract StrategyJob is IStrategyJob, Keep3rJob {\n /// @inheritdoc IStrategyJob\n IDataFeedStrategy public immutable dataFeedStrategy;\n\n /// @inheritdoc IStrategyJob\n IDataFeed public immutable dataFeed;\n\n /// @inheritdoc IStrategyJob\n IBridgeSenderAdapter public defaultBridgeSenderAdapter;\n\n /// @inheritdoc IStrategyJob\n mapping(uint32 => mapping(bytes32 => uint24)) public lastPoolNonceBridged;\n\n constructor(\n address _governor,\n IDataFeedStrategy _dataFeedStrategy,\n IDataFeed _dataFeed,\n IBridgeSenderAdapter _defaultBridgeSenderAdapter\n ) Governable(_governor) {\n dataFeedStrategy = _dataFeedStrategy;\n dataFeed = _dataFeed;\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function work(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce,\n IOracleSidechain.ObservationData[] memory _observationsData\n ) external upkeep {\n // TODO: change criteria for workable (if there's a new nonce, bridge)\n if (!_workable(_chainId, _poolSalt, _poolNonce)) revert NotWorkable();\n lastPoolNonceBridged[_chainId][_poolSalt] = _poolNonce;\n dataFeed.sendObservations(defaultBridgeSenderAdapter, _chainId, _poolSalt, _poolNonce, _observationsData);\n }\n\n /// @inheritdoc IStrategyJob\n function work(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) external upkeep {\n dataFeedStrategy.strategicFetchObservations(_poolSalt, _reason);\n }\n\n /// @inheritdoc IStrategyJob\n function setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) external onlyGovernor {\n _setDefaultBridgeSenderAdapter(_defaultBridgeSenderAdapter);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) public view returns (bool _isWorkable) {\n uint24 _whitelistedNonce = dataFeed.whitelistedNonces(_chainId, _poolSalt);\n if (_whitelistedNonce != 0 && _whitelistedNonce <= _poolNonce) return _workable(_chainId, _poolSalt, _poolNonce);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt) external view returns (IDataFeedStrategy.TriggerReason _reason) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt);\n }\n\n /// @inheritdoc IStrategyJob\n function workable(bytes32 _poolSalt, IDataFeedStrategy.TriggerReason _reason) public view returns (bool _isWorkable) {\n if (dataFeed.isWhitelistedPool(_poolSalt)) return dataFeedStrategy.isStrategic(_poolSalt, _reason);\n }\n\n function _workable(\n uint32 _chainId,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal view returns (bool _isWorkable) {\n uint24 _lastPoolNonceBridged = lastPoolNonceBridged[_chainId][_poolSalt];\n if (_lastPoolNonceBridged == 0) {\n (uint24 _lastPoolNonceObserved, , , ) = dataFeed.lastPoolStateObserved(_poolSalt);\n return _poolNonce == _lastPoolNonceObserved;\n } else {\n return _poolNonce == ++_lastPoolNonceBridged;\n }\n }\n\n function _setDefaultBridgeSenderAdapter(IBridgeSenderAdapter _defaultBridgeSenderAdapter) private {\n defaultBridgeSenderAdapter = _defaultBridgeSenderAdapter;\n emit DefaultBridgeSenderAdapterSet(_defaultBridgeSenderAdapter);\n }\n}\n" - }, - "@openzeppelin/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" - }, - "@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "solidity/for-test/ERC20ForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n // solhint-disable-next-line no-empty-blocks\n function deposit(uint256 _amount) external payable {\n // Function added for compatibility with WETH\n }\n}\n" - }, - "solidity/contracts/bridges/ConnextReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {BridgeReceiverAdapter} from './BridgeReceiverAdapter.sol';\nimport {IConnext, IConnextReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IConnextReceiverAdapter.sol';\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextReceiverAdapter is BridgeReceiverAdapter, IXReceiver, IConnextReceiverAdapter {\n // The connectHandler contract on this domain\n IConnext public immutable connext;\n // The origin domain ID\n uint32 public immutable originDomain;\n // The DAO that's expected as the xcaller\n address public immutable source;\n\n constructor(\n IDataReceiver _dataReceiver,\n address _source,\n uint32 _originDomain,\n IConnext _connext\n ) BridgeReceiverAdapter(_dataReceiver) {\n source = _source;\n originDomain = _originDomain;\n connext = _connext;\n }\n\n function xReceive(\n bytes32, // _transferId\n uint256, // _amount\n address, // _asset\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external onlyExecutor(_originSender, _origin) returns (bytes memory) {\n (IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, uint24 _poolNonce) = abi.decode(\n _callData,\n (IOracleSidechain.ObservationData[], bytes32, uint24)\n );\n\n _addObservations(_observationsData, _poolSalt, _poolNonce);\n return bytes(abi.encode(''));\n }\n\n modifier onlyExecutor(address _originSender, uint32 _originDomain) {\n if (msg.sender != address(connext) || _originSender != source || _originDomain != originDomain) revert UnauthorizedCaller();\n _;\n }\n}\n" - }, - "solidity/contracts/bridges/BridgeReceiverAdapter.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IBridgeReceiverAdapter.sol';\n\nabstract contract BridgeReceiverAdapter is IBridgeReceiverAdapter {\n /// @inheritdoc IBridgeReceiverAdapter\n IDataReceiver public immutable dataReceiver;\n\n constructor(IDataReceiver _dataReceiver) {\n dataReceiver = _dataReceiver;\n }\n\n function _addObservations(\n IOracleSidechain.ObservationData[] memory _observationsData,\n bytes32 _poolSalt,\n uint24 _poolNonce\n ) internal {\n dataReceiver.addObservations(_observationsData, _poolSalt, _poolNonce);\n }\n}\n" - }, - "@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\ninterface IXReceiver {\n function xReceive(\n bytes32 _transferId,\n uint256 _amount,\n address _asset,\n address _originSender,\n uint32 _origin,\n bytes memory _callData\n ) external returns (bytes memory);\n}\n" - }, - "solidity/for-test/ConnextHandlerForTest.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\n\ncontract ConnextHandlerForTest {\n uint32 public origin;\n\n constructor() {\n // TODO: set in constructor\n origin = 1111;\n }\n\n function xcall(\n uint32, // _destination, unique identifier for destination domain\n address _to, // recipient of funds, where calldata will be executed\n address, // _asset, asset being transferred\n address, // _delegate, permissioned address to recover in edgecases on destination domain\n uint256, // _amount, amount being transferred\n uint256, // _slippage, slippage in bps\n bytes calldata _callData // to be executed on _to on the destination domain\n ) external payable returns (bytes32) {\n IXReceiver(_to).xReceive({_transferId: 0, _amount: 0, _asset: address(0), _originSender: msg.sender, _origin: origin, _callData: _callData});\n\n return bytes32(abi.encode('random'));\n }\n}\n" - }, - "solidity/for-test/UniswapV3Importer.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IUniswapV3Factory} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';\nimport {ISwapRouter} from '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';\n\n//import {INonfungiblePositionManager} from '@uniswap/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol';\n\ninterface INFTPositionManager {\n struct MintParams {\n address token0;\n address token1;\n uint24 fee;\n int24 tickLower;\n int24 tickUpper;\n uint256 amount0Desired;\n uint256 amount1Desired;\n uint256 amount0Min;\n uint256 amount1Min;\n address recipient;\n uint256 deadline;\n }\n\n function mint(MintParams calldata _params)\n external\n payable\n returns (\n uint256 _tokenId,\n uint128 _liquidity,\n uint256 _amount0,\n uint256 _amount1\n );\n}\n\n// solhint-disable-next-line no-empty-blocks\ncontract UniswapV3Importer {\n\n}\n" - }, - "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\npragma abicoder v2;\n\nimport '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface ISwapRouter is IUniswapV3SwapCallback {\n struct ExactInputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactOutputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);\n\n struct ExactOutputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title The interface for the Uniswap V3 Factory\n/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees\ninterface IUniswapV3Factory {\n /// @notice Emitted when the owner of the factory is changed\n /// @param oldOwner The owner before the owner was changed\n /// @param newOwner The owner after the owner was changed\n event OwnerChanged(address indexed oldOwner, address indexed newOwner);\n\n /// @notice Emitted when a pool is created\n /// @param token0 The first token of the pool by address sort order\n /// @param token1 The second token of the pool by address sort order\n /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip\n /// @param tickSpacing The minimum number of ticks between initialized ticks\n /// @param pool The address of the created pool\n event PoolCreated(\n address indexed token0,\n address indexed token1,\n uint24 indexed fee,\n int24 tickSpacing,\n address pool\n );\n\n /// @notice Emitted when a new fee amount is enabled for pool creation via the factory\n /// @param fee The enabled fee, denominated in hundredths of a bip\n /// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee\n event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing);\n\n /// @notice Returns the current owner of the factory\n /// @dev Can be changed by the current owner via setOwner\n /// @return The address of the factory owner\n function owner() external view returns (address);\n\n /// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled\n /// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context\n /// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee\n /// @return The tick spacing\n function feeAmountTickSpacing(uint24 fee) external view returns (int24);\n\n /// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist\n /// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order\n /// @param tokenA The contract address of either token0 or token1\n /// @param tokenB The contract address of the other token\n /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip\n /// @return pool The pool address\n function getPool(\n address tokenA,\n address tokenB,\n uint24 fee\n ) external view returns (address pool);\n\n /// @notice Creates a pool for the given two tokens and fee\n /// @param tokenA One of the two tokens in the desired pool\n /// @param tokenB The other of the two tokens in the desired pool\n /// @param fee The desired fee for the pool\n /// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved\n /// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments\n /// are invalid.\n /// @return pool The address of the newly created pool\n function createPool(\n address tokenA,\n address tokenB,\n uint24 fee\n ) external returns (address pool);\n\n /// @notice Updates the owner of the factory\n /// @dev Must be called by the current owner\n /// @param _owner The new owner of the factory\n function setOwner(address _owner) external;\n\n /// @notice Enables a fee amount with the given tickSpacing\n /// @dev Fee amounts may never be removed once enabled\n /// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6)\n /// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount\n function enableFeeAmount(uint24 fee, int24 tickSpacing) external;\n}\n" - }, - "@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol": { - "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Callback for IUniswapV3PoolActions#swap\n/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface\ninterface IUniswapV3SwapCallback {\n /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n /// @dev In the implementation you must pay the pool tokens owed for the swap.\n /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n function uniswapV3SwapCallback(\n int256 amount0Delta,\n int256 amount1Delta,\n bytes calldata data\n ) external;\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file diff --git a/deployments/polygon/.chainId b/deployments/polygon/.chainId new file mode 100644 index 0000000..0973804 --- /dev/null +++ b/deployments/polygon/.chainId @@ -0,0 +1 @@ +137 \ No newline at end of file diff --git a/deployments/polygon/ConnextReceiverAdapter.json b/deployments/polygon/ConnextReceiverAdapter.json new file mode 100644 index 0000000..77b5244 --- /dev/null +++ b/deployments/polygon/ConnextReceiverAdapter.json @@ -0,0 +1,279 @@ +{ + "address": "0x4839750090571A0fCcBaa3a8Fffe3DE22b4B7D51", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IDataReceiver", + "name": "_dataReceiver", + "type": "address" + }, + { + "internalType": "contract IConnext", + "name": "_connext", + "type": "address" + }, + { + "internalType": "address", + "name": "_source", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_originDomain", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "LengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "UnauthorizedCaller", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "inputs": [], + "name": "connext", + "outputs": [ + { + "internalType": "contract IConnext", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dataReceiver", + "outputs": [ + { + "internalType": "contract IDataReceiver", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "originDomain", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "source", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "_originSender", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_origin", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_callData", + "type": "bytes" + } + ], + "name": "xReceive", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x7ab446c7470846b9111cda28f7ce6eb41cbaaa16e16c6c193410ad4e80c71dc7", + "receipt": { + "to": null, + "from": "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "contractAddress": "0x4839750090571A0fCcBaa3a8Fffe3DE22b4B7D51", + "transactionIndex": 31, + "gasUsed": "408291", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000008000000000000000000000000000800000000000000000000000000000800000000000000004000100000000000100000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000040001000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x421e05f516e2ffc103163239fb64c4d4d61c717da593fc746e2ec4a022938689", + "transactionHash": "0x7ab446c7470846b9111cda28f7ce6eb41cbaaa16e16c6c193410ad4e80c71dc7", + "logs": [ + { + "transactionIndex": 31, + "blockNumber": 60867661, + "transactionHash": "0x7ab446c7470846b9111cda28f7ce6eb41cbaaa16e16c6c193410ad4e80c71dc7", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000a6dbff53dd8f89f0bf4f6800bfdffe099875bd9d", + "0x000000000000000000000000b95d435df3f8b2a8d8b9c2b7c8766c9ae6ed8cc9" + ], + "data": "0x000000000000000000000000000000000000000000000000002ce92da346e9640000000000000000000000000000000000000000000000004af4f803dc4dff210000000000000000000000000000000000000000000000231ba49a6617a54e760000000000000000000000000000000000000000000000004ac80ed6390715bd0000000000000000000000000000000000000000000000231bd18393baec37da", + "logIndex": 128, + "blockHash": "0x421e05f516e2ffc103163239fb64c4d4d61c717da593fc746e2ec4a022938689" + } + ], + "blockNumber": 60867661, + "cumulativeGasUsed": "3989023", + "status": 1, + "byzantium": true + }, + "args": [ + "0xe5BE7f12B94D185f892c4BBe6F88ABE65CE1A8af", + "0x11984dc4465481512eb5b777E44061C158CF2259", + "0x5b9315CE1304DF3B2A83B2074cbF849D160642Ab", + 6648936 + ], + "numDeployments": 1, + "solcInputHash": "1ffcc3895a1a8980b9e58deee89219d1", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"},{\"internalType\":\"contract IConnext\",\"name\":\"_connext\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_source\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_originDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"connext\",\"outputs\":[{\"internalType\":\"contract IConnext\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dataReceiver\",\"outputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"originDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"source\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_originSender\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_callData\",\"type\":\"bytes\"}],\"name\":\"xReceive\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"connext\":{\"return\":\"Address of the ConnextHandler contract\",\"returns\":{\"_0\":\"Address of the ConnextHandler contract\"}},\"originDomain\":{\"return\":\"The origin domain id\",\"returns\":{\"_0\":\"The origin domain id\"}},\"source\":{\"return\":\"Address of the xcaller contract\",\"returns\":{\"_0\":\"Address of the xcaller contract\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"UnauthorizedCaller()\":[{\"notice\":\"Thrown if a caller is not authorized\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"kind\":\"user\",\"methods\":{\"connext()\":{\"notice\":\"Gets the ConnextHandler contract on this domain\"},\"dataReceiver()\":{\"notice\":\"Gets the address of the DataReceiver contract\"},\"originDomain()\":{\"notice\":\"Gets the origin domain id\"},\"source()\":{\"notice\":\"Gets the DAO that is expected as the xcaller\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/bridges/ConnextReceiverAdapter.sol\":\"ConnextReceiverAdapter\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {ERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title Liquidity Provider Token\\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\\n * It is used to represent user's shares when providing liquidity to swap contracts.\\n * @dev Only Swap contracts should initialize and own LPToken contracts.\\n */\\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\\n // ============ Upgrade Gap ============\\n\\n uint256[49] private __GAP; // gap for upgrade safety\\n\\n // ============ Storage ============\\n\\n /**\\n * @notice Used to enforce proper token dilution\\n * @dev If this is the first mint of the LP token, this amount of funds are burned.\\n * See audit recommendations here:\\n * - https://github.com/code-423n4/2022-03-prepo-findings/issues/27\\n * - https://github.com/code-423n4/2022-04-jpegd-findings/issues/12\\n * and uniswap v2 implementation here:\\n * https://github.com/Uniswap/v2-core/blob/8b82b04a0b9e696c0e83f8b2f00e5d7be6888c79/contracts/UniswapV2Pair.sol#L15\\n */\\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\\n\\n // ============ Initializer ============\\n\\n /**\\n * @notice Initializes this LPToken contract with the given name and symbol\\n * @dev The caller of this function will become the owner. A Swap contract should call this\\n * in its initializer function.\\n * @param name name of this token\\n * @param symbol symbol of this token\\n */\\n function initialize(string memory name, string memory symbol) external initializer returns (bool) {\\n __Context_init_unchained();\\n __ERC20_init_unchained(name, symbol);\\n __Ownable_init_unchained();\\n return true;\\n }\\n\\n // ============ External functions ============\\n\\n /**\\n * @notice Mints the given amount of LPToken to the recipient.\\n * @dev only owner can call this mint function\\n * @param recipient address of account to receive the tokens\\n * @param amount amount of tokens to mint\\n */\\n function mint(address recipient, uint256 amount) external onlyOwner {\\n require(amount != 0, \\\"LPToken: cannot mint 0\\\");\\n if (totalSupply() == 0) {\\n // NOTE: using the _mint function directly will error because it is going\\n // to the 0 address. fix by using the address(1) here instead\\n _mint(address(1), MINIMUM_LIQUIDITY);\\n }\\n _mint(recipient, amount);\\n }\\n\\n /**\\n * @notice Burns the given amount of LPToken from provided account\\n * @dev only owner can call this burn function\\n * @param account address of account from which to burn token\\n * @param amount amount of tokens to mint\\n */\\n function burnFrom(address account, uint256 amount) external onlyOwner {\\n require(amount != 0, \\\"LPToken: cannot burn 0\\\");\\n _burn(account, amount);\\n }\\n\\n // ============ Internal functions ============\\n\\n /**\\n * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\\n * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\\n * This assumes the owner is set to a Swap contract's address.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20Upgradeable) {\\n super._beforeTokenTransfer(from, to, amount);\\n require(to != address(this), \\\"LPToken: cannot send to itself\\\");\\n }\\n}\\n\",\"keccak256\":\"0x1d3f871488111c70a6f9b09ad3baeb21ebc635c82aa2c6d627d07e09720e4126\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport {ExecuteArgs, TransferInfo, TokenId, DestinationTransferStatus} from \\\"../libraries/LibConnextStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {SwapUtils} from \\\"../libraries/SwapUtils.sol\\\";\\n\\nimport {IStableSwap} from \\\"./IStableSwap.sol\\\";\\n\\nimport {IDiamondCut} from \\\"./IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\ninterface IConnext is IDiamondLoupe, IDiamondCut {\\n // TokenFacet\\n function canonicalToAdopted(bytes32 _key) external view returns (address);\\n\\n function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\\n\\n function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\\n\\n function canonicalToRepresentation(bytes32 _key) external view returns (address);\\n\\n function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\\n\\n function representationToCanonical(address _adopted) external view returns (TokenId memory);\\n\\n function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\\n\\n function approvedAssets(bytes32 _key) external view returns (bool);\\n\\n function approvedAssets(TokenId calldata _canonical) external view returns (bool);\\n\\n function adoptedToLocalPools(bytes32 _key) external view returns (IStableSwap);\\n\\n function adoptedToLocalPools(TokenId calldata _canonical) external view returns (IStableSwap);\\n\\n function getTokenId(address _candidate) external view returns (TokenId memory);\\n\\n function setupAsset(\\n TokenId calldata _canonical,\\n uint8 _canonicalDecimals,\\n string memory _representationName,\\n string memory _representationSymbol,\\n address _adoptedAssetId,\\n address _stableSwapPool,\\n uint256 _cap\\n ) external returns (address);\\n\\n function setupAssetWithDeployedRepresentation(\\n TokenId calldata _canonical,\\n address _representation,\\n address _adoptedAssetId,\\n address _stableSwapPool,\\n uint256 _cap\\n ) external returns (address);\\n\\n function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\\n\\n function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\\n\\n function removeAssetId(\\n bytes32 _key,\\n address _adoptedAssetId,\\n address _representation\\n ) external;\\n\\n function removeAssetId(\\n TokenId calldata _canonical,\\n address _adoptedAssetId,\\n address _representation\\n ) external;\\n\\n function updateDetails(\\n TokenId calldata _canonical,\\n string memory _name,\\n string memory _symbol\\n ) external;\\n\\n // BaseConnextFacet\\n\\n // BridgeFacet\\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\\n\\n function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\\n\\n function remote(uint32 _domain) external view returns (address);\\n\\n function domain() external view returns (uint256);\\n\\n function nonce() external view returns (uint256);\\n\\n function approvedSequencers(address _sequencer) external view returns (bool);\\n\\n function xAppConnectionManager() external view returns (address);\\n\\n function addConnextion(uint32 _domain, address _connext) external;\\n\\n function addSequencer(address _sequencer) external;\\n\\n function removeSequencer(address _sequencer) external;\\n\\n function xcall(\\n uint32 _destination,\\n address _to,\\n address _asset,\\n address _delegate,\\n uint256 _amount,\\n uint256 _slippage,\\n bytes calldata _callData\\n ) external payable returns (bytes32);\\n\\n function xcallIntoLocal(\\n uint32 _destination,\\n address _to,\\n address _asset,\\n address _delegate,\\n uint256 _amount,\\n uint256 _slippage,\\n bytes calldata _callData\\n ) external payable returns (bytes32);\\n\\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\\n\\n function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\\n\\n function bumpTransfer(bytes32 _transferId) external payable;\\n\\n function setXAppConnectionManager(address _xAppConnectionManager) external;\\n\\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\\n\\n function enrollCustom(\\n uint32 _domain,\\n bytes32 _id,\\n address _custom\\n ) external;\\n\\n // InboxFacet\\n\\n function handle(\\n uint32 _origin,\\n uint32 _nonce,\\n bytes32 _sender,\\n bytes memory _message\\n ) external;\\n\\n // ProposedOwnableFacet\\n\\n function owner() external view returns (address);\\n\\n function routerWhitelistRemoved() external view returns (bool);\\n\\n function assetWhitelistRemoved() external view returns (bool);\\n\\n function proposed() external view returns (address);\\n\\n function proposedTimestamp() external view returns (uint256);\\n\\n function routerWhitelistTimestamp() external view returns (uint256);\\n\\n function assetWhitelistTimestamp() external view returns (uint256);\\n\\n function delay() external view returns (uint256);\\n\\n function proposeRouterWhitelistRemoval() external;\\n\\n function removeRouterWhitelist() external;\\n\\n function proposeAssetWhitelistRemoval() external;\\n\\n function removeAssetWhitelist() external;\\n\\n function renounced() external view returns (bool);\\n\\n function proposeNewOwner(address newlyProposed) external;\\n\\n function renounceOwnership() external;\\n\\n function acceptProposedOwner() external;\\n\\n function pause() external;\\n\\n function unpause() external;\\n\\n // RelayerFacet\\n function approvedRelayers(address _relayer) external view returns (bool);\\n\\n function relayerFeeVault() external view returns (address);\\n\\n function setRelayerFeeVault(address _relayerFeeVault) external;\\n\\n function addRelayer(address _relayer) external;\\n\\n function removeRelayer(address _relayer) external;\\n\\n // RoutersFacet\\n function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\\n\\n function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\\n\\n function getRouterApproval(address _router) external view returns (bool);\\n\\n function getRouterRecipient(address _router) external view returns (address);\\n\\n function getRouterOwner(address _router) external view returns (address);\\n\\n function getProposedRouterOwner(address _router) external view returns (address);\\n\\n function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\\n\\n function maxRoutersPerTransfer() external view returns (uint256);\\n\\n function routerBalances(address _router, address _asset) external view returns (uint256);\\n\\n function getRouterApprovalForPortal(address _router) external view returns (bool);\\n\\n function setupRouter(\\n address router,\\n address owner,\\n address recipient\\n ) external;\\n\\n function removeRouter(address router) external;\\n\\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\\n\\n function setLiquidityFeeNumerator(uint256 _numerator) external;\\n\\n function approveRouterForPortal(address _router) external;\\n\\n function unapproveRouterForPortal(address _router) external;\\n\\n function setRouterRecipient(address router, address recipient) external;\\n\\n function proposeRouterOwner(address router, address proposed) external;\\n\\n function acceptProposedRouterOwner(address router) external;\\n\\n function addRouterLiquidityFor(\\n uint256 _amount,\\n address _local,\\n address _router\\n ) external payable;\\n\\n function addRouterLiquidity(uint256 _amount, address _local) external payable;\\n\\n function removeRouterLiquidityFor(\\n uint256 _amount,\\n address _local,\\n address payable _to,\\n address _router\\n ) external;\\n\\n function removeRouterLiquidity(\\n uint256 _amount,\\n address _local,\\n address payable _to\\n ) external;\\n\\n // PortalFacet\\n function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\\n\\n function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\\n\\n function aavePool() external view returns (address);\\n\\n function aavePortalFee() external view returns (uint256);\\n\\n function setAavePool(address _aavePool) external;\\n\\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\\n\\n function repayAavePortal(\\n TransferInfo calldata _params,\\n uint256 _backingAmount,\\n uint256 _feeAmount,\\n uint256 _maxIn\\n ) external;\\n\\n function repayAavePortalFor(\\n TransferInfo calldata _params,\\n uint256 _backingAmount,\\n uint256 _feeAmount\\n ) external;\\n\\n // StableSwapFacet\\n function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\\n\\n function getSwapLPToken(bytes32 canonicalId) external view returns (address);\\n\\n function getSwapA(bytes32 canonicalId) external view returns (uint256);\\n\\n function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\\n\\n function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\\n\\n function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\\n\\n function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\\n\\n function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\\n\\n function calculateSwap(\\n bytes32 canonicalId,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx\\n ) external view returns (uint256);\\n\\n function calculateSwapTokenAmount(\\n bytes32 canonicalId,\\n uint256[] calldata amounts,\\n bool deposit\\n ) external view returns (uint256);\\n\\n function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\\n\\n function calculateRemoveSwapLiquidityOneToken(\\n bytes32 canonicalId,\\n uint256 tokenAmount,\\n uint8 tokenIndex\\n ) external view returns (uint256);\\n\\n function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\\n\\n function swap(\\n bytes32 canonicalId,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function swapExact(\\n bytes32 canonicalId,\\n uint256 amountIn,\\n address assetIn,\\n address assetOut,\\n uint256 minAmountOut,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function swapExactOut(\\n bytes32 canonicalId,\\n uint256 amountOut,\\n address assetIn,\\n address assetOut,\\n uint256 maxAmountIn,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function addSwapLiquidity(\\n bytes32 canonicalId,\\n uint256[] calldata amounts,\\n uint256 minToMint,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeSwapLiquidity(\\n bytes32 canonicalId,\\n uint256 amount,\\n uint256[] calldata minAmounts,\\n uint256 deadline\\n ) external returns (uint256[] memory);\\n\\n function removeSwapLiquidityOneToken(\\n bytes32 canonicalId,\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 minAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeSwapLiquidityImbalance(\\n bytes32 canonicalId,\\n uint256[] calldata amounts,\\n uint256 maxBurnAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n // SwapAdminFacet\\n\\n function initializeSwap(\\n bytes32 _canonicalId,\\n IERC20[] memory _pooledTokens,\\n uint8[] memory decimals,\\n string memory lpTokenName,\\n string memory lpTokenSymbol,\\n uint256 _a,\\n uint256 _fee,\\n uint256 _adminFee,\\n address lpTokenTargetAddress\\n ) external;\\n\\n function withdrawSwapAdminFees(bytes32 canonicalId) external;\\n\\n function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\\n\\n function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\\n\\n function rampA(\\n bytes32 canonicalId,\\n uint256 futureA,\\n uint256 futureTime\\n ) external;\\n\\n function stopRampA(bytes32 canonicalId) external;\\n}\\n\",\"keccak256\":\"0xf4e97b6638cb0af7c41f69b151ec5c66e8d1532067674aecd71d8587a376be4a\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function proposeDiamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n /// @notice Propose to add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function rescindDiamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xd75a7bfdb3aeac3acebf8cf999330a0fc7bec65e9a68711bbb58f4554ef087b2\",\"license\":\"MIT\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xe6d71029d0a1846712477ccf17aa2124b82996c77b6e6486a208a68ea421f563\",\"license\":\"MIT\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IStableSwap {\\n /*** EVENTS ***/\\n\\n // events replicated from SwapUtils to make the ABI easier for dumb\\n // clients\\n event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\\n event AddLiquidity(\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\\n event RemoveLiquidityOne(\\n address indexed provider,\\n uint256 lpTokenAmount,\\n uint256 lpTokenSupply,\\n uint256 boughtId,\\n uint256 tokensBought\\n );\\n event RemoveLiquidityImbalance(\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event NewAdminFee(uint256 newAdminFee);\\n event NewSwapFee(uint256 newSwapFee);\\n event NewWithdrawFee(uint256 newWithdrawFee);\\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\\n event StopRampA(uint256 currentA, uint256 time);\\n\\n function swap(\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function swapExact(\\n uint256 amountIn,\\n address assetIn,\\n address assetOut,\\n uint256 minAmountOut,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function swapExactOut(\\n uint256 amountOut,\\n address assetIn,\\n address assetOut,\\n uint256 maxAmountIn,\\n uint256 deadline\\n ) external payable returns (uint256);\\n\\n function getA() external view returns (uint256);\\n\\n function getToken(uint8 index) external view returns (IERC20);\\n\\n function getTokenIndex(address tokenAddress) external view returns (uint8);\\n\\n function getTokenBalance(uint8 index) external view returns (uint256);\\n\\n function getVirtualPrice() external view returns (uint256);\\n\\n // min return calculation functions\\n function calculateSwap(\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx\\n ) external view returns (uint256);\\n\\n function calculateSwapOut(\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy\\n ) external view returns (uint256);\\n\\n function calculateSwapFromAddress(\\n address assetIn,\\n address assetOut,\\n uint256 amountIn\\n ) external view returns (uint256);\\n\\n function calculateSwapOutFromAddress(\\n address assetIn,\\n address assetOut,\\n uint256 amountOut\\n ) external view returns (uint256);\\n\\n function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\\n\\n function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\\n\\n function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\\n external\\n view\\n returns (uint256 availableTokenAmount);\\n\\n // state modifying functions\\n function initialize(\\n IERC20[] memory pooledTokens,\\n uint8[] memory decimals,\\n string memory lpTokenName,\\n string memory lpTokenSymbol,\\n uint256 a,\\n uint256 fee,\\n uint256 adminFee,\\n address lpTokenTargetAddress\\n ) external;\\n\\n function addLiquidity(\\n uint256[] calldata amounts,\\n uint256 minToMint,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeLiquidity(\\n uint256 amount,\\n uint256[] calldata minAmounts,\\n uint256 deadline\\n ) external returns (uint256[] memory);\\n\\n function removeLiquidityOneToken(\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 minAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function removeLiquidityImbalance(\\n uint256[] calldata amounts,\\n uint256 maxBurnAmount,\\n uint256 deadline\\n ) external returns (uint256);\\n}\\n\",\"keccak256\":\"0xfbbb2cad0639658aa781212c69df10718250a6926d94a1a7508fc9927216abe8\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\ninterface IXReceiver {\\n function xReceive(\\n bytes32 _transferId,\\n uint256 _amount,\\n address _asset,\\n address _originSender,\\n uint32 _origin,\\n bytes memory _callData\\n ) external returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x75286f6ac1b1d5d7f4e508a478c0dad3a26d92675dabbf180d0b46d892618a1a\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport {SwapUtils} from \\\"./SwapUtils.sol\\\";\\n\\n/**\\n * @title AmplificationUtils library\\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\\n * This library assumes the struct is fully validated.\\n */\\nlibrary AmplificationUtils {\\n event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\\n event StopRampA(uint256 currentA, uint256 time);\\n\\n // Constant values used in ramping A calculations\\n uint256 public constant A_PRECISION = 100;\\n uint256 public constant MAX_A = 10**6;\\n uint256 private constant MAX_A_CHANGE = 2;\\n uint256 private constant MIN_RAMP_TIME = 14 days;\\n\\n /**\\n * @notice Return A, the amplification coefficient * n * (n - 1)\\n * @dev See the StableSwap paper for details\\n * @param self Swap struct to read from\\n * @return A parameter\\n */\\n function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\\n return _getAPrecise(self) / A_PRECISION;\\n }\\n\\n /**\\n * @notice Return A in its raw precision\\n * @dev See the StableSwap paper for details\\n * @param self Swap struct to read from\\n * @return A parameter in its raw precision form\\n */\\n function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\\n return _getAPrecise(self);\\n }\\n\\n /**\\n * @notice Return A in its raw precision\\n * @dev See the StableSwap paper for details\\n * @param self Swap struct to read from\\n * @return A parameter in its raw precision form\\n */\\n function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\\n uint256 t1 = self.futureATime; // time when ramp is finished\\n uint256 a1 = self.futureA; // final A value when ramp is finished\\n\\n if (block.timestamp < t1) {\\n uint256 t0 = self.initialATime; // time when ramp is started\\n uint256 a0 = self.initialA; // initial A value when ramp is started\\n if (a1 > a0) {\\n // a0 + (a1 - a0) * (block.timestamp - t0) / (t1 - t0)\\n return a0 + ((a1 - a0) * (block.timestamp - t0)) / (t1 - t0);\\n } else {\\n // a0 - (a0 - a1) * (block.timestamp - t0) / (t1 - t0)\\n return a0 - ((a0 - a1) * (block.timestamp - t0)) / (t1 - t0);\\n }\\n } else {\\n return a1;\\n }\\n }\\n\\n /**\\n * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\\n * Checks if the change is too rapid, and commits the new A value only when it falls under\\n * the limit range.\\n * @param self Swap struct to update\\n * @param futureA_ the new A to ramp towards\\n * @param futureTime_ timestamp when the new A should be reached\\n */\\n function rampA(\\n SwapUtils.Swap storage self,\\n uint256 futureA_,\\n uint256 futureTime_\\n ) internal {\\n require(block.timestamp >= self.initialATime + 1 days, \\\"Wait 1 day before starting ramp\\\");\\n require(futureTime_ >= block.timestamp + MIN_RAMP_TIME, \\\"Insufficient ramp time\\\");\\n require(futureA_ != 0 && futureA_ < MAX_A, \\\"futureA_ must be > 0 and < MAX_A\\\");\\n\\n uint256 initialAPrecise = _getAPrecise(self);\\n uint256 futureAPrecise = futureA_ * A_PRECISION;\\n\\n if (futureAPrecise < initialAPrecise) {\\n require(futureAPrecise * MAX_A_CHANGE >= initialAPrecise, \\\"futureA_ is too small\\\");\\n } else {\\n require(futureAPrecise <= initialAPrecise * MAX_A_CHANGE, \\\"futureA_ is too large\\\");\\n }\\n\\n self.initialA = initialAPrecise;\\n self.futureA = futureAPrecise;\\n self.initialATime = block.timestamp;\\n self.futureATime = futureTime_;\\n\\n emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\\n }\\n\\n /**\\n * @notice Stops ramping A immediately. Once this function is called, rampA()\\n * cannot be called for another 24 hours\\n * @param self Swap struct to update\\n */\\n function stopRampA(SwapUtils.Swap storage self) internal {\\n require(self.futureATime > block.timestamp, \\\"Ramp is already stopped\\\");\\n\\n uint256 currentA = _getAPrecise(self);\\n self.initialA = currentA;\\n self.futureA = currentA;\\n self.initialATime = block.timestamp;\\n self.futureATime = block.timestamp;\\n\\n emit StopRampA(currentA, block.timestamp);\\n }\\n}\\n\",\"keccak256\":\"0x7dca96b10fa307f469c142aaea0855d3c9ba45f79066eaeae1467ce113fc8d28\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {IStableSwap} from \\\"../interfaces/IStableSwap.sol\\\";\\nimport {IConnectorManager} from \\\"../../../messaging/interfaces/IConnectorManager.sol\\\";\\nimport {SwapUtils} from \\\"./SwapUtils.sol\\\";\\n\\n// ============= Enum =============\\n\\n/// @notice Enum representing address role\\n// Returns uint\\n// None - 0\\n// Router - 1\\n// Watcher - 2\\n// Admin - 3\\nenum Role {\\n None,\\n Router,\\n Watcher,\\n Admin\\n}\\n\\n/**\\n * @notice Enum representing status of destination transfer\\n * @dev Status is only assigned on the destination domain, will always be \\\"none\\\" for the\\n * origin domains\\n * @return uint - Index of value in enum\\n */\\nenum DestinationTransferStatus {\\n None, // 0\\n Reconciled, // 1\\n Executed, // 2\\n Completed // 3 - executed + reconciled\\n}\\n\\n// ============= Structs =============\\n\\nstruct TokenId {\\n uint32 domain;\\n bytes32 id;\\n}\\n\\n/**\\n * @notice These are the parameters that will remain constant between the\\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\\n * @property to - The account that receives funds, in the event of a crosschain call,\\n * will receive funds if the call fails.\\n *\\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\\n * @param canonicalDomain - The canonical domain of the asset you are bridging\\n * @param to - The address you are sending funds (and potentially data) to\\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\\n * a user takes 1% slippage, this is expressed as 1_000)\\n * @param originSender - The msg.sender of the xcall\\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\\n */\\nstruct TransferInfo {\\n uint32 originDomain;\\n uint32 destinationDomain;\\n uint32 canonicalDomain;\\n address to;\\n address delegate;\\n bool receiveLocal;\\n bytes callData;\\n uint256 slippage;\\n address originSender;\\n uint256 bridgedAmt;\\n uint256 normalizedIn;\\n uint256 nonce;\\n bytes32 canonicalId;\\n}\\n\\n/**\\n * @notice\\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\\n * @param routers - The routers who you are sending the funds on behalf of.\\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\\n * for the signed transfer ID.\\n * @param sequencer - The sequencer who assigned the router path to this transfer.\\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\\n * for the path that was signed.\\n */\\nstruct ExecuteArgs {\\n TransferInfo params;\\n address[] routers;\\n bytes[] routerSignatures;\\n address sequencer;\\n bytes sequencerSignature;\\n}\\n\\n/**\\n * @notice Contains RouterFacet related state\\n * @param approvedRouters - Mapping of whitelisted router addresses\\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\\n * (if configured) or the router itself\\n * @param routerOwners - Mapping of router owners\\n * If set, can update the routerRecipient\\n * @param proposedRouterOwners - Mapping of proposed router owners\\n * Must wait timeout to set the\\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\\n * When accepting a proposed owner, must wait for delay to elapse\\n */\\nstruct RouterPermissionsManagerInfo {\\n mapping(address => bool) approvedRouters;\\n mapping(address => bool) approvedForPortalRouters;\\n mapping(address => address) routerRecipients;\\n mapping(address => address) routerOwners;\\n mapping(address => address) proposedRouterOwners;\\n mapping(address => uint256) proposedRouterTimestamp;\\n}\\n\\nstruct AppStorage {\\n //\\n // 0\\n bool initialized;\\n //\\n // Connext\\n //\\n // 1\\n uint256 LIQUIDITY_FEE_NUMERATOR;\\n /**\\n * @notice The local address that is custodying relayer fees\\n */\\n // 2\\n address relayerFeeVault;\\n /**\\n * @notice Nonce for the contract, used to keep unique transfer ids.\\n * @dev Assigned at first interaction (xcall on origin domain).\\n */\\n // 3\\n uint256 nonce;\\n /**\\n * @notice The domain this contract exists on.\\n * @dev Must match the nomad domain, which is distinct from the \\\"chainId\\\".\\n */\\n // 4\\n uint32 domain;\\n /**\\n * @notice Mapping holding the AMMs for swapping in and out of local assets.\\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon).\\n * This mapping is keyed on the hash of the canonical id + domain for local asset.\\n */\\n // 6\\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\\n /**\\n * @notice Mapping of whitelisted assets on same domain as contract.\\n * @dev Mapping is keyed on the hash of the canonical id and domain\\n */\\n // 7\\n mapping(bytes32 => bool) approvedAssets;\\n /**\\n * @notice Mapping of liquidity caps of whitelisted assets. If 0, no cap is enforced.\\n * @dev Mapping is keyed on the hash of the canonical id and domain\\n */\\n // 7\\n mapping(bytes32 => uint256) caps;\\n /**\\n * @notice Mapping of adopted to canonical asset information.\\n * @dev If the adopted asset is the native asset, the keyed address will\\n * be the wrapped asset address.\\n */\\n // 8\\n mapping(address => TokenId) adoptedToCanonical;\\n /**\\n * @notice Mapping of representation to canonical asset information.\\n */\\n // 9\\n mapping(address => TokenId) representationToCanonical;\\n /**\\n * @notice Mapping of hash(canonicalId, canonicalDomain) to adopted asset on this domain.\\n * @dev If the adopted asset is the native asset, the stored address will be the\\n * wrapped asset address.\\n */\\n // 10\\n mapping(bytes32 => address) canonicalToAdopted;\\n /**\\n * @notice Mapping of canonical to representation asset information.\\n * @dev If the token is of local origin (meaning it was originanlly deployed on this chain),\\n * this MUST map to address(0).\\n */\\n // 11\\n mapping(bytes32 => address) canonicalToRepresentation;\\n /**\\n * @notice Mapping to track transfer status on destination domain\\n */\\n // 12\\n mapping(bytes32 => DestinationTransferStatus) transferStatus;\\n /**\\n * @notice Mapping holding router address that provided fast liquidity.\\n */\\n // 13\\n mapping(bytes32 => address[]) routedTransfers;\\n /**\\n * @notice Mapping of router to available balance of an asset.\\n * @dev Routers should always store liquidity that they can expect to receive via the bridge on\\n * this domain (the nomad local asset).\\n */\\n // 14\\n mapping(address => mapping(address => uint256)) routerBalances;\\n /**\\n * @notice Mapping of approved relayers\\n * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\\n */\\n // 15\\n mapping(address => bool) approvedRelayers;\\n /**\\n * @notice The max amount of routers a payment can be routed through.\\n */\\n // 18\\n uint256 maxRoutersPerTransfer;\\n /**\\n * @notice Stores a mapping of transfer id to slippage overrides.\\n */\\n // 20\\n mapping(bytes32 => uint256) slippage;\\n /**\\n * @notice Stores a mapping of remote routers keyed on domains.\\n * @dev Addresses are cast to bytes32.\\n * This mapping is required because the Connext now contains the BridgeRouter and must implement\\n * the remotes interface.\\n */\\n // 21\\n mapping(uint32 => bytes32) remotes;\\n //\\n // ProposedOwnable\\n //\\n // 22\\n address _proposed;\\n // 23\\n uint256 _proposedOwnershipTimestamp;\\n // 24\\n bool _routerWhitelistRemoved;\\n // 25\\n uint256 _routerWhitelistTimestamp;\\n // 26\\n bool _assetWhitelistRemoved;\\n // 27\\n uint256 _assetWhitelistTimestamp;\\n /**\\n * @notice Stores a mapping of address to Roles\\n * @dev returns uint representing the enum Role value\\n */\\n // 28\\n mapping(address => Role) roles;\\n //\\n // RouterFacet\\n //\\n // 29\\n RouterPermissionsManagerInfo routerPermissionInfo;\\n //\\n // ReentrancyGuard\\n //\\n // 30\\n uint256 _status;\\n //\\n // StableSwap\\n //\\n /**\\n * @notice Mapping holding the AMM storages for swapping in and out of local assets\\n * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\\n * Struct storing data responsible for automatic market maker functionalities. In order to\\n * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\\n */\\n // 31\\n mapping(bytes32 => SwapUtils.Swap) swapStorages;\\n /**\\n * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\\n * @dev getTokenIndex function also relies on this mapping to retrieve token index.\\n */\\n // 32\\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\\n /**\\n * @notice Stores whether or not bribing, AMMs, have been paused.\\n */\\n // 33\\n bool _paused;\\n //\\n // AavePortals\\n //\\n /**\\n * @notice Address of Aave Pool contract.\\n */\\n // 34\\n address aavePool;\\n /**\\n * @notice Fee percentage numerator for using Portal liquidity.\\n * @dev Assumes the same basis points as the liquidity fee.\\n */\\n // 35\\n uint256 aavePortalFeeNumerator;\\n /**\\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\\n */\\n // 36\\n mapping(bytes32 => uint256) portalDebt;\\n /**\\n * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\\n */\\n // 37\\n mapping(bytes32 => uint256) portalFeeDebt;\\n /**\\n * @notice Mapping of approved sequencers\\n * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\\n * for the fast liquidity route.\\n */\\n // 38\\n mapping(address => bool) approvedSequencers;\\n /**\\n * @notice Remote connection manager for xapp.\\n */\\n // 39\\n IConnectorManager xAppConnectionManager;\\n}\\n\\nlibrary LibConnextStorage {\\n function connextStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n}\\n\",\"keccak256\":\"0x24f998cc9edbb1f3f00c7148d18b7ca0d40eaaac7e3f7fa990ffe89bdee8ec32\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n // hash of proposed facets => acceptance time\\n mapping(bytes32 => uint256) acceptanceTimes;\\n // acceptance delay for upgrading facets\\n uint256 acceptanceDelay;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function acceptanceDelay() internal view returns (uint256) {\\n return diamondStorage().acceptanceDelay;\\n }\\n\\n function acceptanceTime(bytes32 _key) internal view returns (uint256) {\\n return diamondStorage().acceptanceTimes[_key];\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, \\\"LibDiamond: !contract owner\\\");\\n }\\n\\n event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\\n\\n function proposeDiamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 acceptance = block.timestamp + ds.acceptanceDelay;\\n ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\\n emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\\n }\\n\\n event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n function rescindDiamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\\n // period or befor the delay elpases\\n diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = 0;\\n emit DiamondCutRescinded(_diamondCut, _init, _calldata);\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n if (ds.facetAddresses.length != 0) {\\n uint256 time = ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\\n require(time != 0 && time <= block.timestamp, \\\"LibDiamond: delay not elapsed\\\");\\n } // Otherwise, this is the first instance of deployment and it can be set automatically\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length != 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(oldFacetAddress == address(0), \\\"LibDiamondCut: Can't add function that already exists\\\");\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length != 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(oldFacetAddress != _facetAddress, \\\"LibDiamondCut: Can't replace function with same function\\\");\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length != 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), \\\"LibDiamondCut: Remove facet address must be address(0)\\\");\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, \\\"LibDiamondCut: New facet has no code\\\");\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n require(_calldata.length == 0, \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\");\\n } else {\\n require(_calldata.length != 0, \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\");\\n if (_init != address(this)) {\\n enforceHasContractCode(_init, \\\"LibDiamondCut: _init address has no code\\\");\\n }\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length != 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize != 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x0ca55de8a7f4e2256b8b7a5e9ae6cca6d6ff850bbd9fd79542dfc4236871c6d8\",\"license\":\"MIT\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\n/**\\n * @title MathUtils library\\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\\n * differences between two uint256.\\n */\\nlibrary MathUtils {\\n /**\\n * @notice Compares a and b and returns true if the difference between a and b\\n * is less than 1 or equal to each other.\\n * @param a uint256 to compare with\\n * @param b uint256 to compare with\\n * @return True if the difference between a and b is less than 1 or equal,\\n * otherwise return false\\n */\\n function within1(uint256 a, uint256 b) internal pure returns (bool) {\\n return (difference(a, b) <= 1);\\n }\\n\\n /**\\n * @notice Calculates absolute difference between a and b\\n * @param a uint256 to compare with\\n * @param b uint256 to compare with\\n * @return Difference between a and b\\n */\\n function difference(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a > b) {\\n return a - b;\\n }\\n return b - a;\\n }\\n}\\n\",\"keccak256\":\"0xc0e55e78b6b5fec92fbf16f77f10103450f012394d995c8ace507f1abae29371\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.15;\\n\\nimport {SafeERC20, IERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport {LPToken} from \\\"../helpers/LPToken.sol\\\";\\n\\nimport {AmplificationUtils} from \\\"./AmplificationUtils.sol\\\";\\nimport {MathUtils} from \\\"./MathUtils.sol\\\";\\n\\n/**\\n * @title SwapUtils library\\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\\n * Admin functions should be protected within contracts using this library.\\n */\\nlibrary SwapUtils {\\n using SafeERC20 for IERC20;\\n using MathUtils for uint256;\\n\\n /*** EVENTS ***/\\n\\n event TokenSwap(\\n bytes32 indexed key,\\n address indexed buyer,\\n uint256 tokensSold,\\n uint256 tokensBought,\\n uint128 soldId,\\n uint128 boughtId\\n );\\n event AddLiquidity(\\n bytes32 indexed key,\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\\n event RemoveLiquidityOne(\\n bytes32 indexed key,\\n address indexed provider,\\n uint256 lpTokenAmount,\\n uint256 lpTokenSupply,\\n uint256 boughtId,\\n uint256 tokensBought\\n );\\n event RemoveLiquidityImbalance(\\n bytes32 indexed key,\\n address indexed provider,\\n uint256[] tokenAmounts,\\n uint256[] fees,\\n uint256 invariant,\\n uint256 lpTokenSupply\\n );\\n event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\\n event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\\n\\n struct Swap {\\n // variables around the ramp management of A,\\n // the amplification coefficient * n * (n - 1)\\n // see https://www.curve.fi/stableswap-paper.pdf for details\\n bytes32 key;\\n uint256 initialA;\\n uint256 futureA;\\n uint256 initialATime;\\n uint256 futureATime;\\n // fee calculation\\n uint256 swapFee;\\n uint256 adminFee;\\n LPToken lpToken;\\n // contract references for all tokens being pooled\\n IERC20[] pooledTokens;\\n // multipliers for each pooled token's precision to get to POOL_PRECISION_DECIMALS\\n // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\\n // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\\n uint256[] tokenPrecisionMultipliers;\\n // the pool balance of each token, in the token's precision\\n // the contract's actual token balance might differ\\n uint256[] balances;\\n // the admin fee balance of each token, in the token's precision\\n uint256[] adminFees;\\n }\\n\\n // Struct storing variables used in calculations in the\\n // calculateWithdrawOneTokenDY function to avoid stack too deep errors\\n struct CalculateWithdrawOneTokenDYInfo {\\n uint256 d0;\\n uint256 d1;\\n uint256 newY;\\n uint256 feePerToken;\\n uint256 preciseA;\\n }\\n\\n // Struct storing variables used in calculations in the\\n // {add,remove}Liquidity functions to avoid stack too deep errors\\n struct ManageLiquidityInfo {\\n uint256 d0;\\n uint256 d1;\\n uint256 d2;\\n uint256 preciseA;\\n LPToken lpToken;\\n uint256 totalSupply;\\n uint256[] balances;\\n uint256[] multipliers;\\n }\\n\\n // the precision all pools tokens will be converted to\\n uint8 internal constant POOL_PRECISION_DECIMALS = 18;\\n\\n // the denominator used to calculate admin and LP fees. For example, an\\n // LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\\n uint256 internal constant FEE_DENOMINATOR = 1e10;\\n\\n // Max swap fee is 1% or 100bps of each swap\\n uint256 internal constant MAX_SWAP_FEE = 1e8;\\n\\n // Max adminFee is 100% of the swapFee\\n // adminFee does not add additional fee on top of swapFee\\n // Instead it takes a certain % of the swapFee. Therefore it has no impact on the\\n // users but only on the earnings of LPs\\n uint256 internal constant MAX_ADMIN_FEE = 1e10;\\n\\n // Constant value used as max loop limit\\n uint256 internal constant MAX_LOOP_LIMIT = 256;\\n\\n /*** VIEW & PURE FUNCTIONS ***/\\n\\n function _getAPrecise(Swap storage self) private view returns (uint256) {\\n return AmplificationUtils._getAPrecise(self);\\n }\\n\\n /**\\n * @notice Calculate the dy, the amount of selected token that user receives and\\n * the fee of withdrawing in one token\\n * @param tokenAmount the amount to withdraw in the pool's precision\\n * @param tokenIndex which token will be withdrawn\\n * @param self Swap struct to read from\\n * @return the amount of token user will receive\\n */\\n function calculateWithdrawOneToken(\\n Swap storage self,\\n uint256 tokenAmount,\\n uint8 tokenIndex\\n ) internal view returns (uint256) {\\n (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\\n self,\\n tokenAmount,\\n tokenIndex,\\n self.lpToken.totalSupply()\\n );\\n return availableTokenAmount;\\n }\\n\\n function _calculateWithdrawOneToken(\\n Swap storage self,\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 totalSupply\\n ) private view returns (uint256, uint256) {\\n uint256 dy;\\n uint256 newY;\\n uint256 currentY;\\n\\n (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\\n\\n // dy_0 (without fees)\\n // dy, dy_0 - dy\\n\\n uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\\n\\n return (dy, dySwapFee);\\n }\\n\\n /**\\n * @notice Calculate the dy of withdrawing in one token\\n * @param self Swap struct to read from\\n * @param tokenIndex which token will be withdrawn\\n * @param tokenAmount the amount to withdraw in the pools precision\\n * @return the d and the new y after withdrawing one token\\n */\\n function calculateWithdrawOneTokenDY(\\n Swap storage self,\\n uint8 tokenIndex,\\n uint256 tokenAmount,\\n uint256 totalSupply\\n )\\n internal\\n view\\n returns (\\n uint256,\\n uint256,\\n uint256\\n )\\n {\\n // Get the current D, then solve the stableswap invariant\\n // y_i for D - tokenAmount\\n uint256[] memory xp = _xp(self);\\n\\n require(tokenIndex < xp.length, \\\"index out of range\\\");\\n\\n CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\\n v.preciseA = _getAPrecise(self);\\n v.d0 = getD(xp, v.preciseA);\\n v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\\n\\n require(tokenAmount <= xp[tokenIndex], \\\"exceeds available\\\");\\n\\n v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\\n\\n uint256[] memory xpReduced = new uint256[](xp.length);\\n\\n v.feePerToken = _feePerToken(self.swapFee, xp.length);\\n // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\\n for (uint256 i; i < xp.length; ) {\\n uint256 xpi = xp[i];\\n // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\\n // else dxExpected = xp[i] - (xp[i] * d1 / d0)\\n // xpReduced[i] -= dxExpected * fee / FEE_DENOMINATOR\\n xpReduced[i] =\\n xpi -\\n ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\\n FEE_DENOMINATOR);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\\n dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\\n\\n return (dy, v.newY, xp[tokenIndex]);\\n }\\n\\n /**\\n * @notice Calculate the price of a token in the pool with given\\n * precision-adjusted balances and a particular D.\\n *\\n * @dev This is accomplished via solving the invariant iteratively.\\n * See the StableSwap paper and Curve.fi implementation for further details.\\n *\\n * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\\n * x_1**2 + b*x_1 = c\\n * x_1 = (x_1**2 + c) / (2*x_1 + b)\\n *\\n * @param a the amplification coefficient * n * (n - 1). See the StableSwap paper for details.\\n * @param tokenIndex Index of token we are calculating for.\\n * @param xp a precision-adjusted set of pool balances. Array should be\\n * the same cardinality as the pool.\\n * @param d the stableswap invariant\\n * @return the price of the token, in the same precision as in xp\\n */\\n function getYD(\\n uint256 a,\\n uint8 tokenIndex,\\n uint256[] memory xp,\\n uint256 d\\n ) internal pure returns (uint256) {\\n uint256 numTokens = xp.length;\\n require(tokenIndex < numTokens, \\\"Token not found\\\");\\n\\n uint256 c = d;\\n uint256 s;\\n uint256 nA = a * numTokens;\\n\\n for (uint256 i; i < numTokens; ) {\\n if (i != tokenIndex) {\\n s += xp[i];\\n c = (c * d) / (xp[i] * numTokens);\\n // If we were to protect the division loss we would have to keep the denominator separate\\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\\n // c = c * D * D * D * ... overflow!\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\\n\\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\\n uint256 yPrev;\\n uint256 y = d;\\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\\n yPrev = y;\\n y = ((y * y) + c) / ((y * 2) + b - d);\\n if (y.within1(yPrev)) {\\n return y;\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n revert(\\\"Approximation did not converge\\\");\\n }\\n\\n /**\\n * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\\n * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\\n * as the pool.\\n * @param a the amplification coefficient * n * (n - 1) in A_PRECISION.\\n * See the StableSwap paper for details\\n * @return the invariant, at the precision of the pool\\n */\\n function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\\n uint256 numTokens = xp.length;\\n uint256 s;\\n for (uint256 i; i < numTokens; ) {\\n s += xp[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n if (s == 0) {\\n return 0;\\n }\\n\\n uint256 prevD;\\n uint256 d = s;\\n uint256 nA = a * numTokens;\\n\\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\\n uint256 dP = d;\\n for (uint256 j; j < numTokens; ) {\\n dP = (dP * d) / (xp[j] * numTokens);\\n // If we were to protect the division loss we would have to keep the denominator separate\\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\\n // dP = dP * D * D * D * ... overflow!\\n\\n unchecked {\\n ++j;\\n }\\n }\\n prevD = d;\\n d =\\n (((nA * s) / AmplificationUtils.A_PRECISION + dP * numTokens) * d) /\\n ((((nA - AmplificationUtils.A_PRECISION) * d) / AmplificationUtils.A_PRECISION + (numTokens + 1) * dP));\\n if (d.within1(prevD)) {\\n return d;\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\\n // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\\n // function which does not rely on D.\\n revert(\\\"D does not converge\\\");\\n }\\n\\n /**\\n * @notice Given a set of balances and precision multipliers, return the\\n * precision-adjusted balances.\\n *\\n * @param balances an array of token balances, in their native precisions.\\n * These should generally correspond with pooled tokens.\\n *\\n * @param precisionMultipliers an array of multipliers, corresponding to\\n * the amounts in the balances array. When multiplied together they\\n * should yield amounts at the pool's precision.\\n *\\n * @return an array of amounts \\\"scaled\\\" to the pool's precision\\n */\\n function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\\n internal\\n pure\\n returns (uint256[] memory)\\n {\\n uint256 numTokens = balances.length;\\n require(numTokens == precisionMultipliers.length, \\\"mismatch multipliers\\\");\\n uint256[] memory xp = new uint256[](numTokens);\\n for (uint256 i; i < numTokens; ) {\\n xp[i] = balances[i] * precisionMultipliers[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n return xp;\\n }\\n\\n /**\\n * @notice Return the precision-adjusted balances of all tokens in the pool\\n * @param self Swap struct to read from\\n * @return the pool balances \\\"scaled\\\" to the pool's precision, allowing\\n * them to be more easily compared.\\n */\\n function _xp(Swap storage self) internal view returns (uint256[] memory) {\\n return _xp(self.balances, self.tokenPrecisionMultipliers);\\n }\\n\\n /**\\n * @notice Get the virtual price, to help calculate profit\\n * @param self Swap struct to read from\\n * @return the virtual price, scaled to precision of POOL_PRECISION_DECIMALS\\n */\\n function getVirtualPrice(Swap storage self) internal view returns (uint256) {\\n uint256 d = getD(_xp(self), _getAPrecise(self));\\n LPToken lpToken = self.lpToken;\\n uint256 supply = lpToken.totalSupply();\\n if (supply != 0) {\\n return (d * (10**uint256(POOL_PRECISION_DECIMALS))) / supply;\\n }\\n return 0;\\n }\\n\\n /**\\n * @notice Calculate the new balances of the tokens given the indexes of the token\\n * that is swapped from (FROM) and the token that is swapped to (TO).\\n * This function is used as a helper function to calculate how much TO token\\n * the user should receive on swap.\\n *\\n * @param preciseA precise form of amplification coefficient\\n * @param tokenIndexFrom index of FROM token\\n * @param tokenIndexTo index of TO token\\n * @param x the new total amount of FROM token\\n * @param xp balances of the tokens in the pool\\n * @return the amount of TO token that should remain in the pool\\n */\\n function getY(\\n uint256 preciseA,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 x,\\n uint256[] memory xp\\n ) internal pure returns (uint256) {\\n uint256 numTokens = xp.length;\\n require(tokenIndexFrom != tokenIndexTo, \\\"compare token to itself\\\");\\n require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \\\"token not found\\\");\\n\\n uint256 d = getD(xp, preciseA);\\n uint256 c = d;\\n uint256 s;\\n uint256 nA = numTokens * preciseA;\\n\\n uint256 _x;\\n for (uint256 i; i < numTokens; ) {\\n if (i == tokenIndexFrom) {\\n _x = x;\\n } else if (i != tokenIndexTo) {\\n _x = xp[i];\\n } else {\\n unchecked {\\n ++i;\\n }\\n continue;\\n }\\n s += _x;\\n c = (c * d) / (_x * numTokens);\\n // If we were to protect the division loss we would have to keep the denominator separate\\n // and divide at the end. However this leads to overflow with large numTokens or/and D.\\n // c = c * D * D * D * ... overflow!\\n\\n unchecked {\\n ++i;\\n }\\n }\\n c = (c * d * AmplificationUtils.A_PRECISION) / (nA * numTokens);\\n uint256 b = s + ((d * AmplificationUtils.A_PRECISION) / nA);\\n uint256 yPrev;\\n uint256 y = d;\\n\\n // iterative approximation\\n for (uint256 i; i < MAX_LOOP_LIMIT; ) {\\n yPrev = y;\\n y = ((y * y) + c) / ((y * 2) + b - d);\\n if (y.within1(yPrev)) {\\n return y;\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n revert(\\\"Approximation did not converge\\\");\\n }\\n\\n /**\\n * @notice Externally calculates a swap between two tokens.\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @return dy the number of tokens the user will get\\n */\\n function calculateSwap(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx\\n ) internal view returns (uint256 dy) {\\n (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\\n }\\n\\n /**\\n * @notice Externally calculates a swap between two tokens.\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dy the number of tokens to buy.\\n * @return dx the number of tokens the user have to transfer + fee\\n */\\n function calculateSwapInv(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy\\n ) internal view returns (uint256 dx) {\\n (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\\n }\\n\\n /**\\n * @notice Internally calculates a swap between two tokens.\\n *\\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\\n * using the token contracts.\\n *\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dx the number of tokens to sell. If the token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\\n * @return dyFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\\n */\\n function _calculateSwap(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256[] memory balances\\n ) internal view returns (uint256 dy, uint256 dyFee) {\\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\\n uint256[] memory xp = _xp(balances, multipliers);\\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \\\"index out of range\\\");\\n uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\\n uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\\n dy = xp[tokenIndexTo] - y - 1;\\n dyFee = (dy * self.swapFee) / FEE_DENOMINATOR;\\n dy = (dy - dyFee) / multipliers[tokenIndexTo];\\n }\\n\\n /**\\n * @notice Internally calculates a swap between two tokens.\\n *\\n * @dev The caller is expected to transfer the actual amounts (dx and dy)\\n * using the token contracts.\\n *\\n * @param self Swap struct to read from\\n * @param tokenIndexFrom the token to sell\\n * @param tokenIndexTo the token to buy\\n * @param dy the number of tokens to buy. If the token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\\n * @return dxFee the associated fee in multiplied precision (POOL_PRECISION_DECIMALS)\\n */\\n function _calculateSwapInv(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy,\\n uint256[] memory balances\\n ) internal view returns (uint256 dx, uint256 dxFee) {\\n require(tokenIndexFrom != tokenIndexTo, \\\"compare token to itself\\\");\\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\\n uint256[] memory xp = _xp(balances, multipliers);\\n require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \\\"index out of range\\\");\\n\\n uint256 a = _getAPrecise(self);\\n uint256 d0 = getD(xp, a);\\n\\n xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\\n uint256 x = getYD(a, tokenIndexFrom, xp, d0);\\n dx = x - xp[tokenIndexFrom] + 1;\\n dxFee = (dx * self.swapFee) / FEE_DENOMINATOR;\\n dx = (dx + dxFee) / multipliers[tokenIndexFrom];\\n }\\n\\n /**\\n * @notice A simple method to calculate amount of each underlying\\n * tokens that is returned upon burning given amount of\\n * LP tokens\\n *\\n * @param amount the amount of LP tokens that would to be burned on\\n * withdrawal\\n * @return array of amounts of tokens user will receive\\n */\\n function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\\n return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\\n }\\n\\n function _calculateRemoveLiquidity(\\n uint256[] memory balances,\\n uint256 amount,\\n uint256 totalSupply\\n ) internal pure returns (uint256[] memory) {\\n require(amount <= totalSupply, \\\"exceed total supply\\\");\\n\\n uint256 numBalances = balances.length;\\n uint256[] memory amounts = new uint256[](numBalances);\\n\\n for (uint256 i; i < numBalances; ) {\\n amounts[i] = (balances[i] * amount) / totalSupply;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n return amounts;\\n }\\n\\n /**\\n * @notice A simple method to calculate prices from deposits or\\n * withdrawals, excluding fees but including slippage. This is\\n * helpful as an input into the various \\\"min\\\" parameters on calls\\n * to fight front-running\\n *\\n * @dev This shouldn't be used outside frontends for user estimates.\\n *\\n * @param self Swap struct to read from\\n * @param amounts an array of token amounts to deposit or withdrawal,\\n * corresponding to pooledTokens. The amount should be in each\\n * pooled token's native precision. If a token charges a fee on transfers,\\n * use the amount that gets transferred after the fee.\\n * @param deposit whether this is a deposit or a withdrawal\\n * @return if deposit was true, total amount of lp token that will be minted and if\\n * deposit was false, total amount of lp token that will be burned\\n */\\n function calculateTokenAmount(\\n Swap storage self,\\n uint256[] calldata amounts,\\n bool deposit\\n ) internal view returns (uint256) {\\n uint256 a = _getAPrecise(self);\\n uint256[] memory balances = self.balances;\\n uint256[] memory multipliers = self.tokenPrecisionMultipliers;\\n\\n uint256 numBalances = balances.length;\\n uint256 d0 = getD(_xp(balances, multipliers), a);\\n for (uint256 i; i < numBalances; ) {\\n if (deposit) {\\n balances[i] = balances[i] + amounts[i];\\n } else {\\n balances[i] = balances[i] - amounts[i];\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n uint256 d1 = getD(_xp(balances, multipliers), a);\\n uint256 totalSupply = self.lpToken.totalSupply();\\n\\n if (deposit) {\\n return ((d1 - d0) * totalSupply) / d0;\\n } else {\\n return ((d0 - d1) * totalSupply) / d0;\\n }\\n }\\n\\n /**\\n * @notice return accumulated amount of admin fees of the token with given index\\n * @param self Swap struct to read from\\n * @param index Index of the pooled token\\n * @return admin balance in the token's precision\\n */\\n function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\\n require(index < self.pooledTokens.length, \\\"index out of range\\\");\\n return self.adminFees[index];\\n }\\n\\n /**\\n * @notice internal helper function to calculate fee per token multiplier used in\\n * swap fee calculations\\n * @param swapFee swap fee for the tokens\\n * @param numTokens number of tokens pooled\\n */\\n function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\\n return (swapFee * numTokens) / ((numTokens - 1) * 4);\\n }\\n\\n /*** STATE MODIFYING FUNCTIONS ***/\\n\\n /**\\n * @notice swap two tokens in the pool\\n * @param self Swap struct to read from and write to\\n * @param tokenIndexFrom the token the user wants to sell\\n * @param tokenIndexTo the token the user wants to buy\\n * @param dx the amount of tokens the user wants to sell\\n * @param minDy the min amount the user would like to receive, or revert.\\n * @return amount of token user received on swap\\n */\\n function swap(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy\\n ) internal returns (uint256) {\\n {\\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\\n require(dx <= tokenFrom.balanceOf(msg.sender), \\\"swap more than you own\\\");\\n // Transfer tokens first to see if a fee was charged on transfer\\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\\n\\n // Use the actual transferred amount for AMM math\\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \\\"no fee token support\\\");\\n }\\n\\n uint256 dy;\\n uint256 dyFee;\\n uint256[] memory balances = self.balances;\\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\\n require(dy >= minDy, \\\"dy < minDy\\\");\\n\\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\\n if (dyAdminFee != 0) {\\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\\n }\\n\\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dy;\\n }\\n\\n /**\\n * @notice swap two tokens in the pool\\n * @param self Swap struct to read from and write to\\n * @param tokenIndexFrom the token the user wants to sell\\n * @param tokenIndexTo the token the user wants to buy\\n * @param dy the amount of tokens the user wants to buy\\n * @param maxDx the max amount the user would like to send.\\n * @return amount of token user have to transfer on swap\\n */\\n function swapOut(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy,\\n uint256 maxDx\\n ) internal returns (uint256) {\\n require(dy <= self.balances[tokenIndexTo], \\\">pool balance\\\");\\n\\n uint256 dx;\\n uint256 dxFee;\\n uint256[] memory balances = self.balances;\\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\\n require(dx <= maxDx, \\\"dx > maxDx\\\");\\n\\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\\n if (dxAdminFee != 0) {\\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\\n }\\n\\n {\\n IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\\n require(dx <= tokenFrom.balanceOf(msg.sender), \\\"more than you own\\\");\\n // Transfer tokens first to see if a fee was charged on transfer\\n uint256 beforeBalance = tokenFrom.balanceOf(address(this));\\n tokenFrom.safeTransferFrom(msg.sender, address(this), dx);\\n\\n // Use the actual transferred amount for AMM math\\n require(dx == tokenFrom.balanceOf(address(this)) - beforeBalance, \\\"not support fee token\\\");\\n }\\n\\n self.pooledTokens[tokenIndexTo].safeTransfer(msg.sender, dy);\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dx;\\n }\\n\\n /**\\n * @notice swap two tokens in the pool internally\\n * @param self Swap struct to read from and write to\\n * @param tokenIndexFrom the token the user wants to sell\\n * @param tokenIndexTo the token the user wants to buy\\n * @param dx the amount of tokens the user wants to sell\\n * @param minDy the min amount the user would like to receive, or revert.\\n * @return amount of token user received on swap\\n */\\n function swapInternal(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dx,\\n uint256 minDy\\n ) internal returns (uint256) {\\n require(dx <= self.balances[tokenIndexFrom], \\\"more than pool balance\\\");\\n\\n uint256 dy;\\n uint256 dyFee;\\n uint256[] memory balances = self.balances;\\n (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\\n require(dy >= minDy, \\\"dy < minDy\\\");\\n\\n uint256 dyAdminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexTo];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\\n\\n if (dyAdminFee != 0) {\\n self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\\n }\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dy;\\n }\\n\\n /**\\n * @notice Should get exact amount out of AMM for asset put in\\n */\\n function swapInternalOut(\\n Swap storage self,\\n uint8 tokenIndexFrom,\\n uint8 tokenIndexTo,\\n uint256 dy,\\n uint256 maxDx\\n ) internal returns (uint256) {\\n require(dy <= self.balances[tokenIndexTo], \\\"more than pool balance\\\");\\n\\n uint256 dx;\\n uint256 dxFee;\\n uint256[] memory balances = self.balances;\\n (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\\n require(dx <= maxDx, \\\"dx > maxDx\\\");\\n\\n uint256 dxAdminFee = (dxFee * self.adminFee) / FEE_DENOMINATOR / self.tokenPrecisionMultipliers[tokenIndexFrom];\\n\\n self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\\n self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\\n\\n if (dxAdminFee != 0) {\\n self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\\n }\\n\\n emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\\n\\n return dx;\\n }\\n\\n /**\\n * @notice Add liquidity to the pool\\n * @param self Swap struct to read from and write to\\n * @param amounts the amounts of each token to add, in their native precision\\n * @param minToMint the minimum LP tokens adding this amount of liquidity\\n * should mint, otherwise revert. Handy for front-running mitigation\\n * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\\n * @return amount of LP token user received\\n */\\n function addLiquidity(\\n Swap storage self,\\n uint256[] memory amounts,\\n uint256 minToMint\\n ) internal returns (uint256) {\\n uint256 numTokens = self.pooledTokens.length;\\n require(amounts.length == numTokens, \\\"mismatch pooled tokens\\\");\\n\\n // current state\\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\\n 0,\\n 0,\\n 0,\\n _getAPrecise(self),\\n self.lpToken,\\n 0,\\n self.balances,\\n self.tokenPrecisionMultipliers\\n );\\n v.totalSupply = v.lpToken.totalSupply();\\n if (v.totalSupply != 0) {\\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\\n }\\n\\n uint256[] memory newBalances = new uint256[](numTokens);\\n\\n for (uint256 i; i < numTokens; ) {\\n require(v.totalSupply != 0 || amounts[i] != 0, \\\"!supply all tokens\\\");\\n\\n // Transfer tokens first to see if a fee was charged on transfer\\n if (amounts[i] != 0) {\\n IERC20 token = self.pooledTokens[i];\\n uint256 beforeBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), amounts[i]);\\n\\n // Update the amounts[] with actual transfer amount\\n amounts[i] = token.balanceOf(address(this)) - beforeBalance;\\n }\\n\\n newBalances[i] = v.balances[i] + amounts[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // invariant after change\\n v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\\n require(v.d1 > v.d0, \\\"D should increase\\\");\\n\\n // updated to reflect fees and calculate the user's LP tokens\\n v.d2 = v.d1;\\n uint256[] memory fees = new uint256[](numTokens);\\n\\n if (v.totalSupply != 0) {\\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\\n for (uint256 i; i < numTokens; ) {\\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\\n fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / FEE_DENOMINATOR;\\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\\n self.balances[i] = newBalances[i] - adminFee;\\n self.adminFees[i] = self.adminFees[i] + adminFee;\\n newBalances[i] = newBalances[i] - fees[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\\n } else {\\n // the initial depositor doesn't pay fees\\n self.balances = newBalances;\\n }\\n\\n uint256 toMint;\\n if (v.totalSupply == 0) {\\n toMint = v.d1;\\n } else {\\n toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\\n }\\n\\n require(toMint >= minToMint, \\\"mint < min\\\");\\n\\n // mint the user's LP tokens\\n v.lpToken.mint(msg.sender, toMint);\\n\\n emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\\n\\n return toMint;\\n }\\n\\n /**\\n * @notice Burn LP tokens to remove liquidity from the pool.\\n * @dev Liquidity can always be removed, even when the pool is paused.\\n * @param self Swap struct to read from and write to\\n * @param amount the amount of LP tokens to burn\\n * @param minAmounts the minimum amounts of each token in the pool\\n * acceptable for this burn. Useful as a front-running mitigation\\n * @return amounts of tokens the user received\\n */\\n function removeLiquidity(\\n Swap storage self,\\n uint256 amount,\\n uint256[] calldata minAmounts\\n ) internal returns (uint256[] memory) {\\n LPToken lpToken = self.lpToken;\\n require(amount <= lpToken.balanceOf(msg.sender), \\\">LP.balanceOf\\\");\\n uint256 numTokens = self.pooledTokens.length;\\n require(minAmounts.length == numTokens, \\\"mismatch poolTokens\\\");\\n\\n uint256[] memory balances = self.balances;\\n uint256 totalSupply = lpToken.totalSupply();\\n\\n uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\\n\\n uint256 numAmounts = amounts.length;\\n for (uint256 i; i < numAmounts; ) {\\n require(amounts[i] >= minAmounts[i], \\\"amounts[i] < minAmounts[i]\\\");\\n self.balances[i] = balances[i] - amounts[i];\\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n lpToken.burnFrom(msg.sender, amount);\\n\\n emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\\n\\n return amounts;\\n }\\n\\n /**\\n * @notice Remove liquidity from the pool all in one token.\\n * @param self Swap struct to read from and write to\\n * @param tokenAmount the amount of the lp tokens to burn\\n * @param tokenIndex the index of the token you want to receive\\n * @param minAmount the minimum amount to withdraw, otherwise revert\\n * @return amount chosen token that user received\\n */\\n function removeLiquidityOneToken(\\n Swap storage self,\\n uint256 tokenAmount,\\n uint8 tokenIndex,\\n uint256 minAmount\\n ) internal returns (uint256) {\\n LPToken lpToken = self.lpToken;\\n\\n require(tokenAmount <= lpToken.balanceOf(msg.sender), \\\">LP.balanceOf\\\");\\n uint256 numTokens = self.pooledTokens.length;\\n require(tokenIndex < numTokens, \\\"not found\\\");\\n\\n uint256 totalSupply = lpToken.totalSupply();\\n\\n (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\\n\\n require(dy >= minAmount, \\\"dy < minAmount\\\");\\n\\n uint256 adminFee = (dyFee * self.adminFee) / FEE_DENOMINATOR;\\n self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\\n if (adminFee != 0) {\\n self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\\n }\\n lpToken.burnFrom(msg.sender, tokenAmount);\\n self.pooledTokens[tokenIndex].safeTransfer(msg.sender, dy);\\n\\n emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\\n\\n return dy;\\n }\\n\\n /**\\n * @notice Remove liquidity from the pool, weighted differently than the\\n * pool's current balances.\\n *\\n * @param self Swap struct to read from and write to\\n * @param amounts how much of each token to withdraw\\n * @param maxBurnAmount the max LP token provider is willing to pay to\\n * remove liquidity. Useful as a front-running mitigation.\\n * @return actual amount of LP tokens burned in the withdrawal\\n */\\n function removeLiquidityImbalance(\\n Swap storage self,\\n uint256[] memory amounts,\\n uint256 maxBurnAmount\\n ) internal returns (uint256) {\\n ManageLiquidityInfo memory v = ManageLiquidityInfo(\\n 0,\\n 0,\\n 0,\\n _getAPrecise(self),\\n self.lpToken,\\n 0,\\n self.balances,\\n self.tokenPrecisionMultipliers\\n );\\n v.totalSupply = v.lpToken.totalSupply();\\n\\n uint256 numTokens = self.pooledTokens.length;\\n uint256 numAmounts = amounts.length;\\n require(numAmounts == numTokens, \\\"mismatch pool tokens\\\");\\n\\n require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \\\">LP.balanceOf\\\");\\n\\n uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\\n uint256[] memory fees = new uint256[](numTokens);\\n {\\n uint256[] memory balances1 = new uint256[](numTokens);\\n v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\\n for (uint256 i; i < numTokens; ) {\\n require(v.balances[i] >= amounts[i], \\\"withdraw more than available\\\");\\n\\n unchecked {\\n balances1[i] = v.balances[i] - amounts[i];\\n ++i;\\n }\\n }\\n v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\\n\\n for (uint256 i; i < numTokens; ) {\\n {\\n uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\\n uint256 difference = idealBalance.difference(balances1[i]);\\n fees[i] = (feePerToken * difference) / FEE_DENOMINATOR;\\n }\\n uint256 adminFee = (fees[i] * self.adminFee) / FEE_DENOMINATOR;\\n self.balances[i] = balances1[i] - adminFee;\\n self.adminFees[i] = self.adminFees[i] + adminFee;\\n balances1[i] = balances1[i] - fees[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\\n }\\n uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\\n require(tokenAmount != 0, \\\"!zero amount\\\");\\n tokenAmount = tokenAmount + 1;\\n\\n require(tokenAmount <= maxBurnAmount, \\\"tokenAmount > maxBurnAmount\\\");\\n\\n v.lpToken.burnFrom(msg.sender, tokenAmount);\\n\\n for (uint256 i; i < numTokens; ) {\\n self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\\n\\n return tokenAmount;\\n }\\n\\n /**\\n * @notice withdraw all admin fees to a given address\\n * @param self Swap struct to withdraw fees from\\n * @param to Address to send the fees to\\n */\\n function withdrawAdminFees(Swap storage self, address to) internal {\\n uint256 numTokens = self.pooledTokens.length;\\n for (uint256 i; i < numTokens; ) {\\n IERC20 token = self.pooledTokens[i];\\n uint256 balance = self.adminFees[i];\\n if (balance != 0) {\\n self.adminFees[i] = 0;\\n token.safeTransfer(to, balance);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Sets the admin fee\\n * @dev adminFee cannot be higher than 100% of the swap fee\\n * @param self Swap struct to update\\n * @param newAdminFee new admin fee to be applied on future transactions\\n */\\n function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\\n require(newAdminFee <= MAX_ADMIN_FEE, \\\"too high\\\");\\n self.adminFee = newAdminFee;\\n\\n emit NewAdminFee(self.key, newAdminFee);\\n }\\n\\n /**\\n * @notice update the swap fee\\n * @dev fee cannot be higher than 1% of each swap\\n * @param self Swap struct to update\\n * @param newSwapFee new swap fee to be applied on future transactions\\n */\\n function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\\n require(newSwapFee <= MAX_SWAP_FEE, \\\"too high\\\");\\n self.swapFee = newSwapFee;\\n\\n emit NewSwapFee(self.key, newSwapFee);\\n }\\n\\n /**\\n * @notice Check if this stableswap pool exists and is valid (i.e. has been\\n * initialized and tokens have been added).\\n * @return bool true if this stableswap pool is valid, false if not.\\n */\\n function exists(Swap storage self) internal view returns (bool) {\\n return self.pooledTokens.length != 0;\\n }\\n}\\n\",\"keccak256\":\"0x3da6aa3cd7cf97886db9958cbb174b8edaf7771aebce5da2a8d87e993a8301fa\",\"license\":\"UNLICENSED\"},\"@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport {IOutbox} from \\\"./IOutbox.sol\\\";\\n\\n/**\\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\\n * allows an admin to call `setXAppConnectionManager` to update the underlying\\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\\n *\\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\\n * will interface with.\\n */\\ninterface IConnectorManager {\\n /**\\n * @notice Get the local inbox contract from the xAppConnectionManager\\n * @return The local inbox contract\\n * @dev The local inbox contract is a SpokeConnector with AMBs, and a\\n * Home contract with nomad\\n */\\n function home() external view returns (IOutbox);\\n\\n /**\\n * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\\n * @return True if _potentialReplica is an enrolled Replica\\n */\\n function isReplica(address _potentialReplica) external view returns (bool);\\n\\n /**\\n * @notice Get the local domain from the xAppConnectionManager\\n * @return The local domain\\n */\\n function localDomain() external view returns (uint32);\\n}\\n\",\"keccak256\":\"0xa2c9a88a7b76a89615fe199d8a78878e5deb8dd13b036a86b575d31966beab1a\",\"license\":\"MIT OR Apache-2.0\"},\"@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity 0.8.15;\\n\\n/**\\n * @notice Interface for all contracts sending messages originating on their\\n * current domain.\\n *\\n * @dev These are the Home.sol interface methods used by the `Router`\\n * and exposed via `home()` on the `XAppConnectionClient`\\n */\\ninterface IOutbox {\\n /**\\n * @notice Emitted when a new message is added to an outbound message merkle root\\n * @param leafIndex Index of message's leaf in merkle tree\\n * @param destinationAndNonce Destination and destination-specific\\n * nonce combined in single field ((destination << 32) & nonce)\\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\\n * @param committedRoot the latest notarized root submitted in the last signed Update\\n * @param message Raw bytes of message\\n */\\n event Dispatch(\\n bytes32 indexed messageHash,\\n uint256 indexed leafIndex,\\n uint64 indexed destinationAndNonce,\\n bytes32 committedRoot,\\n bytes message\\n );\\n\\n /**\\n * @notice Dispatch the message it to the destination domain & recipient\\n * @dev Format the message, insert its hash into Merkle tree,\\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\\n * @param _destinationDomain Domain of destination chain\\n * @param _recipientAddress Address of recipient on destination chain as bytes32\\n * @param _messageBody Raw bytes content of message\\n * @return bytes32 The leaf added to the tree\\n */\\n function dispatch(\\n uint32 _destinationDomain,\\n bytes32 _recipientAddress,\\n bytes memory _messageBody\\n ) external returns (bytes32);\\n}\\n\",\"keccak256\":\"0xe6a213bd3c9e0c4dcf0e982cdef2a6a613a49b7bca3d6ad662c179e509de6c2b\",\"license\":\"MIT OR Apache-2.0\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.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 IERC20Upgradeable {\\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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\\n function __ERC20Burnable_init() internal onlyInitializing {\\n }\\n\\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xea2c6f9d434127bf36b1e3e5ebaaf6d28a64dbaeea560508e570014e905a5ad2\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\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\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 > 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 >= 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 functionCall(target, data, \\\"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(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) 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(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) 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 >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // Look for revert reason and bubble it up if present\\n if (returndata.length > 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}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/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\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= 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 > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 > 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 >= 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 functionCall(target, data, \\\"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(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) 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(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) 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 >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // Look for revert reason and bubble it up if present\\n if (returndata.length > 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}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"solidity/contracts/bridges/BridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IBridgeReceiverAdapter.sol';\\n\\nabstract contract BridgeReceiverAdapter is IBridgeReceiverAdapter {\\n /// @inheritdoc IBridgeReceiverAdapter\\n IDataReceiver public immutable dataReceiver;\\n\\n constructor(IDataReceiver _dataReceiver) {\\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\\n dataReceiver = _dataReceiver;\\n }\\n\\n function _addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) internal {\\n dataReceiver.addObservations(_observationsData, _poolSalt, _poolNonce);\\n }\\n}\\n\",\"keccak256\":\"0x9242c7b33b40003d937f4facdc0aeb0e121ad4574c1191fe0d543eec0c3552b0\",\"license\":\"MIT\"},\"solidity/contracts/bridges/ConnextReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {BridgeReceiverAdapter} from './BridgeReceiverAdapter.sol';\\nimport {IConnext, IXReceiver, IConnextReceiverAdapter, IDataReceiver, IOracleSidechain} from '../../interfaces/bridges/IConnextReceiverAdapter.sol';\\n\\ncontract ConnextReceiverAdapter is IConnextReceiverAdapter, BridgeReceiverAdapter {\\n /// @inheritdoc IConnextReceiverAdapter\\n IConnext public immutable connext;\\n\\n /// @inheritdoc IConnextReceiverAdapter\\n address public immutable source;\\n\\n /// @inheritdoc IConnextReceiverAdapter\\n uint32 public immutable originDomain;\\n\\n constructor(\\n IDataReceiver _dataReceiver,\\n IConnext _connext,\\n address _source,\\n uint32 _originDomain\\n ) BridgeReceiverAdapter(_dataReceiver) {\\n if (address(_connext) == address(0) || _source == address(0)) revert ZeroAddress();\\n connext = _connext;\\n source = _source;\\n originDomain = _originDomain;\\n }\\n\\n /// @inheritdoc IXReceiver\\n function xReceive(\\n bytes32, // _transferId\\n uint256, // _amount\\n address, // _asset\\n address _originSender,\\n uint32 _origin,\\n bytes memory _callData\\n ) external onlyExecutor(_originSender, _origin) returns (bytes memory) {\\n (IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, uint24 _poolNonce) = abi.decode(\\n _callData,\\n (IOracleSidechain.ObservationData[], bytes32, uint24)\\n );\\n\\n _addObservations(_observationsData, _poolSalt, _poolNonce);\\n }\\n\\n modifier onlyExecutor(address _originSender, uint32 _originDomain) {\\n if (msg.sender != address(connext) || _originSender != source || _originDomain != originDomain) revert UnauthorizedCaller();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x7895c6ee2da8eca15d2960a39bec9a7c0093bd33d094f0e0c751e96231951968\",\"license\":\"MIT\"},\"solidity/interfaces/IDataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleFactory} from './IOracleFactory.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\\n\\ninterface IDataReceiver is IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @notice Tracks already deployed oracles\\n /// @param _poolSalt The identifier of the oracle\\n /// @return _deployedOracle The address of the correspondant Oracle\\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\\n\\n /// @notice Tracks the whitelisting of bridge adapters\\n /// @param _adapter Address of the bridge adapter to consult\\n /// @return _isAllowed Whether a bridge adapter is whitelisted\\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a broadcast observation is succesfully processed\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsAdded(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a broadcast observation is cached for later processing\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsCached(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a new adapter whitelisting rule is set\\n /// @param _adapter Address of the adapter\\n /// @param _isAllowed New whitelisting status\\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\\n\\n // ERRORS\\n\\n /// @notice Thrown when the broadcast nonce is incorrect\\n error ObservationsNotWritable();\\n\\n /// @notice Thrown when a not-whitelisted adapter triggers an update\\n error UnallowedAdapter();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows whitelisted bridge adapters to push a broadcast\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _poolNonce Nonce of the observation broadcast\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external;\\n\\n /// @notice Allows any address to attempt to insert cached observations\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _maxObservations Maximum number of observations to process\\n /// @dev Use _maxObservations = 0 to process all possible cached observations\\n function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external;\\n\\n /// @notice Allows governance to set an adapter whitelisted state\\n /// @param _receiverAdapter Address of the adapter\\n /// @param _isWhitelisted New whitelisting status\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\\n\\n /// @notice Allows governance to batch set adapters whitelisted state\\n /// @param _receiverAdapters Array of addresses of the adapter\\n /// @param _isWhitelisted Array of whitelisting status for each address\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\\n}\\n\",\"keccak256\":\"0xd07e75380d5086ea78909bc5c80aadc110903004f50c006b0281cc090f273291\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IDataReceiver} from './IDataReceiver.sol';\\n\\ninterface IOracleFactory is IGovernable {\\n // STRUCTS\\n\\n struct OracleParameters {\\n bytes32 poolSalt; // Identifier of the pool and oracle\\n uint24 poolNonce; // Initial nonce of the deployed pool\\n uint16 cardinality; // Initial cardinality of the deployed pool\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\\n //solhint-disable-next-line func-name-mixedcase\\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\\n\\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /// @return _poolSalt The id of both the oracle and the pool\\n /// @return _poolNonce The initial nonce of the pool data\\n /// @return _cardinality The size of the observations memory storage\\n function oracleParameters()\\n external\\n view\\n returns (\\n bytes32 _poolSalt,\\n uint24 _poolNonce,\\n uint16 _cardinality\\n );\\n\\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function initialCardinality() external view returns (uint16 _initialCardinality);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new oracle is deployed\\n /// @param _poolSalt The id of both the oracle and the pool\\n /// @param _oracle The address of the deployed oracle\\n /// @param _initialNonce The initial nonce of the pool data\\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\\n\\n /// @notice Emitted when a new DataReceiver is set\\n /// @param _dataReceiver The address of the new DataReceiver\\n event DataReceiverSet(IDataReceiver _dataReceiver);\\n\\n /// @notice Emitted when a new initial oracle cardinality is set\\n /// @param _initialCardinality The initial length of the observationCardinality array\\n event InitialCardinalitySet(uint16 _initialCardinality);\\n\\n // ERRORS\\n\\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\\n error OnlyDataReceiver();\\n\\n // FUNCTIONS\\n\\n /// @notice Deploys a new oracle given an inputted salt\\n /// @dev Requires that the salt has not been deployed before\\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\\n /// @return _oracle The address of the newly deployed oracle\\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\\n\\n /// @notice Allows governor to set a new allowed dataReceiver\\n /// @dev Will disallow the previous dataReceiver\\n /// @param _dataReceiver The address of the new allowed dataReceiver\\n function setDataReceiver(IDataReceiver _dataReceiver) external;\\n\\n /// @notice Allows governor to set a new initial cardinality for new oracles\\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function setInitialCardinality(uint16 _initialCardinality) external;\\n\\n /// @notice Overrides UniV3Factory getPool mapping\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _oracle The oracle address\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle);\\n\\n /// @notice Tracks the addresses of the oracle by poolSalt\\n /// @param _poolSalt Identifier of both the pool and the oracle\\n /// @return _oracle The address (if deployed) of the correspondant oracle\\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\\n\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _poolSalt Pool salt for inquired parameters\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (bytes32 _poolSalt);\\n}\\n\",\"keccak256\":\"0xc32bfc32a274923ce1a089acc024396e702ae354773f0ac0a683e43ded904954\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleFactory} from './IOracleFactory.sol';\\n\\ninterface IOracleSidechain {\\n // STRUCTS\\n\\n struct ObservationData {\\n uint32 blockTimestamp;\\n int24 tick;\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function factory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @return _token0 The mainnet address of the Token0 of the oracle\\n function token0() external view returns (address _token0);\\n\\n /// @return _token1 The mainnet address of the Token1 of the oracle\\n function token1() external view returns (address _token1);\\n\\n /// @return _fee The fee identifier of the pool\\n function fee() external view returns (uint24 _fee);\\n\\n /// @return _poolSalt The identifier of both the pool and the oracle\\n function poolSalt() external view returns (bytes32 _poolSalt);\\n\\n /// @return _poolNonce Last recorded nonce of the pool history\\n function poolNonce() external view returns (uint24 _poolNonce);\\n\\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\\n /// @return _tick Used to maintain compatibility with Uniswap V3\\n /// @return _observationIndex The index of the last oracle observation that was written,\\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\\n /// @return _unlocked Used to track if a pool information was already verified\\n function slot0()\\n external\\n view\\n returns (\\n uint160 _sqrtPriceX96,\\n int24 _tick,\\n uint16 _observationIndex,\\n uint16 _observationCardinality,\\n uint16 _observationCardinalityNext,\\n uint8 _feeProtocol,\\n bool _unlocked\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param _index The element of the observations array to fetch\\n /// @return _blockTimestamp The timestamp of the observation,\\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// @return _initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 _index)\\n external\\n view\\n returns (\\n uint32 _blockTimestamp,\\n int56 _tickCumulative,\\n uint160 _secondsPerLiquidityCumulativeX128,\\n bool _initialized\\n );\\n\\n // EVENTS\\n\\n /// @notice Emitted when the pool information is verified\\n /// @param _poolSalt Identifier of the pool and the oracle\\n /// @param _token0 The contract address of either token0 or token1\\n /// @param _token1 The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\\n\\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param _tick The log base 1.0001 of price of the pool after the swap\\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\\n\\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\\n\\n // ERRORS\\n\\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\\n error AI();\\n\\n /// @notice Thrown if the pool info does not correspond to the pool salt\\n error InvalidPool();\\n\\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\\n error OnlyDataReceiver();\\n\\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\\n error OnlyFactory();\\n\\n // FUNCTIONS\\n\\n /// @notice Permisionless method to verify token0, token1 and fee\\n /// @dev Before verified, token0 and token1 views will return address(0)\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external;\\n\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\\n\\n /// @notice Permisioned method to push a dataset to update\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolNonce Nonce of the observation broadcast\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\\n\\n /// @notice Permisioned method to increase the cardinalityNext value\\n /// @param _observationCardinalityNext The new next length of the observations array\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa90206e3de00ad866b7f4792ce29220ee0ca561d59629ba638a31c4d6fd3941b\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IBridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport {IDataReceiver} from '../IDataReceiver.sol';\\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\\n\\ninterface IBridgeReceiverAdapter is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @notice Gets the address of the DataReceiver contract\\n /// @return _dataReceiver Address of the DataReceiver contract\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /* NOTE: callback methods should be here declared */\\n}\\n\",\"keccak256\":\"0x49e5c9c6a28521933a3f2b01a529fbae9aac1edd71dbe904586a2f06148b1974\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IConnextReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IConnext} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol';\\nimport {IXReceiver} from '@connext/nxtp-contracts/contracts/core/connext/interfaces/IXReceiver.sol';\\nimport {IBridgeReceiverAdapter, IDataReceiver, IOracleSidechain} from './IBridgeReceiverAdapter.sol';\\n\\ninterface IConnextReceiverAdapter is IXReceiver, IBridgeReceiverAdapter {\\n // STATE VARIABLES\\n\\n /// @notice Gets the ConnextHandler contract on this domain\\n /// @return _connext Address of the ConnextHandler contract\\n function connext() external view returns (IConnext _connext);\\n\\n /// @notice Gets the DAO that is expected as the xcaller\\n /// @return _originContract Address of the xcaller contract\\n function source() external view returns (address _originContract);\\n\\n /// @notice Gets the origin domain id\\n /// @return _originDomain The origin domain id\\n function originDomain() external view returns (uint32 _originDomain);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a caller is not authorized\\n error UnauthorizedCaller();\\n}\\n\",\"keccak256\":\"0x382097cdc88bb383c1aec1ec6ebddf9e6ba5b87b405650432e85616acd03e218\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b506040516107e33803806107e3833981016040819052610030916100d3565b836001600160a01b0381166100585760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b039081166080528316158061007b57506001600160a01b038216155b156100995760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0392831660a052911660c05263ffffffff1660e0525061013b565b6001600160a01b03811681146100d057600080fd5b50565b600080600080608085870312156100e957600080fd5b84516100f4816100bb565b6020860151909450610105816100bb565b6040860151909350610116816100bb565b606086015190925063ffffffff8116811461013057600080fd5b939692955090935050565b60805160a05160c05160e05161065661018d6000396000818160a501526101c00152600081816061015261018301526000818160e10152610159015260008181610108015261025d01526106566000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806367e828bf1461005c578063cee85d7e146100a0578063de4b0548146100dc578063e804778814610103578063fd614f411461012a575b600080fd5b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c77f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610097565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b61013d61013836600461036e565b61014a565b6040516100979190610449565b60608383336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806101b857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b806101ef57507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1614155b1561020d57604051635c427cd960e01b815260040160405180910390fd5b60008060008680602001905181019061022691906104b1565b925092509250610237838383610246565b50505050509695505050505050565b60405163d34ad40960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d34ad40990610296908690869086906004016105b5565b600060405180830381600087803b1580156102b057600080fd5b505af11580156102c4573d6000803e3d6000fd5b50505050505050565b80356001600160a01b03811681146102e457600080fd5b919050565b63ffffffff811681146102fb57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610337576103376102fe565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610366576103666102fe565b604052919050565b60008060008060008060c0878903121561038757600080fd5b86359550602080880135955061039f604089016102cd565b94506103ad606089016102cd565b935060808801356103bd816102e9565b925060a088013567ffffffffffffffff808211156103da57600080fd5b818a0191508a601f8301126103ee57600080fd5b813581811115610400576104006102fe565b610412601f8201601f1916850161033d565b91508082528b8482850101111561042857600080fd5b80848401858401376000848284010152508093505050509295509295509295565b600060208083528351808285015260005b818110156104765785810183015185820160400152820161045a565b81811115610488576000604083870101525b50601f01601f1916929092016040019392505050565b805162ffffff811681146102e457600080fd5b6000806000606084860312156104c657600080fd5b835167ffffffffffffffff808211156104de57600080fd5b818601915086601f8301126104f257600080fd5b8151602082821115610506576105066102fe565b610514818360051b0161033d565b828152818101935060069290921b84018101918983111561053457600080fd5b938101935b82851015610592576040858b0312156105525760008081fd5b61055a610314565b8551610565816102e9565b815285830151600281900b811461057c5760008081fd5b8184015284526040949094019392810192610539565b80975050808801519550505050506105ac6040850161049e565b90509250925092565b606080825284519082018190526000906020906080840190828801845b82811015610602578151805163ffffffff16855285015160020b85850152604090930192908401906001016105d2565b505050908301949094525062ffffff9190911660409091015291905056fea26469706673582212202c12c0bf792175159d5e1c1f0caa4f166cc61f5519e6f66b2bb8f2fa8cad462564736f6c634300080f0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c806367e828bf1461005c578063cee85d7e146100a0578063de4b0548146100dc578063e804778814610103578063fd614f411461012a575b600080fd5b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c77f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610097565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b6100837f000000000000000000000000000000000000000000000000000000000000000081565b61013d61013836600461036e565b61014a565b6040516100979190610449565b60608383336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806101b857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b806101ef57507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1614155b1561020d57604051635c427cd960e01b815260040160405180910390fd5b60008060008680602001905181019061022691906104b1565b925092509250610237838383610246565b50505050509695505050505050565b60405163d34ad40960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d34ad40990610296908690869086906004016105b5565b600060405180830381600087803b1580156102b057600080fd5b505af11580156102c4573d6000803e3d6000fd5b50505050505050565b80356001600160a01b03811681146102e457600080fd5b919050565b63ffffffff811681146102fb57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610337576103376102fe565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610366576103666102fe565b604052919050565b60008060008060008060c0878903121561038757600080fd5b86359550602080880135955061039f604089016102cd565b94506103ad606089016102cd565b935060808801356103bd816102e9565b925060a088013567ffffffffffffffff808211156103da57600080fd5b818a0191508a601f8301126103ee57600080fd5b813581811115610400576104006102fe565b610412601f8201601f1916850161033d565b91508082528b8482850101111561042857600080fd5b80848401858401376000848284010152508093505050509295509295509295565b600060208083528351808285015260005b818110156104765785810183015185820160400152820161045a565b81811115610488576000604083870101525b50601f01601f1916929092016040019392505050565b805162ffffff811681146102e457600080fd5b6000806000606084860312156104c657600080fd5b835167ffffffffffffffff808211156104de57600080fd5b818601915086601f8301126104f257600080fd5b8151602082821115610506576105066102fe565b610514818360051b0161033d565b828152818101935060069290921b84018101918983111561053457600080fd5b938101935b82851015610592576040858b0312156105525760008081fd5b61055a610314565b8551610565816102e9565b815285830151600281900b811461057c5760008081fd5b8184015284526040949094019392810192610539565b80975050808801519550505050506105ac6040850161049e565b90509250925092565b606080825284519082018190526000906020906080840190828801845b82811015610602578151805163ffffffff16855285015160020b85850152604090930192908401906001016105d2565b505050908301949094525062ffffff9190911660409091015291905056fea26469706673582212202c12c0bf792175159d5e1c1f0caa4f166cc61f5519e6f66b2bb8f2fa8cad462564736f6c634300080f0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "stateVariables": { + "connext": { + "return": "Address of the ConnextHandler contract", + "returns": { + "_0": "Address of the ConnextHandler contract" + } + }, + "originDomain": { + "return": "The origin domain id", + "returns": { + "_0": "The origin domain id" + } + }, + "source": { + "return": "Address of the xcaller contract", + "returns": { + "_0": "Address of the xcaller contract" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidAddress()": [ + { + "notice": "Thrown if an address is invalid" + } + ], + "InvalidAmount()": [ + { + "notice": "Thrown if an amount is invalid" + } + ], + "LengthMismatch()": [ + { + "notice": "Thrown if the lengths of a set of lists mismatch" + } + ], + "UnauthorizedCaller()": [ + { + "notice": "Thrown if a caller is not authorized" + } + ], + "ZeroAddress()": [ + { + "notice": "Thrown if an address is the zero address" + } + ], + "ZeroAmount()": [ + { + "notice": "Thrown if an amount is zero" + } + ] + }, + "kind": "user", + "methods": { + "connext()": { + "notice": "Gets the ConnextHandler contract on this domain" + }, + "dataReceiver()": { + "notice": "Gets the address of the DataReceiver contract" + }, + "originDomain()": { + "notice": "Gets the origin domain id" + }, + "source()": { + "notice": "Gets the DAO that is expected as the xcaller" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/DataReceiver.json b/deployments/polygon/DataReceiver.json new file mode 100644 index 0000000..bcb420e --- /dev/null +++ b/deployments/polygon/DataReceiver.json @@ -0,0 +1,696 @@ +{ + "address": "0xe5BE7f12B94D185f892c4BBe6F88ABE65CE1A8af", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "internalType": "contract IOracleFactory", + "name": "_oracleFactory", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "LengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "ObservationsNotWritable", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "UnallowedAdapter", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IBridgeReceiverAdapter", + "name": "_adapter", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_isAllowed", + "type": "bool" + } + ], + "name": "AdapterWhitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint24", + "name": "_poolNonce", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "address", + "name": "_receiverAdapter", + "type": "address" + } + ], + "name": "ObservationsAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint24", + "name": "_poolNonce", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "address", + "name": "_receiverAdapter", + "type": "address" + } + ], + "name": "ObservationsCached", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newGovernor", + "type": "address" + } + ], + "name": "PendingGovernorAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "PendingGovernorSet", + "type": "event" + }, + { + "inputs": [], + "name": "acceptPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "internalType": "struct IOracleSidechain.ObservationData[]", + "name": "_observationsData", + "type": "tuple[]" + }, + { + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + }, + { + "internalType": "uint24", + "name": "_poolNonce", + "type": "uint24" + } + ], + "name": "addObservations", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "deployedOracles", + "outputs": [ + { + "internalType": "contract IOracleSidechain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracleFactory", + "outputs": [ + { + "internalType": "contract IOracleFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingGovernor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "setPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_maxObservations", + "type": "uint256" + } + ], + "name": "syncObservations", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBridgeReceiverAdapter", + "name": "_receiverAdapter", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isWhitelisted", + "type": "bool" + } + ], + "name": "whitelistAdapter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBridgeReceiverAdapter[]", + "name": "_receiverAdapters", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "_isWhitelisted", + "type": "bool[]" + } + ], + "name": "whitelistAdapters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBridgeReceiverAdapter", + "name": "", + "type": "address" + } + ], + "name": "whitelistedAdapters", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xb8ed4faeb1f2fbe54a217608ccd9a72b40fbff317a58992eda9025595d19a325", + "receipt": { + "to": null, + "from": "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "contractAddress": "0xe5BE7f12B94D185f892c4BBe6F88ABE65CE1A8af", + "transactionIndex": 63, + "gasUsed": "1025842", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000008000000000000000000000000000800000000000000000000000000000800000000000000004000100000000000100000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000040001000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x4efecbd7ae5d35e536a88e4848a47aefafee6ac757f15cf52ccd36ec9e7db003", + "transactionHash": "0xb8ed4faeb1f2fbe54a217608ccd9a72b40fbff317a58992eda9025595d19a325", + "logs": [ + { + "transactionIndex": 63, + "blockNumber": 60867655, + "transactionHash": "0xb8ed4faeb1f2fbe54a217608ccd9a72b40fbff317a58992eda9025595d19a325", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000a6dbff53dd8f89f0bf4f6800bfdffe099875bd9d", + "0x000000000000000000000000b95d435df3f8b2a8d8b9c2b7c8766c9ae6ed8cc9" + ], + "data": "0x000000000000000000000000000000000000000000000000006f8f79745f46040000000000000000000000000000000000000000000000004ba533103ddf4bb1000000000000000000000000000000000000000000000022f64db69ba8b4dcb30000000000000000000000000000000000000000000000004b35a396c98005ad000000000000000000000000000000000000000000000022f6bd46151d1422b7", + "logIndex": 236, + "blockHash": "0x4efecbd7ae5d35e536a88e4848a47aefafee6ac757f15cf52ccd36ec9e7db003" + } + ], + "blockNumber": 60867655, + "cumulativeGasUsed": "14959288", + "status": 1, + "byzantium": true + }, + "args": [ + "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "0x69ceAA797274fd85F3b3a1f5b29857BFD9B9b259" + ], + "numDeployments": 1, + "solcInputHash": "1ffcc3895a1a8980b9e58deee89219d1", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract IOracleFactory\",\"name\":\"_oracleFactory\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ObservationsNotWritable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnallowedAdapter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IBridgeReceiverAdapter\",\"name\":\"_adapter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isAllowed\",\"type\":\"bool\"}],\"name\":\"AdapterWhitelisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"_poolNonce\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_receiverAdapter\",\"type\":\"address\"}],\"name\":\"ObservationsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"_poolNonce\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_receiverAdapter\",\"type\":\"address\"}],\"name\":\"ObservationsCached\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockTimestamp\",\"type\":\"uint32\"},{\"internalType\":\"int24\",\"name\":\"tick\",\"type\":\"int24\"}],\"internalType\":\"struct IOracleSidechain.ObservationData[]\",\"name\":\"_observationsData\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"_poolNonce\",\"type\":\"uint24\"}],\"name\":\"addObservations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deployedOracles\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleFactory\",\"outputs\":[{\"internalType\":\"contract IOracleFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"setPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_maxObservations\",\"type\":\"uint256\"}],\"name\":\"syncObservations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBridgeReceiverAdapter\",\"name\":\"_receiverAdapter\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_isWhitelisted\",\"type\":\"bool\"}],\"name\":\"whitelistAdapter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBridgeReceiverAdapter[]\",\"name\":\"_receiverAdapters\",\"type\":\"address[]\"},{\"internalType\":\"bool[]\",\"name\":\"_isWhitelisted\",\"type\":\"bool[]\"}],\"name\":\"whitelistAdapters\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBridgeReceiverAdapter\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"whitelistedAdapters\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addObservations((uint32,int24)[],bytes32,uint24)\":{\"params\":{\"_observationsData\":\"Array of tuples containing the dataset\",\"_poolNonce\":\"Nonce of the observation broadcast\",\"_poolSalt\":\"Identifier of the pool to fetch\"}},\"setPendingGovernor(address)\":{\"params\":{\"_pendingGovernor\":\"Address of the proposed new governor\"}},\"syncObservations(bytes32,uint256)\":{\"details\":\"Use _maxObservations = 0 to process all possible cached observations\",\"params\":{\"_maxObservations\":\"Maximum number of observations to process\",\"_poolSalt\":\"Identifier of the pool to fetch\"}},\"whitelistAdapter(address,bool)\":{\"params\":{\"_isWhitelisted\":\"New whitelisting status\",\"_receiverAdapter\":\"Address of the adapter\"}},\"whitelistAdapters(address[],bool[])\":{\"params\":{\"_isWhitelisted\":\"Array of whitelisting status for each address\",\"_receiverAdapters\":\"Array of addresses of the adapter\"}}},\"stateVariables\":{\"deployedOracles\":{\"params\":{\"_poolSalt\":\"The identifier of the oracle\"},\"return\":\"The address of the correspondant Oracle\",\"returns\":{\"_0\":\"The address of the correspondant Oracle\"}},\"oracleFactory\":{\"return\":\"The address of the OracleFactory\",\"returns\":{\"_0\":\"The address of the OracleFactory\"}},\"whitelistedAdapters\":{\"params\":{\"_adapter\":\"Address of the bridge adapter to consult\"},\"return\":\"Whether a bridge adapter is whitelisted\",\"returns\":{\"_0\":\"Whether a bridge adapter is whitelisted\"}}},\"title\":\"The DataReceiver contract\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"ObservationsNotWritable()\":[{\"notice\":\"Thrown when the broadcast nonce is incorrect\"}],\"OnlyGovernor()\":[{\"notice\":\"Thrown if a non-governor user tries to call a OnlyGovernor function\"}],\"OnlyPendingGovernor()\":[{\"notice\":\"Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\"}],\"UnallowedAdapter()\":[{\"notice\":\"Thrown when a not-whitelisted adapter triggers an update\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"events\":{\"AdapterWhitelisted(address,bool)\":{\"notice\":\"Emitted when a new adapter whitelisting rule is set\"},\"ObservationsAdded(bytes32,uint24,address)\":{\"notice\":\"Emitted when a broadcast observation is succesfully processed\"},\"ObservationsCached(bytes32,uint24,address)\":{\"notice\":\"Emitted when a broadcast observation is cached for later processing\"},\"PendingGovernorAccepted(address)\":{\"notice\":\"Emitted when a new governor is set\"},\"PendingGovernorSet(address,address)\":{\"notice\":\"Emitted when a new pending governor is set\"}},\"kind\":\"user\",\"methods\":{\"acceptPendingGovernor()\":{\"notice\":\"Allows a proposed governor to accept the governance\"},\"addObservations((uint32,int24)[],bytes32,uint24)\":{\"notice\":\"Allows whitelisted bridge adapters to push a broadcast\"},\"deployedOracles(bytes32)\":{\"notice\":\"Tracks already deployed oracles\"},\"setPendingGovernor(address)\":{\"notice\":\"Allows a governor to propose a new governor\"},\"syncObservations(bytes32,uint256)\":{\"notice\":\"Allows any address to attempt to insert cached observations\"},\"whitelistAdapter(address,bool)\":{\"notice\":\"Allows governance to set an adapter whitelisted state\"},\"whitelistAdapters(address[],bool[])\":{\"notice\":\"Allows governance to batch set adapters whitelisted state\"},\"whitelistedAdapters(address)\":{\"notice\":\"Tracks the whitelisting of bridge adapters\"}},\"notice\":\"Handles reception of broadcast data and delivers it to correspondant oracle\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/DataReceiver.sol\":\"DataReceiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '../interfaces/IGovernable.sol';\\n\\n/// @title Governable contract\\n/// @notice Manages the governor role\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public governor;\\n\\n /// @inheritdoc IGovernable\\n address public pendingGovernor;\\n\\n constructor(address _governor) {\\n if (_governor == address(0)) revert ZeroAddress();\\n governor = _governor;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\\n _setPendingGovernor(_pendingGovernor);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptPendingGovernor() external onlyPendingGovernor {\\n _acceptPendingGovernor();\\n }\\n\\n function _setPendingGovernor(address _pendingGovernor) internal {\\n if (_pendingGovernor == address(0)) revert ZeroAddress();\\n pendingGovernor = _pendingGovernor;\\n emit PendingGovernorSet(governor, _pendingGovernor);\\n }\\n\\n function _acceptPendingGovernor() internal {\\n governor = pendingGovernor;\\n delete pendingGovernor;\\n emit PendingGovernorAccepted(governor);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governor\\n modifier onlyGovernor() {\\n if (msg.sender != governor) revert OnlyGovernor();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernor\\n modifier onlyPendingGovernor() {\\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x3f11408cfcb015a99dc417e075c8ebc39b796fc2adc3e81b036487e4486881b3\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@uniswap/v3-core/contracts/libraries/Oracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.0;\\n\\n/// @title Oracle\\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\\n/// @dev Instances of stored oracle data, \\\"observations\\\", are collected in the oracle array\\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\\n/// Observations are overwritten when the full length of the oracle array is populated.\\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\\nlibrary Oracle {\\n error I();\\n error OLD();\\n\\n struct Observation {\\n // the block timestamp of the observation\\n uint32 blockTimestamp;\\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\\n int56 tickCumulative;\\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\\n uint160 secondsPerLiquidityCumulativeX128;\\n // whether or not the observation is initialized\\n bool initialized;\\n }\\n\\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\\n /// @param last The specified observation to be transformed\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @return Observation The newly populated observation\\n function transform(\\n Observation memory last,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity\\n ) private pure returns (Observation memory) {\\n unchecked {\\n uint32 delta = blockTimestamp - last.blockTimestamp;\\n return\\n Observation({\\n blockTimestamp: blockTimestamp,\\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\\n initialized: true\\n });\\n }\\n }\\n\\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\\n /// @param self The stored oracle array\\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\\n /// @return cardinality The number of populated elements in the oracle array\\n /// @return cardinalityNext The new length of the oracle array, independent of population\\n function initialize(Observation[65535] storage self, uint32 time)\\n internal\\n returns (uint16 cardinality, uint16 cardinalityNext)\\n {\\n self[0] = Observation({\\n blockTimestamp: time,\\n tickCumulative: 0,\\n secondsPerLiquidityCumulativeX128: 0,\\n initialized: true\\n });\\n return (1, 1);\\n }\\n\\n /// @notice Writes an oracle observation to the array\\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\\n /// @param self The stored oracle array\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @param cardinalityNext The new length of the oracle array, independent of population\\n /// @return indexUpdated The new index of the most recently written element in the oracle array\\n /// @return cardinalityUpdated The new cardinality of the oracle array\\n function write(\\n Observation[65535] storage self,\\n uint16 index,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity,\\n uint16 cardinality,\\n uint16 cardinalityNext\\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\\n unchecked {\\n Observation memory last = self[index];\\n\\n // early return if we've already written an observation this block\\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\\n\\n // if the conditions are right, we can bump the cardinality\\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\\n cardinalityUpdated = cardinalityNext;\\n } else {\\n cardinalityUpdated = cardinality;\\n }\\n\\n indexUpdated = (index + 1) % cardinalityUpdated;\\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\\n }\\n }\\n\\n /// @notice Prepares the oracle array to store up to `next` observations\\n /// @param self The stored oracle array\\n /// @param current The current next cardinality of the oracle array\\n /// @param next The proposed next cardinality which will be populated in the oracle array\\n /// @return next The next cardinality which will be populated in the oracle array\\n function grow(\\n Observation[65535] storage self,\\n uint16 current,\\n uint16 next\\n ) internal returns (uint16) {\\n unchecked {\\n if (current <= 0) revert I();\\n // no-op if the passed next value isn't greater than the current next value\\n if (next <= current) return current;\\n // store in each slot to prevent fresh SSTOREs in swaps\\n // this data will not be used because the initialized boolean is still false\\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\\n return next;\\n }\\n }\\n\\n /// @notice comparator for 32-bit timestamps\\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\\n /// @param time A timestamp truncated to 32 bits\\n /// @param a A comparison timestamp from which to determine the relative position of `time`\\n /// @param b From which to determine the relative position of `time`\\n /// @return Whether `a` is chronologically <= `b`\\n function lte(\\n uint32 time,\\n uint32 a,\\n uint32 b\\n ) private pure returns (bool) {\\n unchecked {\\n // if there hasn't been overflow, no need to adjust\\n if (a <= time && b <= time) return a <= b;\\n\\n uint256 aAdjusted = a > time ? a : a + 2**32;\\n uint256 bAdjusted = b > time ? b : b + 2**32;\\n\\n return aAdjusted <= bAdjusted;\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\\n /// The result may be the same observation, or adjacent observations.\\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation recorded before, or at, the target\\n /// @return atOrAfter The observation recorded at, or after, the target\\n function binarySearch(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n uint16 index,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n uint256 l = (index + 1) % cardinality; // oldest observation\\n uint256 r = l + cardinality - 1; // newest observation\\n uint256 i;\\n while (true) {\\n i = (l + r) / 2;\\n\\n beforeOrAt = self[i % cardinality];\\n\\n // we've landed on an uninitialized tick, keep searching higher (more recently)\\n if (!beforeOrAt.initialized) {\\n l = i + 1;\\n continue;\\n }\\n\\n atOrAfter = self[(i + 1) % cardinality];\\n\\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\\n\\n // check if we've found the answer!\\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\\n\\n if (!targetAtOrAfter) r = i - 1;\\n else l = i + 1;\\n }\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\\n /// @dev Assumes there is at least 1 initialized observation.\\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param tick The active tick at the time of the returned or simulated observation\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The total pool liquidity at the time of the call\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\\n function getSurroundingObservations(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n // optimistically set before to the newest observation\\n beforeOrAt = self[index];\\n\\n // if the target is chronologically at or after the newest observation, we can early return\\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\\n if (beforeOrAt.blockTimestamp == target) {\\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\\n return (beforeOrAt, atOrAfter);\\n } else {\\n // otherwise, we need to transform\\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\\n }\\n }\\n\\n // now, set before to the oldest observation\\n beforeOrAt = self[(index + 1) % cardinality];\\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\\n\\n // ensure that the target is chronologically at or after the oldest observation\\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\\n\\n // if we've reached this point, we have to binary search\\n return binarySearch(self, time, target, index, cardinality);\\n }\\n }\\n\\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\\n /// at exactly the timestamp between the two observations.\\n /// @param self The stored oracle array\\n /// @param time The current block timestamp\\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\\n function observeSingle(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 secondsAgo,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\\n unchecked {\\n if (secondsAgo == 0) {\\n Observation memory last = self[index];\\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\\n }\\n\\n uint32 target = time - secondsAgo;\\n\\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\\n self,\\n time,\\n target,\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n\\n if (target == beforeOrAt.blockTimestamp) {\\n // we're at the left boundary\\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\\n } else if (target == atOrAfter.blockTimestamp) {\\n // we're at the right boundary\\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\\n } else {\\n // we're in the middle\\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\\n return (\\n beforeOrAt.tickCumulative +\\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\\n int56(uint56(targetDelta)),\\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\\n uint160(\\n (uint256(\\n atOrAfter.secondsPerLiquidityCumulativeX128 -\\n beforeOrAt.secondsPerLiquidityCumulativeX128\\n ) * targetDelta) / observationTimeDelta\\n )\\n );\\n }\\n }\\n }\\n\\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\\n /// @dev Reverts if `secondsAgos` > oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\\n function observe(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32[] memory secondsAgos,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\\n unchecked {\\n if (cardinality <= 0) revert I();\\n\\n tickCumulatives = new int56[](secondsAgos.length);\\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\\n for (uint256 i = 0; i < secondsAgos.length; i++) {\\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\\n self,\\n time,\\n secondsAgos[i],\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa25b18af947c36b9add9e229c361beb6aba176fb435d7a24e6dc723cbc187442\",\"license\":\"BUSL-1.1\"},\"@uniswap/v3-core/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity ^0.8.0;\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n error T();\\n error R();\\n\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n unchecked {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n if (absTick > uint256(int256(MAX_TICK))) revert T();\\n\\n uint256 ratio = absTick & 0x1 != 0\\n ? 0xfffcb933bd6fad37aa2d162d1a594001\\n : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\\n /// ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n unchecked {\\n // second inequality must be < because the price can never reach the price at the max tick\\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5c57de03a91cc2ec8939865dbbcb0197bb6c353b711075eefd8e0fca5e102129\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/DataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\\nimport {OracleSidechain} from './OracleSidechain.sol';\\nimport {IDataReceiver, IOracleFactory, IOracleSidechain, IBridgeReceiverAdapter} from '../interfaces/IDataReceiver.sol';\\n\\n/// @title The DataReceiver contract\\n/// @notice Handles reception of broadcast data and delivers it to correspondant oracle\\ncontract DataReceiver is IDataReceiver, Governable {\\n /// @inheritdoc IDataReceiver\\n IOracleFactory public immutable oracleFactory;\\n\\n /// @inheritdoc IDataReceiver\\n mapping(bytes32 => IOracleSidechain) public deployedOracles;\\n\\n /// @inheritdoc IDataReceiver\\n mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters;\\n\\n mapping(bytes32 => mapping(uint24 => IOracleSidechain.ObservationData[])) internal _cachedObservations;\\n\\n constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) {\\n if (address(_oracleFactory) == address(0)) revert ZeroAddress();\\n oracleFactory = _oracleFactory;\\n }\\n\\n /// @inheritdoc IDataReceiver\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external onlyWhitelistedAdapters {\\n _addObservations(_observationsData, _poolSalt, _poolNonce);\\n }\\n\\n function _addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) internal {\\n // Read, store or deploy oracle given poolSalt\\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\\n if (address(_oracle) == address(0)) {\\n _oracle = oracleFactory.getPool(_poolSalt);\\n if (address(_oracle) == address(0)) {\\n _oracle = oracleFactory.deployOracle(_poolSalt, _poolNonce);\\n }\\n deployedOracles[_poolSalt] = _oracle;\\n }\\n // Try to write observations data into oracle\\n if (_oracle.write(_observationsData, _poolNonce)) {\\n emit ObservationsAdded(_poolSalt, _poolNonce, msg.sender);\\n } else {\\n // Query pool's current nonce\\n uint24 _currentNonce = _oracle.poolNonce();\\n // Discard old observations (already written in the oracle)\\n // NOTE: if _currentNonce == _poolNonce it shouldn't reach this else block\\n if (_currentNonce > _poolNonce) revert ObservationsNotWritable();\\n\\n IOracleSidechain.ObservationData[] storage _cachedObservationsData = _cachedObservations[_poolSalt][_poolNonce];\\n // Store not-added observations to cachedObservations mapping\\n if (_cachedObservationsData.length == 0) {\\n // NOTE: memory to storage is not supported\\n for (uint256 _i; _i < _observationsData.length; ++_i) {\\n _cachedObservationsData.push(_observationsData[_i]);\\n }\\n emit ObservationsCached(_poolSalt, _poolNonce, msg.sender);\\n }\\n while (_currentNonce <= _poolNonce) {\\n // Try backfilling pending observations (from current to {sent|first empty} nonce)\\n _observationsData = _cachedObservations[_poolSalt][_currentNonce];\\n // If the struct is not empty, write it into the oracle\\n if (_observationsData.length > 0) {\\n // Since observation nonce == oracle nonce, we can safely write the observations\\n _oracle.write(_observationsData, _currentNonce);\\n emit ObservationsAdded(_poolSalt, _currentNonce, msg.sender);\\n // Clear out the written observations\\n delete _cachedObservations[_poolSalt][_currentNonce];\\n _currentNonce++;\\n } else {\\n // When an empty nonce is found, break the loop\\n break;\\n }\\n }\\n }\\n }\\n\\n /// @inheritdoc IDataReceiver\\n function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external {\\n IOracleSidechain _oracle = deployedOracles[_poolSalt];\\n if (address(_oracle) == address(0)) revert ZeroAddress();\\n IOracleSidechain.ObservationData[] memory _cachedObservationsData;\\n uint24 _currentNonce = _oracle.poolNonce();\\n uint256 _i;\\n while (_maxObservations == 0 || _i < _maxObservations) {\\n _cachedObservationsData = _cachedObservations[_poolSalt][_currentNonce];\\n if (_cachedObservationsData.length > 0) {\\n _oracle.write(_cachedObservationsData, _currentNonce);\\n emit ObservationsAdded(_poolSalt, _currentNonce, msg.sender);\\n delete _cachedObservations[_poolSalt][_currentNonce];\\n _currentNonce++;\\n _i++;\\n } else {\\n break;\\n }\\n }\\n if (_i == 0) revert ObservationsNotWritable();\\n }\\n\\n /// @inheritdoc IDataReceiver\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor {\\n _whitelistAdapter(_receiverAdapter, _isWhitelisted);\\n }\\n\\n /// @inheritdoc IDataReceiver\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external onlyGovernor {\\n uint256 _receiverAdapterLength = _receiverAdapters.length;\\n if (_receiverAdapterLength != _isWhitelisted.length) revert LengthMismatch();\\n unchecked {\\n for (uint256 _i; _i < _receiverAdapterLength; ++_i) {\\n _whitelistAdapter(_receiverAdapters[_i], _isWhitelisted[_i]);\\n }\\n }\\n }\\n\\n function _whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) internal {\\n whitelistedAdapters[_receiverAdapter] = _isWhitelisted;\\n emit AdapterWhitelisted(_receiverAdapter, _isWhitelisted);\\n }\\n\\n modifier onlyWhitelistedAdapters() {\\n if (!whitelistedAdapters[IBridgeReceiverAdapter(msg.sender)]) revert UnallowedAdapter();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5dc12e8bff1c84e0edf0dab64a72f71e57a213308b6c578c5210e2e3d1922c43\",\"license\":\"MIT\"},\"solidity/contracts/OracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\\n\\n/// @title The SidechainOracle contract\\n/// @notice Computes and stores on-chain price data from Mainnet\\ncontract OracleSidechain is IOracleSidechain {\\n using Oracle for Oracle.Observation[65535];\\n\\n /// @inheritdoc IOracleSidechain\\n IOracleFactory public immutable factory;\\n\\n struct Slot0 {\\n // the current price\\n uint160 sqrtPriceX96;\\n // the current tick\\n int24 tick;\\n // the most-recently updated index of the observations array\\n uint16 observationIndex;\\n // the current maximum number of observations that are being stored\\n uint16 observationCardinality;\\n // the next maximum number of observations to store, triggered in observations.write\\n uint16 observationCardinalityNext;\\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\\n // represented as an integer denominator (1/x)%\\n uint8 feeProtocol;\\n // whether the pool is locked\\n bool unlocked;\\n }\\n /// @inheritdoc IOracleSidechain\\n Slot0 public slot0;\\n\\n /// @inheritdoc IOracleSidechain\\n Oracle.Observation[65535] public observations;\\n\\n /// @inheritdoc IOracleSidechain\\n bytes32 public immutable poolSalt;\\n\\n uint24 public poolNonce;\\n /// @inheritdoc IOracleSidechain\\n address public token0;\\n /// @inheritdoc IOracleSidechain\\n address public token1;\\n /// @inheritdoc IOracleSidechain\\n uint24 public fee;\\n\\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\\n function _getBlockTimestamp() internal view virtual returns (uint32) {\\n return uint32(block.timestamp); // truncation is desired\\n }\\n\\n constructor() {\\n factory = IOracleFactory(msg.sender);\\n uint16 _cardinality;\\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\\n\\n slot0 = Slot0({\\n sqrtPriceX96: 0,\\n tick: 0,\\n observationIndex: _cardinality - 1,\\n observationCardinality: _cardinality,\\n observationCardinalityNext: _cardinality,\\n feeProtocol: 0,\\n unlocked: true\\n });\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external {\\n if (!slot0.unlocked) revert AI();\\n\\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\\n\\n token0 = _token0;\\n token1 = _token1;\\n fee = _fee;\\n slot0.unlocked = false;\\n\\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\\n {\\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\\n if (_poolNonce != poolNonce) return false;\\n poolNonce++;\\n\\n uint256 _observationsDataLength = _observationsData.length;\\n for (uint256 _i; _i < _observationsDataLength; ) {\\n _write(_observationsData[_i]);\\n unchecked {\\n ++_i;\\n }\\n }\\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\\n\\n // emits UniV3 Swap event topic with minimal data\\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\\n return true;\\n }\\n\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\\n if (_observationCardinalityNext <= _observationCardinalityNextOld) revert AI();\\n slot0.observationCardinalityNext = _observationCardinalityNext;\\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\\n }\\n\\n function _write(ObservationData memory _observationData) private {\\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\\n slot0.observationIndex,\\n _observationData.blockTimestamp,\\n slot0.tick,\\n 0,\\n slot0.observationCardinality,\\n slot0.observationCardinalityNext\\n );\\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\\n slot0.tick = _observationData.tick;\\n }\\n\\n modifier onlyDataReceiver() {\\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\\n _;\\n }\\n\\n modifier onlyFactory() {\\n if (msg.sender != address(factory)) revert OnlyFactory();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x1b830dc6ad7405f2d533e1aa8eb079853edcdf301b396ac6b1d3c41573b62787\",\"license\":\"MIT\"},\"solidity/interfaces/IDataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleFactory} from './IOracleFactory.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\\n\\ninterface IDataReceiver is IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @notice Tracks already deployed oracles\\n /// @param _poolSalt The identifier of the oracle\\n /// @return _deployedOracle The address of the correspondant Oracle\\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\\n\\n /// @notice Tracks the whitelisting of bridge adapters\\n /// @param _adapter Address of the bridge adapter to consult\\n /// @return _isAllowed Whether a bridge adapter is whitelisted\\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a broadcast observation is succesfully processed\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsAdded(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a broadcast observation is cached for later processing\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsCached(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a new adapter whitelisting rule is set\\n /// @param _adapter Address of the adapter\\n /// @param _isAllowed New whitelisting status\\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\\n\\n // ERRORS\\n\\n /// @notice Thrown when the broadcast nonce is incorrect\\n error ObservationsNotWritable();\\n\\n /// @notice Thrown when a not-whitelisted adapter triggers an update\\n error UnallowedAdapter();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows whitelisted bridge adapters to push a broadcast\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _poolNonce Nonce of the observation broadcast\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external;\\n\\n /// @notice Allows any address to attempt to insert cached observations\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _maxObservations Maximum number of observations to process\\n /// @dev Use _maxObservations = 0 to process all possible cached observations\\n function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external;\\n\\n /// @notice Allows governance to set an adapter whitelisted state\\n /// @param _receiverAdapter Address of the adapter\\n /// @param _isWhitelisted New whitelisting status\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\\n\\n /// @notice Allows governance to batch set adapters whitelisted state\\n /// @param _receiverAdapters Array of addresses of the adapter\\n /// @param _isWhitelisted Array of whitelisting status for each address\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\\n}\\n\",\"keccak256\":\"0xd07e75380d5086ea78909bc5c80aadc110903004f50c006b0281cc090f273291\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IDataReceiver} from './IDataReceiver.sol';\\n\\ninterface IOracleFactory is IGovernable {\\n // STRUCTS\\n\\n struct OracleParameters {\\n bytes32 poolSalt; // Identifier of the pool and oracle\\n uint24 poolNonce; // Initial nonce of the deployed pool\\n uint16 cardinality; // Initial cardinality of the deployed pool\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\\n //solhint-disable-next-line func-name-mixedcase\\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\\n\\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /// @return _poolSalt The id of both the oracle and the pool\\n /// @return _poolNonce The initial nonce of the pool data\\n /// @return _cardinality The size of the observations memory storage\\n function oracleParameters()\\n external\\n view\\n returns (\\n bytes32 _poolSalt,\\n uint24 _poolNonce,\\n uint16 _cardinality\\n );\\n\\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function initialCardinality() external view returns (uint16 _initialCardinality);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new oracle is deployed\\n /// @param _poolSalt The id of both the oracle and the pool\\n /// @param _oracle The address of the deployed oracle\\n /// @param _initialNonce The initial nonce of the pool data\\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\\n\\n /// @notice Emitted when a new DataReceiver is set\\n /// @param _dataReceiver The address of the new DataReceiver\\n event DataReceiverSet(IDataReceiver _dataReceiver);\\n\\n /// @notice Emitted when a new initial oracle cardinality is set\\n /// @param _initialCardinality The initial length of the observationCardinality array\\n event InitialCardinalitySet(uint16 _initialCardinality);\\n\\n // ERRORS\\n\\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\\n error OnlyDataReceiver();\\n\\n // FUNCTIONS\\n\\n /// @notice Deploys a new oracle given an inputted salt\\n /// @dev Requires that the salt has not been deployed before\\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\\n /// @return _oracle The address of the newly deployed oracle\\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\\n\\n /// @notice Allows governor to set a new allowed dataReceiver\\n /// @dev Will disallow the previous dataReceiver\\n /// @param _dataReceiver The address of the new allowed dataReceiver\\n function setDataReceiver(IDataReceiver _dataReceiver) external;\\n\\n /// @notice Allows governor to set a new initial cardinality for new oracles\\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function setInitialCardinality(uint16 _initialCardinality) external;\\n\\n /// @notice Overrides UniV3Factory getPool mapping\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _oracle The oracle address\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle);\\n\\n /// @notice Tracks the addresses of the oracle by poolSalt\\n /// @param _poolSalt Identifier of both the pool and the oracle\\n /// @return _oracle The address (if deployed) of the correspondant oracle\\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\\n\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _poolSalt Pool salt for inquired parameters\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (bytes32 _poolSalt);\\n}\\n\",\"keccak256\":\"0xc32bfc32a274923ce1a089acc024396e702ae354773f0ac0a683e43ded904954\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleFactory} from './IOracleFactory.sol';\\n\\ninterface IOracleSidechain {\\n // STRUCTS\\n\\n struct ObservationData {\\n uint32 blockTimestamp;\\n int24 tick;\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function factory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @return _token0 The mainnet address of the Token0 of the oracle\\n function token0() external view returns (address _token0);\\n\\n /// @return _token1 The mainnet address of the Token1 of the oracle\\n function token1() external view returns (address _token1);\\n\\n /// @return _fee The fee identifier of the pool\\n function fee() external view returns (uint24 _fee);\\n\\n /// @return _poolSalt The identifier of both the pool and the oracle\\n function poolSalt() external view returns (bytes32 _poolSalt);\\n\\n /// @return _poolNonce Last recorded nonce of the pool history\\n function poolNonce() external view returns (uint24 _poolNonce);\\n\\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\\n /// @return _tick Used to maintain compatibility with Uniswap V3\\n /// @return _observationIndex The index of the last oracle observation that was written,\\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\\n /// @return _unlocked Used to track if a pool information was already verified\\n function slot0()\\n external\\n view\\n returns (\\n uint160 _sqrtPriceX96,\\n int24 _tick,\\n uint16 _observationIndex,\\n uint16 _observationCardinality,\\n uint16 _observationCardinalityNext,\\n uint8 _feeProtocol,\\n bool _unlocked\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param _index The element of the observations array to fetch\\n /// @return _blockTimestamp The timestamp of the observation,\\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// @return _initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 _index)\\n external\\n view\\n returns (\\n uint32 _blockTimestamp,\\n int56 _tickCumulative,\\n uint160 _secondsPerLiquidityCumulativeX128,\\n bool _initialized\\n );\\n\\n // EVENTS\\n\\n /// @notice Emitted when the pool information is verified\\n /// @param _poolSalt Identifier of the pool and the oracle\\n /// @param _token0 The contract address of either token0 or token1\\n /// @param _token1 The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\\n\\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param _tick The log base 1.0001 of price of the pool after the swap\\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\\n\\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\\n\\n // ERRORS\\n\\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\\n error AI();\\n\\n /// @notice Thrown if the pool info does not correspond to the pool salt\\n error InvalidPool();\\n\\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\\n error OnlyDataReceiver();\\n\\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\\n error OnlyFactory();\\n\\n // FUNCTIONS\\n\\n /// @notice Permisionless method to verify token0, token1 and fee\\n /// @dev Before verified, token0 and token1 views will return address(0)\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external;\\n\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\\n\\n /// @notice Permisioned method to push a dataset to update\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolNonce Nonce of the observation broadcast\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\\n\\n /// @notice Permisioned method to increase the cardinalityNext value\\n /// @param _observationCardinalityNext The new next length of the observations array\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa90206e3de00ad866b7f4792ce29220ee0ca561d59629ba638a31c4d6fd3941b\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IBridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport {IDataReceiver} from '../IDataReceiver.sol';\\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\\n\\ninterface IBridgeReceiverAdapter is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @notice Gets the address of the DataReceiver contract\\n /// @return _dataReceiver Address of the DataReceiver contract\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /* NOTE: callback methods should be here declared */\\n}\\n\",\"keccak256\":\"0x49e5c9c6a28521933a3f2b01a529fbae9aac1edd71dbe904586a2f06148b1974\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060405161123e38038061123e83398101604081905261002f916100bc565b816001600160a01b0381166100575760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0392831617905581166100925760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052506100f6565b6001600160a01b03811681146100b957600080fd5b50565b600080604083850312156100cf57600080fd5b82516100da816100a4565b60208401519092506100eb816100a4565b809150509250929050565b60805161111f61011f60003960008181610182015281816106ce0152610772015261111f6000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063a853456211610071578063a853456214610137578063b893cce21461014a578063c7f7fb901461017d578063d34ad409146101a4578063e3056a34146101b7578063f235757f146101ca57600080fd5b80630c340a24146100ae5780630ddb5dd2146100de57806313f6986d146100f35780636607baca146100fb578063954e863e14610124575b600080fd5b6000546100c1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100f16100ec366004610ce5565b6101dd565b005b6100f161029d565b6100c1610109366004610d51565b6002602052600090815260409020546001600160a01b031681565b6100f1610132366004610d8d565b6102d2565b6100f1610145366004610dc6565b61030b565b61016d610158366004610de8565b60036020526000908152604090205460ff1681565b60405190151581526020016100d5565b6100c17f000000000000000000000000000000000000000000000000000000000000000081565b6100f16101b2366004610e9d565b610563565b6001546100c1906001600160a01b031681565b6100f16101d8366004610de8565b6105a3565b6000546001600160a01b031633146102085760405163070545c960e51b815260040160405180910390fd5b8281811461022c576040516001621398b960e31b0319815260040160405180910390fd5b60005b818110156102955761028d86868381811061024c5761024c610fa9565b90506020020160208101906102619190610de8565b85858481811061027357610273610fa9565b90506020020160208101906102889190610fbf565b6105da565b60010161022f565b505050505050565b6001546001600160a01b031633146102c857604051639ba0305d60e01b815260040160405180910390fd5b6102d061063d565b565b6000546001600160a01b031633146102fd5760405163070545c960e51b815260040160405180910390fd5b61030782826105da565b5050565b6000828152600260205260409020546001600160a01b0316806103415760405163d92e233d60e01b815260040160405180910390fd5b60606000826001600160a01b0316639fdbd4d76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610fdc565b905060005b8415806103b857508481105b1561054257600086815260046020908152604080832062ffffff86168452825280832080548251818502810185019093528083529193909284015b8282101561043a576000848152602090819020604080518082019091529084015463ffffffff81168252640100000000900460020b818301528252600190920191016103f3565b505050509250600083511115610542576040516308f944b560e21b81526001600160a01b038516906323e512d4906104789086908690600401610ff9565b6020604051808303816000875af1158015610497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bb919061105e565b506040805162ffffff8416815233602082015287917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2600086815260046020908152604080832062ffffff86168452909152812061052291610c5d565b8161052c81611091565b925050808061053a906110b3565b9150506103ac565b8060000361029557604051630a96dcbd60e11b815260040160405180910390fd5b3360009081526003602052604090205460ff16610593576040516360ece74160e01b815260040160405180910390fd5b61059e83838361069b565b505050565b6000546001600160a01b031633146105ce5760405163070545c960e51b815260040160405180910390fd5b6105d781610bd4565b50565b6001600160a01b038216600081815260036020908152604091829020805460ff19168515159081179091558251938452908301527f3cece36ac6216147f57b10bb30975f82b18b8b290a7925c322277e684afcce4a910160405180910390a15050565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000828152600260205260409020546001600160a01b0316806108125760405163f6c0092760e01b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f6c0092790602401602060405180830381865afa15801561071d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074191906110cc565b90506001600160a01b0381166107ea57604051632e60fe9b60e11b81526004810184905262ffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635cc1fd36906044016020604051808303816000875af11580156107c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e791906110cc565b90505b600083815260026020526040902080546001600160a01b0319166001600160a01b0383161790555b6040516308f944b560e21b81526001600160a01b038216906323e512d4906108409087908690600401610ff9565b6020604051808303816000875af115801561085f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610883919061105e565b156108cc576040805162ffffff8416815233602082015284917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2610bce565b6000816001600160a01b0316639fdbd4d76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109309190610fdc565b90508262ffffff168162ffffff16111561095d57604051630a96dcbd60e11b815260040160405180910390fd5b600084815260046020908152604080832062ffffff8716845290915281208054909103610a465760005b8651811015610a0557818782815181106109a3576109a3610fa9565b6020908102919091018101518254600181018455600093845292829020815193018054919092015162ffffff166401000000000266ffffffffffffff1990911663ffffffff909316929092179190911790556109fe816110b3565b9050610987565b506040805162ffffff8616815233602082015286917fca8a146eac241d31b0d3d0650d8747b21a7d1f1a21c55abdbb7209740d742dd1910160405180910390a25b8362ffffff168262ffffff161161029557600085815260046020908152604080832062ffffff86168452825280832080548251818502810185019093528083529193909284015b82821015610ad4576000848152602090819020604080518082019091529084015463ffffffff81168252640100000000900460020b81830152825260019092019101610a8d565b505050509550600086511115610295576040516308f944b560e21b81526001600160a01b038416906323e512d490610b129089908690600401610ff9565b6020604051808303816000875af1158015610b31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b55919061105e565b506040805162ffffff8416815233602082015286917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2600085815260046020908152604080832062ffffff861684529091528120610bbc91610c5d565b81610bc681611091565b925050610a46565b50505050565b6001600160a01b038116610bfb5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910160405180910390a150565b50805460008255906000526020600020908101906105d791905b80821115610c9557805466ffffffffffffff19168155600101610c77565b5090565b60008083601f840112610cab57600080fd5b50813567ffffffffffffffff811115610cc357600080fd5b6020830191508360208260051b8501011115610cde57600080fd5b9250929050565b60008060008060408587031215610cfb57600080fd5b843567ffffffffffffffff80821115610d1357600080fd5b610d1f88838901610c99565b90965094506020870135915080821115610d3857600080fd5b50610d4587828801610c99565b95989497509550505050565b600060208284031215610d6357600080fd5b5035919050565b6001600160a01b03811681146105d757600080fd5b80151581146105d757600080fd5b60008060408385031215610da057600080fd5b8235610dab81610d6a565b91506020830135610dbb81610d7f565b809150509250929050565b60008060408385031215610dd957600080fd5b50508035926020909101359150565b600060208284031215610dfa57600080fd5b8135610e0581610d6a565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610e4557610e45610e0c565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e7457610e74610e0c565b604052919050565b62ffffff811681146105d757600080fd5b8035610e9881610e7c565b919050565b600080600060608486031215610eb257600080fd5b833567ffffffffffffffff80821115610eca57600080fd5b818601915086601f830112610ede57600080fd5b8135602082821115610ef257610ef2610e0c565b610f00818360051b01610e4b565b828152818101935060069290921b840181019189831115610f2057600080fd5b938101935b82851015610f88576040858b031215610f3e5760008081fd5b610f46610e22565b853563ffffffff81168114610f5b5760008081fd5b815285830135600281900b8114610f725760008081fd5b8184015284526040949094019392810192610f25565b96508701359450610fa0925050604086019050610e8d565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610fd157600080fd5b8135610e0581610d7f565b600060208284031215610fee57600080fd5b8151610e0581610e7c565b60408082528351828201819052600091906020906060850190828801855b82811015611045578151805163ffffffff16855285015160020b858501529285019290840190600101611017565b50505062ffffff95909516930192909252509092915050565b60006020828403121561107057600080fd5b8151610e0581610d7f565b634e487b7160e01b600052601160045260246000fd5b600062ffffff8083168181036110a9576110a961107b565b6001019392505050565b6000600182016110c5576110c561107b565b5060010190565b6000602082840312156110de57600080fd5b8151610e0581610d6a56fea2646970667358221220feefa69a3de86bbaf7ecd4017a75d5900e14dae7c288b4dcb2f4bcea3c8fdb5264736f6c634300080f0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c8063a853456211610071578063a853456214610137578063b893cce21461014a578063c7f7fb901461017d578063d34ad409146101a4578063e3056a34146101b7578063f235757f146101ca57600080fd5b80630c340a24146100ae5780630ddb5dd2146100de57806313f6986d146100f35780636607baca146100fb578063954e863e14610124575b600080fd5b6000546100c1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100f16100ec366004610ce5565b6101dd565b005b6100f161029d565b6100c1610109366004610d51565b6002602052600090815260409020546001600160a01b031681565b6100f1610132366004610d8d565b6102d2565b6100f1610145366004610dc6565b61030b565b61016d610158366004610de8565b60036020526000908152604090205460ff1681565b60405190151581526020016100d5565b6100c17f000000000000000000000000000000000000000000000000000000000000000081565b6100f16101b2366004610e9d565b610563565b6001546100c1906001600160a01b031681565b6100f16101d8366004610de8565b6105a3565b6000546001600160a01b031633146102085760405163070545c960e51b815260040160405180910390fd5b8281811461022c576040516001621398b960e31b0319815260040160405180910390fd5b60005b818110156102955761028d86868381811061024c5761024c610fa9565b90506020020160208101906102619190610de8565b85858481811061027357610273610fa9565b90506020020160208101906102889190610fbf565b6105da565b60010161022f565b505050505050565b6001546001600160a01b031633146102c857604051639ba0305d60e01b815260040160405180910390fd5b6102d061063d565b565b6000546001600160a01b031633146102fd5760405163070545c960e51b815260040160405180910390fd5b61030782826105da565b5050565b6000828152600260205260409020546001600160a01b0316806103415760405163d92e233d60e01b815260040160405180910390fd5b60606000826001600160a01b0316639fdbd4d76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610fdc565b905060005b8415806103b857508481105b1561054257600086815260046020908152604080832062ffffff86168452825280832080548251818502810185019093528083529193909284015b8282101561043a576000848152602090819020604080518082019091529084015463ffffffff81168252640100000000900460020b818301528252600190920191016103f3565b505050509250600083511115610542576040516308f944b560e21b81526001600160a01b038516906323e512d4906104789086908690600401610ff9565b6020604051808303816000875af1158015610497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bb919061105e565b506040805162ffffff8416815233602082015287917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2600086815260046020908152604080832062ffffff86168452909152812061052291610c5d565b8161052c81611091565b925050808061053a906110b3565b9150506103ac565b8060000361029557604051630a96dcbd60e11b815260040160405180910390fd5b3360009081526003602052604090205460ff16610593576040516360ece74160e01b815260040160405180910390fd5b61059e83838361069b565b505050565b6000546001600160a01b031633146105ce5760405163070545c960e51b815260040160405180910390fd5b6105d781610bd4565b50565b6001600160a01b038216600081815260036020908152604091829020805460ff19168515159081179091558251938452908301527f3cece36ac6216147f57b10bb30975f82b18b8b290a7925c322277e684afcce4a910160405180910390a15050565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000828152600260205260409020546001600160a01b0316806108125760405163f6c0092760e01b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f6c0092790602401602060405180830381865afa15801561071d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074191906110cc565b90506001600160a01b0381166107ea57604051632e60fe9b60e11b81526004810184905262ffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635cc1fd36906044016020604051808303816000875af11580156107c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e791906110cc565b90505b600083815260026020526040902080546001600160a01b0319166001600160a01b0383161790555b6040516308f944b560e21b81526001600160a01b038216906323e512d4906108409087908690600401610ff9565b6020604051808303816000875af115801561085f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610883919061105e565b156108cc576040805162ffffff8416815233602082015284917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2610bce565b6000816001600160a01b0316639fdbd4d76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109309190610fdc565b90508262ffffff168162ffffff16111561095d57604051630a96dcbd60e11b815260040160405180910390fd5b600084815260046020908152604080832062ffffff8716845290915281208054909103610a465760005b8651811015610a0557818782815181106109a3576109a3610fa9565b6020908102919091018101518254600181018455600093845292829020815193018054919092015162ffffff166401000000000266ffffffffffffff1990911663ffffffff909316929092179190911790556109fe816110b3565b9050610987565b506040805162ffffff8616815233602082015286917fca8a146eac241d31b0d3d0650d8747b21a7d1f1a21c55abdbb7209740d742dd1910160405180910390a25b8362ffffff168262ffffff161161029557600085815260046020908152604080832062ffffff86168452825280832080548251818502810185019093528083529193909284015b82821015610ad4576000848152602090819020604080518082019091529084015463ffffffff81168252640100000000900460020b81830152825260019092019101610a8d565b505050509550600086511115610295576040516308f944b560e21b81526001600160a01b038416906323e512d490610b129089908690600401610ff9565b6020604051808303816000875af1158015610b31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b55919061105e565b506040805162ffffff8416815233602082015286917f9a777601844e27c439fe9f23f4ada7ea2b67551ea35b07439e3dad53e0e369cd910160405180910390a2600085815260046020908152604080832062ffffff861684529091528120610bbc91610c5d565b81610bc681611091565b925050610a46565b50505050565b6001600160a01b038116610bfb5760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910160405180910390a150565b50805460008255906000526020600020908101906105d791905b80821115610c9557805466ffffffffffffff19168155600101610c77565b5090565b60008083601f840112610cab57600080fd5b50813567ffffffffffffffff811115610cc357600080fd5b6020830191508360208260051b8501011115610cde57600080fd5b9250929050565b60008060008060408587031215610cfb57600080fd5b843567ffffffffffffffff80821115610d1357600080fd5b610d1f88838901610c99565b90965094506020870135915080821115610d3857600080fd5b50610d4587828801610c99565b95989497509550505050565b600060208284031215610d6357600080fd5b5035919050565b6001600160a01b03811681146105d757600080fd5b80151581146105d757600080fd5b60008060408385031215610da057600080fd5b8235610dab81610d6a565b91506020830135610dbb81610d7f565b809150509250929050565b60008060408385031215610dd957600080fd5b50508035926020909101359150565b600060208284031215610dfa57600080fd5b8135610e0581610d6a565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610e4557610e45610e0c565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e7457610e74610e0c565b604052919050565b62ffffff811681146105d757600080fd5b8035610e9881610e7c565b919050565b600080600060608486031215610eb257600080fd5b833567ffffffffffffffff80821115610eca57600080fd5b818601915086601f830112610ede57600080fd5b8135602082821115610ef257610ef2610e0c565b610f00818360051b01610e4b565b828152818101935060069290921b840181019189831115610f2057600080fd5b938101935b82851015610f88576040858b031215610f3e5760008081fd5b610f46610e22565b853563ffffffff81168114610f5b5760008081fd5b815285830135600281900b8114610f725760008081fd5b8184015284526040949094019392810192610f25565b96508701359450610fa0925050604086019050610e8d565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610fd157600080fd5b8135610e0581610d7f565b600060208284031215610fee57600080fd5b8151610e0581610e7c565b60408082528351828201819052600091906020906060850190828801855b82811015611045578151805163ffffffff16855285015160020b858501529285019290840190600101611017565b50505062ffffff95909516930192909252509092915050565b60006020828403121561107057600080fd5b8151610e0581610d7f565b634e487b7160e01b600052601160045260246000fd5b600062ffffff8083168181036110a9576110a961107b565b6001019392505050565b6000600182016110c5576110c561107b565b5060010190565b6000602082840312156110de57600080fd5b8151610e0581610d6a56fea2646970667358221220feefa69a3de86bbaf7ecd4017a75d5900e14dae7c288b4dcb2f4bcea3c8fdb5264736f6c634300080f0033", + "devdoc": { + "kind": "dev", + "methods": { + "addObservations((uint32,int24)[],bytes32,uint24)": { + "params": { + "_observationsData": "Array of tuples containing the dataset", + "_poolNonce": "Nonce of the observation broadcast", + "_poolSalt": "Identifier of the pool to fetch" + } + }, + "setPendingGovernor(address)": { + "params": { + "_pendingGovernor": "Address of the proposed new governor" + } + }, + "syncObservations(bytes32,uint256)": { + "details": "Use _maxObservations = 0 to process all possible cached observations", + "params": { + "_maxObservations": "Maximum number of observations to process", + "_poolSalt": "Identifier of the pool to fetch" + } + }, + "whitelistAdapter(address,bool)": { + "params": { + "_isWhitelisted": "New whitelisting status", + "_receiverAdapter": "Address of the adapter" + } + }, + "whitelistAdapters(address[],bool[])": { + "params": { + "_isWhitelisted": "Array of whitelisting status for each address", + "_receiverAdapters": "Array of addresses of the adapter" + } + } + }, + "stateVariables": { + "deployedOracles": { + "params": { + "_poolSalt": "The identifier of the oracle" + }, + "return": "The address of the correspondant Oracle", + "returns": { + "_0": "The address of the correspondant Oracle" + } + }, + "oracleFactory": { + "return": "The address of the OracleFactory", + "returns": { + "_0": "The address of the OracleFactory" + } + }, + "whitelistedAdapters": { + "params": { + "_adapter": "Address of the bridge adapter to consult" + }, + "return": "Whether a bridge adapter is whitelisted", + "returns": { + "_0": "Whether a bridge adapter is whitelisted" + } + } + }, + "title": "The DataReceiver contract", + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidAddress()": [ + { + "notice": "Thrown if an address is invalid" + } + ], + "InvalidAmount()": [ + { + "notice": "Thrown if an amount is invalid" + } + ], + "LengthMismatch()": [ + { + "notice": "Thrown if the lengths of a set of lists mismatch" + } + ], + "ObservationsNotWritable()": [ + { + "notice": "Thrown when the broadcast nonce is incorrect" + } + ], + "OnlyGovernor()": [ + { + "notice": "Thrown if a non-governor user tries to call a OnlyGovernor function" + } + ], + "OnlyPendingGovernor()": [ + { + "notice": "Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function" + } + ], + "UnallowedAdapter()": [ + { + "notice": "Thrown when a not-whitelisted adapter triggers an update" + } + ], + "ZeroAddress()": [ + { + "notice": "Thrown if an address is the zero address" + } + ], + "ZeroAmount()": [ + { + "notice": "Thrown if an amount is zero" + } + ] + }, + "events": { + "AdapterWhitelisted(address,bool)": { + "notice": "Emitted when a new adapter whitelisting rule is set" + }, + "ObservationsAdded(bytes32,uint24,address)": { + "notice": "Emitted when a broadcast observation is succesfully processed" + }, + "ObservationsCached(bytes32,uint24,address)": { + "notice": "Emitted when a broadcast observation is cached for later processing" + }, + "PendingGovernorAccepted(address)": { + "notice": "Emitted when a new governor is set" + }, + "PendingGovernorSet(address,address)": { + "notice": "Emitted when a new pending governor is set" + } + }, + "kind": "user", + "methods": { + "acceptPendingGovernor()": { + "notice": "Allows a proposed governor to accept the governance" + }, + "addObservations((uint32,int24)[],bytes32,uint24)": { + "notice": "Allows whitelisted bridge adapters to push a broadcast" + }, + "deployedOracles(bytes32)": { + "notice": "Tracks already deployed oracles" + }, + "setPendingGovernor(address)": { + "notice": "Allows a governor to propose a new governor" + }, + "syncObservations(bytes32,uint256)": { + "notice": "Allows any address to attempt to insert cached observations" + }, + "whitelistAdapter(address,bool)": { + "notice": "Allows governance to set an adapter whitelisted state" + }, + "whitelistAdapters(address[],bool[])": { + "notice": "Allows governance to batch set adapters whitelisted state" + }, + "whitelistedAdapters(address)": { + "notice": "Tracks the whitelisting of bridge adapters" + } + }, + "notice": "Handles reception of broadcast data and delivers it to correspondant oracle", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8014, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "governor", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 8017, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "pendingGovernor", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 14967, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "deployedOracles", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_bytes32,t_contract(IOracleSidechain)18334)" + }, + { + "astId": 14973, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "whitelistedAdapters", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_contract(IBridgeReceiverAdapter)18469,t_bool)" + }, + { + "astId": 14981, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "_cachedObservations", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_bytes32,t_mapping(t_uint24,t_array(t_struct(ObservationData)18176_storage)dyn_storage))" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(ObservationData)18176_storage)dyn_storage": { + "base": "t_struct(ObservationData)18176_storage", + "encoding": "dynamic_array", + "label": "struct IOracleSidechain.ObservationData[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IBridgeReceiverAdapter)18469": { + "encoding": "inplace", + "label": "contract IBridgeReceiverAdapter", + "numberOfBytes": "20" + }, + "t_contract(IOracleSidechain)18334": { + "encoding": "inplace", + "label": "contract IOracleSidechain", + "numberOfBytes": "20" + }, + "t_int24": { + "encoding": "inplace", + "label": "int24", + "numberOfBytes": "3" + }, + "t_mapping(t_bytes32,t_contract(IOracleSidechain)18334)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => contract IOracleSidechain)", + "numberOfBytes": "32", + "value": "t_contract(IOracleSidechain)18334" + }, + "t_mapping(t_bytes32,t_mapping(t_uint24,t_array(t_struct(ObservationData)18176_storage)dyn_storage))": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => mapping(uint24 => struct IOracleSidechain.ObservationData[]))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint24,t_array(t_struct(ObservationData)18176_storage)dyn_storage)" + }, + "t_mapping(t_contract(IBridgeReceiverAdapter)18469,t_bool)": { + "encoding": "mapping", + "key": "t_contract(IBridgeReceiverAdapter)18469", + "label": "mapping(contract IBridgeReceiverAdapter => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_uint24,t_array(t_struct(ObservationData)18176_storage)dyn_storage)": { + "encoding": "mapping", + "key": "t_uint24", + "label": "mapping(uint24 => struct IOracleSidechain.ObservationData[])", + "numberOfBytes": "32", + "value": "t_array(t_struct(ObservationData)18176_storage)dyn_storage" + }, + "t_struct(ObservationData)18176_storage": { + "encoding": "inplace", + "label": "struct IOracleSidechain.ObservationData", + "members": [ + { + "astId": 18173, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "blockTimestamp", + "offset": 0, + "slot": "0", + "type": "t_uint32" + }, + { + "astId": 18175, + "contract": "solidity/contracts/DataReceiver.sol:DataReceiver", + "label": "tick", + "offset": 4, + "slot": "0", + "type": "t_int24" + } + ], + "numberOfBytes": "32" + }, + "t_uint24": { + "encoding": "inplace", + "label": "uint24", + "numberOfBytes": "3" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/OracleFactory.json b/deployments/polygon/OracleFactory.json new file mode 100644 index 0000000..fd85756 --- /dev/null +++ b/deployments/polygon/OracleFactory.json @@ -0,0 +1,726 @@ +{ + "address": "0x69ceAA797274fd85F3b3a1f5b29857BFD9B9b259", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "internalType": "contract IDataReceiver", + "name": "_dataReceiver", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "LengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyDataReceiver", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IDataReceiver", + "name": "_dataReceiver", + "type": "address" + } + ], + "name": "DataReceiverSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_initialCardinality", + "type": "uint16" + } + ], + "name": "InitialCardinalitySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "_oracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint24", + "name": "_initialNonce", + "type": "uint24" + } + ], + "name": "OracleDeployed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newGovernor", + "type": "address" + } + ], + "name": "PendingGovernorAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "PendingGovernorSet", + "type": "event" + }, + { + "inputs": [], + "name": "ORACLE_INIT_CODE_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dataReceiver", + "outputs": [ + { + "internalType": "contract IDataReceiver", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + }, + { + "internalType": "uint24", + "name": "_initialNonce", + "type": "uint24" + } + ], + "name": "deployOracle", + "outputs": [ + { + "internalType": "contract IOracleSidechain", + "name": "_oracle", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenB", + "type": "address" + }, + { + "internalType": "uint24", + "name": "_fee", + "type": "uint24" + } + ], + "name": "getPool", + "outputs": [ + { + "internalType": "contract IOracleSidechain", + "name": "_oracle", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + } + ], + "name": "getPool", + "outputs": [ + { + "internalType": "contract IOracleSidechain", + "name": "_oracle", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenB", + "type": "address" + }, + { + "internalType": "uint24", + "name": "_fee", + "type": "uint24" + } + ], + "name": "getPoolSalt", + "outputs": [ + { + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_poolSalt", + "type": "bytes32" + }, + { + "internalType": "uint16", + "name": "_observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseOracleCardinality", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialCardinality", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracleParameters", + "outputs": [ + { + "internalType": "bytes32", + "name": "poolSalt", + "type": "bytes32" + }, + { + "internalType": "uint24", + "name": "poolNonce", + "type": "uint24" + }, + { + "internalType": "uint16", + "name": "cardinality", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingGovernor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IDataReceiver", + "name": "_dataReceiver", + "type": "address" + } + ], + "name": "setDataReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_initialCardinality", + "type": "uint16" + } + ], + "name": "setInitialCardinality", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "setPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xe996d2199e475d2e891b6aaee96d869e1a1efa720e775b3b4e61b225b4daa46f", + "receipt": { + "to": null, + "from": "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "contractAddress": "0x69ceAA797274fd85F3b3a1f5b29857BFD9B9b259", + "transactionIndex": 59, + "gasUsed": "2228781", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000008000000000000000000000000000800000000000000000000000000000800002000000000004000100000000000100000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000400000000000000000000000000200000000000000000000400000000000000000000000000000000000000004001000000000000040001000000000000000800000000000000140000040000000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x748d87af71cc5eb21c2739ef54507a65b5e910b3fbf945298e3f553f0affbcc1", + "transactionHash": "0xe996d2199e475d2e891b6aaee96d869e1a1efa720e775b3b4e61b225b4daa46f", + "logs": [ + { + "transactionIndex": 59, + "blockNumber": 60867651, + "transactionHash": "0xe996d2199e475d2e891b6aaee96d869e1a1efa720e775b3b4e61b225b4daa46f", + "address": "0x69ceAA797274fd85F3b3a1f5b29857BFD9B9b259", + "topics": [ + "0x23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000042069", + "logIndex": 257, + "blockHash": "0x748d87af71cc5eb21c2739ef54507a65b5e910b3fbf945298e3f553f0affbcc1" + }, + { + "transactionIndex": 59, + "blockNumber": 60867651, + "transactionHash": "0xe996d2199e475d2e891b6aaee96d869e1a1efa720e775b3b4e61b225b4daa46f", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000a6dbff53dd8f89f0bf4f6800bfdffe099875bd9d", + "0x000000000000000000000000b95d435df3f8b2a8d8b9c2b7c8766c9ae6ed8cc9" + ], + "data": "0x00000000000000000000000000000000000000000000000000eae1fba4c816b60000000000000000000000000000000000000000000000004d18b1d4754bcce3000000000000000000000000000000000000000000000022ca5a85252b66ddf50000000000000000000000000000000000000000000000004c2dcfd8d083b62d000000000000000000000000000000000000000000000022cb456720d02ef4ab", + "logIndex": 258, + "blockHash": "0x748d87af71cc5eb21c2739ef54507a65b5e910b3fbf945298e3f553f0affbcc1" + } + ], + "blockNumber": 60867651, + "cumulativeGasUsed": "10121536", + "status": 1, + "byzantium": true + }, + "args": [ + "0xa6DBFF53DD8F89f0bf4f6800BFDFfE099875bd9d", + "0x0000000000000000000000000000000000042069" + ], + "numDeployments": 2, + "solcInputHash": "1ffcc3895a1a8980b9e58deee89219d1", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDataReceiver\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"}],\"name\":\"DataReceiverSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"_initialCardinality\",\"type\":\"uint16\"}],\"name\":\"InitialCardinalitySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"_initialNonce\",\"type\":\"uint24\"}],\"name\":\"OracleDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ORACLE_INIT_CODE_HASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dataReceiver\",\"outputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"_initialNonce\",\"type\":\"uint24\"}],\"name\":\"deployOracle\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenA\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenB\",\"type\":\"address\"},{\"internalType\":\"uint24\",\"name\":\"_fee\",\"type\":\"uint24\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"contract IOracleSidechain\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenA\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenB\",\"type\":\"address\"},{\"internalType\":\"uint24\",\"name\":\"_fee\",\"type\":\"uint24\"}],\"name\":\"getPoolSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint16\",\"name\":\"_observationCardinalityNext\",\"type\":\"uint16\"}],\"name\":\"increaseOracleCardinality\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialCardinality\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleParameters\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolSalt\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"poolNonce\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"cardinality\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IDataReceiver\",\"name\":\"_dataReceiver\",\"type\":\"address\"}],\"name\":\"setDataReceiver\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"_initialCardinality\",\"type\":\"uint16\"}],\"name\":\"setInitialCardinality\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"setPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"deployOracle(bytes32,uint24)\":{\"details\":\"Requires that the salt has not been deployed before\",\"params\":{\"_poolSalt\":\"Pool salt that deterministically binds an oracle with a pool\"},\"returns\":{\"_oracle\":\"The address of the newly deployed oracle\"}},\"getPool(address,address,uint24)\":{\"params\":{\"_fee\":\"The fee denominated in hundredths of a bip\",\"_tokenA\":\"The contract address of either token0 or token1\",\"_tokenB\":\"The contract address of the other token\"},\"returns\":{\"_oracle\":\"The oracle address\"}},\"getPool(bytes32)\":{\"params\":{\"_poolSalt\":\"Identifier of both the pool and the oracle\"},\"returns\":{\"_oracle\":\"The address (if deployed) of the correspondant oracle\"}},\"getPoolSalt(address,address,uint24)\":{\"params\":{\"_fee\":\"The fee denominated in hundredths of a bip\",\"_tokenA\":\"The contract address of either token0 or token1\",\"_tokenB\":\"The contract address of the other token\"},\"returns\":{\"_poolSalt\":\"Pool salt for inquired parameters\"}},\"setDataReceiver(address)\":{\"details\":\"Will disallow the previous dataReceiver\",\"params\":{\"_dataReceiver\":\"The address of the new allowed dataReceiver\"}},\"setInitialCardinality(uint16)\":{\"params\":{\"_initialCardinality\":\"The initial size of the observations memory storage for newly deployed pools\"}},\"setPendingGovernor(address)\":{\"params\":{\"_pendingGovernor\":\"Address of the proposed new governor\"}}},\"stateVariables\":{\"ORACLE_INIT_CODE_HASH\":{\"return\":\"The oracle creation code hash used to calculate their address\",\"returns\":{\"_0\":\"The oracle creation code hash used to calculate their address\"}},\"dataReceiver\":{\"return\":\"The address of the DataReceiver for the oracles to consult\",\"returns\":{\"_0\":\"The address of the DataReceiver for the oracles to consult\"}},\"initialCardinality\":{\"return\":\"The initial size of the observations memory storage for newly deployed pools\",\"returns\":{\"_0\":\"The initial size of the observations memory storage for newly deployed pools\"}},\"oracleParameters\":{\"returns\":{\"cardinality\":\"The size of the observations memory storage\",\"poolNonce\":\"The initial nonce of the pool data\",\"poolSalt\":\"The id of both the oracle and the pool\"}}},\"title\":\"The OracleFactory contract\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"OnlyDataReceiver()\":[{\"notice\":\"Thrown when a contract other than the DataReceiver tries to deploy an oracle\"}],\"OnlyGovernor()\":[{\"notice\":\"Thrown if a non-governor user tries to call a OnlyGovernor function\"}],\"OnlyPendingGovernor()\":[{\"notice\":\"Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"events\":{\"DataReceiverSet(address)\":{\"notice\":\"Emitted when a new DataReceiver is set\"},\"InitialCardinalitySet(uint16)\":{\"notice\":\"Emitted when a new initial oracle cardinality is set\"},\"OracleDeployed(bytes32,address,uint24)\":{\"notice\":\"Emitted when a new oracle is deployed\"},\"PendingGovernorAccepted(address)\":{\"notice\":\"Emitted when a new governor is set\"},\"PendingGovernorSet(address,address)\":{\"notice\":\"Emitted when a new pending governor is set\"}},\"kind\":\"user\",\"methods\":{\"acceptPendingGovernor()\":{\"notice\":\"Allows a proposed governor to accept the governance\"},\"deployOracle(bytes32,uint24)\":{\"notice\":\"Deploys a new oracle given an inputted salt\"},\"getPool(address,address,uint24)\":{\"notice\":\"Overrides UniV3Factory getPool mapping\"},\"getPool(bytes32)\":{\"notice\":\"Tracks the addresses of the oracle by poolSalt\"},\"setDataReceiver(address)\":{\"notice\":\"Allows governor to set a new allowed dataReceiver\"},\"setInitialCardinality(uint16)\":{\"notice\":\"Allows governor to set a new initial cardinality for new oracles\"},\"setPendingGovernor(address)\":{\"notice\":\"Allows a governor to propose a new governor\"}},\"notice\":\"Handles the deployment of new OracleSidechains\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/OracleFactory.sol\":\"OracleFactory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '../interfaces/IGovernable.sol';\\n\\n/// @title Governable contract\\n/// @notice Manages the governor role\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public governor;\\n\\n /// @inheritdoc IGovernable\\n address public pendingGovernor;\\n\\n constructor(address _governor) {\\n if (_governor == address(0)) revert ZeroAddress();\\n governor = _governor;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\\n _setPendingGovernor(_pendingGovernor);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptPendingGovernor() external onlyPendingGovernor {\\n _acceptPendingGovernor();\\n }\\n\\n function _setPendingGovernor(address _pendingGovernor) internal {\\n if (_pendingGovernor == address(0)) revert ZeroAddress();\\n pendingGovernor = _pendingGovernor;\\n emit PendingGovernorSet(governor, _pendingGovernor);\\n }\\n\\n function _acceptPendingGovernor() internal {\\n governor = pendingGovernor;\\n delete pendingGovernor;\\n emit PendingGovernorAccepted(governor);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governor\\n modifier onlyGovernor() {\\n if (msg.sender != governor) revert OnlyGovernor();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernor\\n modifier onlyPendingGovernor() {\\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x3f11408cfcb015a99dc417e075c8ebc39b796fc2adc3e81b036487e4486881b3\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity >=0.8.8 <0.9.0;\\n\\n/// @title Provides functions for deriving a UniswapV3Pool address from its factory, tokens and fee\\nlibrary Create2Address {\\n /// @notice Deterministically computes the pool address given the factory, salt and initCodeHash\\n /// @param _factory The Uniswap V3 factory contract address\\n /// @param _salt The PoolKey encoded bytes\\n /// @param _initCodeHash The Init Code Hash of the target\\n /// @return _pool The contract address of the target UniswapV3Pool\\n function computeAddress(address _factory, bytes32 _salt, bytes32 _initCodeHash)\\n internal\\n pure\\n returns (address _pool)\\n {\\n _pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', _factory, _salt, _initCodeHash)))));\\n }\\n}\\n\",\"keccak256\":\"0x867e71cdb6b5b3a4b5f3e6d9bd27262a13d6b54eb18957e8c27cfbbff886ad9d\",\"license\":\"BUSL-1.1\"},\"@uniswap/v3-core/contracts/libraries/Oracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.0;\\n\\n/// @title Oracle\\n/// @notice Provides price and liquidity data useful for a wide variety of system designs\\n/// @dev Instances of stored oracle data, \\\"observations\\\", are collected in the oracle array\\n/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the\\n/// maximum length of the oracle array. New slots will be added when the array is fully populated.\\n/// Observations are overwritten when the full length of the oracle array is populated.\\n/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe()\\nlibrary Oracle {\\n error I();\\n error OLD();\\n\\n struct Observation {\\n // the block timestamp of the observation\\n uint32 blockTimestamp;\\n // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized\\n int56 tickCumulative;\\n // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized\\n uint160 secondsPerLiquidityCumulativeX128;\\n // whether or not the observation is initialized\\n bool initialized;\\n }\\n\\n /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values\\n /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows\\n /// @param last The specified observation to be transformed\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @return Observation The newly populated observation\\n function transform(\\n Observation memory last,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity\\n ) private pure returns (Observation memory) {\\n unchecked {\\n uint32 delta = blockTimestamp - last.blockTimestamp;\\n return\\n Observation({\\n blockTimestamp: blockTimestamp,\\n tickCumulative: last.tickCumulative + int56(tick) * int56(uint56(delta)),\\n secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +\\n ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),\\n initialized: true\\n });\\n }\\n }\\n\\n /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array\\n /// @param self The stored oracle array\\n /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32\\n /// @return cardinality The number of populated elements in the oracle array\\n /// @return cardinalityNext The new length of the oracle array, independent of population\\n function initialize(Observation[65535] storage self, uint32 time)\\n internal\\n returns (uint16 cardinality, uint16 cardinalityNext)\\n {\\n self[0] = Observation({\\n blockTimestamp: time,\\n tickCumulative: 0,\\n secondsPerLiquidityCumulativeX128: 0,\\n initialized: true\\n });\\n return (1, 1);\\n }\\n\\n /// @notice Writes an oracle observation to the array\\n /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally.\\n /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality\\n /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering.\\n /// @param self The stored oracle array\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param blockTimestamp The timestamp of the new observation\\n /// @param tick The active tick at the time of the new observation\\n /// @param liquidity The total in-range liquidity at the time of the new observation\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @param cardinalityNext The new length of the oracle array, independent of population\\n /// @return indexUpdated The new index of the most recently written element in the oracle array\\n /// @return cardinalityUpdated The new cardinality of the oracle array\\n function write(\\n Observation[65535] storage self,\\n uint16 index,\\n uint32 blockTimestamp,\\n int24 tick,\\n uint128 liquidity,\\n uint16 cardinality,\\n uint16 cardinalityNext\\n ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\\n unchecked {\\n Observation memory last = self[index];\\n\\n // early return if we've already written an observation this block\\n if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\\n\\n // if the conditions are right, we can bump the cardinality\\n if (cardinalityNext > cardinality && index == (cardinality - 1)) {\\n cardinalityUpdated = cardinalityNext;\\n } else {\\n cardinalityUpdated = cardinality;\\n }\\n\\n indexUpdated = (index + 1) % cardinalityUpdated;\\n self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);\\n }\\n }\\n\\n /// @notice Prepares the oracle array to store up to `next` observations\\n /// @param self The stored oracle array\\n /// @param current The current next cardinality of the oracle array\\n /// @param next The proposed next cardinality which will be populated in the oracle array\\n /// @return next The next cardinality which will be populated in the oracle array\\n function grow(\\n Observation[65535] storage self,\\n uint16 current,\\n uint16 next\\n ) internal returns (uint16) {\\n unchecked {\\n if (current <= 0) revert I();\\n // no-op if the passed next value isn't greater than the current next value\\n if (next <= current) return current;\\n // store in each slot to prevent fresh SSTOREs in swaps\\n // this data will not be used because the initialized boolean is still false\\n for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;\\n return next;\\n }\\n }\\n\\n /// @notice comparator for 32-bit timestamps\\n /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time\\n /// @param time A timestamp truncated to 32 bits\\n /// @param a A comparison timestamp from which to determine the relative position of `time`\\n /// @param b From which to determine the relative position of `time`\\n /// @return Whether `a` is chronologically <= `b`\\n function lte(\\n uint32 time,\\n uint32 a,\\n uint32 b\\n ) private pure returns (bool) {\\n unchecked {\\n // if there hasn't been overflow, no need to adjust\\n if (a <= time && b <= time) return a <= b;\\n\\n uint256 aAdjusted = a > time ? a : a + 2**32;\\n uint256 bAdjusted = b > time ? b : b + 2**32;\\n\\n return aAdjusted <= bAdjusted;\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied.\\n /// The result may be the same observation, or adjacent observations.\\n /// @dev The answer must be contained in the array, used when the target is located within the stored observation\\n /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation recorded before, or at, the target\\n /// @return atOrAfter The observation recorded at, or after, the target\\n function binarySearch(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n uint16 index,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n uint256 l = (index + 1) % cardinality; // oldest observation\\n uint256 r = l + cardinality - 1; // newest observation\\n uint256 i;\\n while (true) {\\n i = (l + r) / 2;\\n\\n beforeOrAt = self[i % cardinality];\\n\\n // we've landed on an uninitialized tick, keep searching higher (more recently)\\n if (!beforeOrAt.initialized) {\\n l = i + 1;\\n continue;\\n }\\n\\n atOrAfter = self[(i + 1) % cardinality];\\n\\n bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);\\n\\n // check if we've found the answer!\\n if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;\\n\\n if (!targetAtOrAfter) r = i - 1;\\n else l = i + 1;\\n }\\n }\\n }\\n\\n /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied\\n /// @dev Assumes there is at least 1 initialized observation.\\n /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp.\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param target The timestamp at which the reserved observation should be for\\n /// @param tick The active tick at the time of the returned or simulated observation\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The total pool liquidity at the time of the call\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return beforeOrAt The observation which occurred at, or before, the given timestamp\\n /// @return atOrAfter The observation which occurred at, or after, the given timestamp\\n function getSurroundingObservations(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 target,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\\n unchecked {\\n // optimistically set before to the newest observation\\n beforeOrAt = self[index];\\n\\n // if the target is chronologically at or after the newest observation, we can early return\\n if (lte(time, beforeOrAt.blockTimestamp, target)) {\\n if (beforeOrAt.blockTimestamp == target) {\\n // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\\n return (beforeOrAt, atOrAfter);\\n } else {\\n // otherwise, we need to transform\\n return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));\\n }\\n }\\n\\n // now, set before to the oldest observation\\n beforeOrAt = self[(index + 1) % cardinality];\\n if (!beforeOrAt.initialized) beforeOrAt = self[0];\\n\\n // ensure that the target is chronologically at or after the oldest observation\\n if (!lte(time, beforeOrAt.blockTimestamp, target)) revert OLD();\\n\\n // if we've reached this point, we have to binary search\\n return binarySearch(self, time, target, index, cardinality);\\n }\\n }\\n\\n /// @dev Reverts if an observation at or before the desired observation timestamp does not exist.\\n /// 0 may be passed as `secondsAgo' to return the current cumulative values.\\n /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values\\n /// at exactly the timestamp between the two observations.\\n /// @param self The stored oracle array\\n /// @param time The current block timestamp\\n /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo`\\n function observeSingle(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32 secondsAgo,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {\\n unchecked {\\n if (secondsAgo == 0) {\\n Observation memory last = self[index];\\n if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);\\n return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);\\n }\\n\\n uint32 target = time - secondsAgo;\\n\\n (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\\n self,\\n time,\\n target,\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n\\n if (target == beforeOrAt.blockTimestamp) {\\n // we're at the left boundary\\n return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);\\n } else if (target == atOrAfter.blockTimestamp) {\\n // we're at the right boundary\\n return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);\\n } else {\\n // we're in the middle\\n uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;\\n uint32 targetDelta = target - beforeOrAt.blockTimestamp;\\n return (\\n beforeOrAt.tickCumulative +\\n ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / int56(uint56(observationTimeDelta))) *\\n int56(uint56(targetDelta)),\\n beforeOrAt.secondsPerLiquidityCumulativeX128 +\\n uint160(\\n (uint256(\\n atOrAfter.secondsPerLiquidityCumulativeX128 -\\n beforeOrAt.secondsPerLiquidityCumulativeX128\\n ) * targetDelta) / observationTimeDelta\\n )\\n );\\n }\\n }\\n }\\n\\n /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos`\\n /// @dev Reverts if `secondsAgos` > oldest observation\\n /// @param self The stored oracle array\\n /// @param time The current block.timestamp\\n /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation\\n /// @param tick The current tick\\n /// @param index The index of the observation that was most recently written to the observations array\\n /// @param liquidity The current in-range pool liquidity\\n /// @param cardinality The number of populated elements in the oracle array\\n /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo`\\n /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo`\\n function observe(\\n Observation[65535] storage self,\\n uint32 time,\\n uint32[] memory secondsAgos,\\n int24 tick,\\n uint16 index,\\n uint128 liquidity,\\n uint16 cardinality\\n ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {\\n unchecked {\\n if (cardinality <= 0) revert I();\\n\\n tickCumulatives = new int56[](secondsAgos.length);\\n secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);\\n for (uint256 i = 0; i < secondsAgos.length; i++) {\\n (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(\\n self,\\n time,\\n secondsAgos[i],\\n tick,\\n index,\\n liquidity,\\n cardinality\\n );\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa25b18af947c36b9add9e229c361beb6aba176fb435d7a24e6dc723cbc187442\",\"license\":\"BUSL-1.1\"},\"@uniswap/v3-core/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity ^0.8.0;\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n error T();\\n error R();\\n\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n unchecked {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n if (absTick > uint256(int256(MAX_TICK))) revert T();\\n\\n uint256 ratio = absTick & 0x1 != 0\\n ? 0xfffcb933bd6fad37aa2d162d1a594001\\n : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\\n /// ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n unchecked {\\n // second inequality must be < because the price can never reach the price at the max tick\\n if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5c57de03a91cc2ec8939865dbbcb0197bb6c353b711075eefd8e0fca5e102129\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/OracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {Governable} from '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\\nimport {OracleSidechain} from './OracleSidechain.sol';\\nimport {IOracleFactory, IOracleSidechain, IDataReceiver} from '../interfaces/IOracleFactory.sol';\\nimport {Create2Address} from '@defi-wonderland/solidity-utils/solidity/libraries/Create2Address.sol';\\n\\n/// @title The OracleFactory contract\\n/// @notice Handles the deployment of new OracleSidechains\\ncontract OracleFactory is IOracleFactory, Governable {\\n /// @inheritdoc IOracleFactory\\n IDataReceiver public dataReceiver;\\n\\n /// @inheritdoc IOracleFactory\\n OracleParameters public oracleParameters;\\n\\n /// @inheritdoc IOracleFactory\\n uint16 public initialCardinality = 144;\\n\\n /// @inheritdoc IOracleFactory\\n bytes32 public constant ORACLE_INIT_CODE_HASH = keccak256(type(OracleSidechain).creationCode);\\n\\n constructor(address _governor, IDataReceiver _dataReceiver) Governable(_governor) {\\n _setDataReceiver(_dataReceiver);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function deployOracle(bytes32 _poolSalt, uint24 _initialNonce) external onlyDataReceiver returns (IOracleSidechain _oracle) {\\n oracleParameters = OracleParameters({poolSalt: _poolSalt, poolNonce: _initialNonce, cardinality: initialCardinality});\\n _oracle = new OracleSidechain{salt: _poolSalt}();\\n\\n delete oracleParameters;\\n emit OracleDeployed(_poolSalt, address(_oracle), _initialNonce);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function setDataReceiver(IDataReceiver _dataReceiver) external onlyGovernor {\\n _setDataReceiver(_dataReceiver);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function setInitialCardinality(uint16 _initialCardinality) external onlyGovernor {\\n if (_initialCardinality == 0) revert ZeroAmount();\\n\\n initialCardinality = _initialCardinality;\\n emit InitialCardinalitySet(_initialCardinality);\\n }\\n\\n function increaseOracleCardinality(bytes32 _poolSalt, uint16 _observationCardinalityNext) external onlyGovernor {\\n IOracleSidechain _oracle = getPool(_poolSalt);\\n _oracle.increaseObservationCardinalityNext(_observationCardinalityNext);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle) {\\n bytes32 _poolSalt = getPoolSalt(_tokenA, _tokenB, _fee);\\n _oracle = getPool(_poolSalt);\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function getPool(bytes32 _poolSalt) public view returns (IOracleSidechain _oracle) {\\n _oracle = IOracleSidechain(Create2Address.computeAddress(address(this), _poolSalt, ORACLE_INIT_CODE_HASH));\\n if (address(_oracle).code.length == 0) return IOracleSidechain(address(0));\\n }\\n\\n /// @inheritdoc IOracleFactory\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) public pure returns (bytes32 _poolSalt) {\\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\\n _poolSalt = keccak256(abi.encode(_token0, _token1, _fee));\\n }\\n\\n function _setDataReceiver(IDataReceiver _dataReceiver) private {\\n if (address(_dataReceiver) == address(0)) revert ZeroAddress();\\n\\n dataReceiver = _dataReceiver;\\n emit DataReceiverSet(_dataReceiver);\\n }\\n\\n modifier onlyDataReceiver() {\\n if (msg.sender != address(dataReceiver)) revert OnlyDataReceiver();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xf0707ebeed3425fca5ccc20dfc2cb291859674ada92d5d651f7271ee3cef3d49\",\"license\":\"MIT\"},\"solidity/contracts/OracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleSidechain, IOracleFactory} from '../interfaces/IOracleSidechain.sol';\\nimport {Oracle} from '@uniswap/v3-core/contracts/libraries/Oracle.sol';\\nimport {TickMath} from '@uniswap/v3-core/contracts/libraries/TickMath.sol';\\n\\n/// @title The SidechainOracle contract\\n/// @notice Computes and stores on-chain price data from Mainnet\\ncontract OracleSidechain is IOracleSidechain {\\n using Oracle for Oracle.Observation[65535];\\n\\n /// @inheritdoc IOracleSidechain\\n IOracleFactory public immutable factory;\\n\\n struct Slot0 {\\n // the current price\\n uint160 sqrtPriceX96;\\n // the current tick\\n int24 tick;\\n // the most-recently updated index of the observations array\\n uint16 observationIndex;\\n // the current maximum number of observations that are being stored\\n uint16 observationCardinality;\\n // the next maximum number of observations to store, triggered in observations.write\\n uint16 observationCardinalityNext;\\n // the current protocol fee as a percentage of the swap fee taken on withdrawal\\n // represented as an integer denominator (1/x)%\\n uint8 feeProtocol;\\n // whether the pool is locked\\n bool unlocked;\\n }\\n /// @inheritdoc IOracleSidechain\\n Slot0 public slot0;\\n\\n /// @inheritdoc IOracleSidechain\\n Oracle.Observation[65535] public observations;\\n\\n /// @inheritdoc IOracleSidechain\\n bytes32 public immutable poolSalt;\\n\\n uint24 public poolNonce;\\n /// @inheritdoc IOracleSidechain\\n address public token0;\\n /// @inheritdoc IOracleSidechain\\n address public token1;\\n /// @inheritdoc IOracleSidechain\\n uint24 public fee;\\n\\n /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests.\\n function _getBlockTimestamp() internal view virtual returns (uint32) {\\n return uint32(block.timestamp); // truncation is desired\\n }\\n\\n constructor() {\\n factory = IOracleFactory(msg.sender);\\n uint16 _cardinality;\\n (poolSalt, poolNonce, _cardinality) = factory.oracleParameters();\\n\\n slot0 = Slot0({\\n sqrtPriceX96: 0,\\n tick: 0,\\n observationIndex: _cardinality - 1,\\n observationCardinality: _cardinality,\\n observationCardinalityNext: _cardinality,\\n feeProtocol: 0,\\n unlocked: true\\n });\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external {\\n if (!slot0.unlocked) revert AI();\\n\\n (address _token0, address _token1) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);\\n if (poolSalt != keccak256(abi.encode(_token0, _token1, _fee))) revert InvalidPool();\\n\\n token0 = _token0;\\n token1 = _token1;\\n fee = _fee;\\n slot0.unlocked = false;\\n\\n emit PoolInfoInitialized(poolSalt, _token0, _token1, _fee);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsPerLiquidityCumulativeX128s)\\n {\\n return observations.observe(_getBlockTimestamp(), _secondsAgos, slot0.tick, slot0.observationIndex, 0, slot0.observationCardinality);\\n }\\n\\n /// @inheritdoc IOracleSidechain\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) {\\n if (_poolNonce != poolNonce) return false;\\n poolNonce++;\\n\\n uint256 _observationsDataLength = _observationsData.length;\\n for (uint256 _i; _i < _observationsDataLength; ) {\\n _write(_observationsData[_i]);\\n unchecked {\\n ++_i;\\n }\\n }\\n slot0.sqrtPriceX96 = TickMath.getSqrtRatioAtTick(slot0.tick);\\n\\n // emits UniV3 Swap event topic with minimal data\\n emit Swap(address(0), address(0), 0, 0, slot0.sqrtPriceX96, 0, slot0.tick);\\n return true;\\n }\\n\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external onlyFactory {\\n uint16 _observationCardinalityNextOld = slot0.observationCardinalityNext;\\n if (_observationCardinalityNext <= _observationCardinalityNextOld) revert AI();\\n slot0.observationCardinalityNext = _observationCardinalityNext;\\n emit IncreaseObservationCardinalityNext(_observationCardinalityNextOld, _observationCardinalityNext);\\n }\\n\\n function _write(ObservationData memory _observationData) private {\\n (uint16 _indexUpdated, uint16 _cardinalityUpdated) = observations.write(\\n slot0.observationIndex,\\n _observationData.blockTimestamp,\\n slot0.tick,\\n 0,\\n slot0.observationCardinality,\\n slot0.observationCardinalityNext\\n );\\n (slot0.observationIndex, slot0.observationCardinality) = (_indexUpdated, _cardinalityUpdated);\\n slot0.tick = _observationData.tick;\\n }\\n\\n modifier onlyDataReceiver() {\\n if (msg.sender != address(factory.dataReceiver())) revert OnlyDataReceiver();\\n _;\\n }\\n\\n modifier onlyFactory() {\\n if (msg.sender != address(factory)) revert OnlyFactory();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x1b830dc6ad7405f2d533e1aa8eb079853edcdf301b396ac6b1d3c41573b62787\",\"license\":\"MIT\"},\"solidity/interfaces/IDataReceiver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleFactory} from './IOracleFactory.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IBridgeReceiverAdapter} from './bridges/IBridgeReceiverAdapter.sol';\\n\\ninterface IDataReceiver is IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function oracleFactory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @notice Tracks already deployed oracles\\n /// @param _poolSalt The identifier of the oracle\\n /// @return _deployedOracle The address of the correspondant Oracle\\n function deployedOracles(bytes32 _poolSalt) external view returns (IOracleSidechain _deployedOracle);\\n\\n /// @notice Tracks the whitelisting of bridge adapters\\n /// @param _adapter Address of the bridge adapter to consult\\n /// @return _isAllowed Whether a bridge adapter is whitelisted\\n function whitelistedAdapters(IBridgeReceiverAdapter _adapter) external view returns (bool _isAllowed);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a broadcast observation is succesfully processed\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsAdded(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a broadcast observation is cached for later processing\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @return _poolNonce Nonce of the observation broadcast\\n /// @return _receiverAdapter Handler of the broadcast\\n event ObservationsCached(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter);\\n\\n /// @notice Emitted when a new adapter whitelisting rule is set\\n /// @param _adapter Address of the adapter\\n /// @param _isAllowed New whitelisting status\\n event AdapterWhitelisted(IBridgeReceiverAdapter _adapter, bool _isAllowed);\\n\\n // ERRORS\\n\\n /// @notice Thrown when the broadcast nonce is incorrect\\n error ObservationsNotWritable();\\n\\n /// @notice Thrown when a not-whitelisted adapter triggers an update\\n error UnallowedAdapter();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows whitelisted bridge adapters to push a broadcast\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _poolNonce Nonce of the observation broadcast\\n function addObservations(\\n IOracleSidechain.ObservationData[] memory _observationsData,\\n bytes32 _poolSalt,\\n uint24 _poolNonce\\n ) external;\\n\\n /// @notice Allows any address to attempt to insert cached observations\\n /// @param _poolSalt Identifier of the pool to fetch\\n /// @param _maxObservations Maximum number of observations to process\\n /// @dev Use _maxObservations = 0 to process all possible cached observations\\n function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external;\\n\\n /// @notice Allows governance to set an adapter whitelisted state\\n /// @param _receiverAdapter Address of the adapter\\n /// @param _isWhitelisted New whitelisting status\\n function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external;\\n\\n /// @notice Allows governance to batch set adapters whitelisted state\\n /// @param _receiverAdapters Array of addresses of the adapter\\n /// @param _isWhitelisted Array of whitelisting status for each address\\n function whitelistAdapters(IBridgeReceiverAdapter[] calldata _receiverAdapters, bool[] calldata _isWhitelisted) external;\\n}\\n\",\"keccak256\":\"0xd07e75380d5086ea78909bc5c80aadc110903004f50c006b0281cc090f273291\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport {IOracleSidechain} from './IOracleSidechain.sol';\\nimport {IDataReceiver} from './IDataReceiver.sol';\\n\\ninterface IOracleFactory is IGovernable {\\n // STRUCTS\\n\\n struct OracleParameters {\\n bytes32 poolSalt; // Identifier of the pool and oracle\\n uint24 poolNonce; // Initial nonce of the deployed pool\\n uint16 cardinality; // Initial cardinality of the deployed pool\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleInitCodeHash The oracle creation code hash used to calculate their address\\n //solhint-disable-next-line func-name-mixedcase\\n function ORACLE_INIT_CODE_HASH() external view returns (bytes32 _oracleInitCodeHash);\\n\\n /// @return _dataReceiver The address of the DataReceiver for the oracles to consult\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /// @return _poolSalt The id of both the oracle and the pool\\n /// @return _poolNonce The initial nonce of the pool data\\n /// @return _cardinality The size of the observations memory storage\\n function oracleParameters()\\n external\\n view\\n returns (\\n bytes32 _poolSalt,\\n uint24 _poolNonce,\\n uint16 _cardinality\\n );\\n\\n /// @return _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function initialCardinality() external view returns (uint16 _initialCardinality);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new oracle is deployed\\n /// @param _poolSalt The id of both the oracle and the pool\\n /// @param _oracle The address of the deployed oracle\\n /// @param _initialNonce The initial nonce of the pool data\\n event OracleDeployed(bytes32 indexed _poolSalt, address indexed _oracle, uint24 _initialNonce);\\n\\n /// @notice Emitted when a new DataReceiver is set\\n /// @param _dataReceiver The address of the new DataReceiver\\n event DataReceiverSet(IDataReceiver _dataReceiver);\\n\\n /// @notice Emitted when a new initial oracle cardinality is set\\n /// @param _initialCardinality The initial length of the observationCardinality array\\n event InitialCardinalitySet(uint16 _initialCardinality);\\n\\n // ERRORS\\n\\n /// @notice Thrown when a contract other than the DataReceiver tries to deploy an oracle\\n error OnlyDataReceiver();\\n\\n // FUNCTIONS\\n\\n /// @notice Deploys a new oracle given an inputted salt\\n /// @dev Requires that the salt has not been deployed before\\n /// @param _poolSalt Pool salt that deterministically binds an oracle with a pool\\n /// @return _oracle The address of the newly deployed oracle\\n function deployOracle(bytes32 _poolSalt, uint24 _poolNonce) external returns (IOracleSidechain _oracle);\\n\\n /// @notice Allows governor to set a new allowed dataReceiver\\n /// @dev Will disallow the previous dataReceiver\\n /// @param _dataReceiver The address of the new allowed dataReceiver\\n function setDataReceiver(IDataReceiver _dataReceiver) external;\\n\\n /// @notice Allows governor to set a new initial cardinality for new oracles\\n /// @param _initialCardinality The initial size of the observations memory storage for newly deployed pools\\n function setInitialCardinality(uint16 _initialCardinality) external;\\n\\n /// @notice Overrides UniV3Factory getPool mapping\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _oracle The oracle address\\n function getPool(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (IOracleSidechain _oracle);\\n\\n /// @notice Tracks the addresses of the oracle by poolSalt\\n /// @param _poolSalt Identifier of both the pool and the oracle\\n /// @return _oracle The address (if deployed) of the correspondant oracle\\n function getPool(bytes32 _poolSalt) external view returns (IOracleSidechain _oracle);\\n\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n /// @return _poolSalt Pool salt for inquired parameters\\n function getPoolSalt(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external view returns (bytes32 _poolSalt);\\n}\\n\",\"keccak256\":\"0xc32bfc32a274923ce1a089acc024396e702ae354773f0ac0a683e43ded904954\",\"license\":\"MIT\"},\"solidity/interfaces/IOracleSidechain.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IOracleFactory} from './IOracleFactory.sol';\\n\\ninterface IOracleSidechain {\\n // STRUCTS\\n\\n struct ObservationData {\\n uint32 blockTimestamp;\\n int24 tick;\\n }\\n\\n // STATE VARIABLES\\n\\n /// @return _oracleFactory The address of the OracleFactory\\n function factory() external view returns (IOracleFactory _oracleFactory);\\n\\n /// @return _token0 The mainnet address of the Token0 of the oracle\\n function token0() external view returns (address _token0);\\n\\n /// @return _token1 The mainnet address of the Token1 of the oracle\\n function token1() external view returns (address _token1);\\n\\n /// @return _fee The fee identifier of the pool\\n function fee() external view returns (uint24 _fee);\\n\\n /// @return _poolSalt The identifier of both the pool and the oracle\\n function poolSalt() external view returns (bytes32 _poolSalt);\\n\\n /// @return _poolNonce Last recorded nonce of the pool history\\n function poolNonce() external view returns (uint24 _poolNonce);\\n\\n /// @notice Replicates the UniV3Pool slot0 behaviour (semi-compatible)\\n /// @return _sqrtPriceX96 Used to maintain compatibility with Uniswap V3\\n /// @return _tick Used to maintain compatibility with Uniswap V3\\n /// @return _observationIndex The index of the last oracle observation that was written,\\n /// @return _observationCardinality The current maximum number of observations stored in the pool,\\n /// @return _observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// @return _feeProtocol Used to maintain compatibility with Uniswap V3\\n /// @return _unlocked Used to track if a pool information was already verified\\n function slot0()\\n external\\n view\\n returns (\\n uint160 _sqrtPriceX96,\\n int24 _tick,\\n uint16 _observationIndex,\\n uint16 _observationCardinality,\\n uint16 _observationCardinalityNext,\\n uint8 _feeProtocol,\\n bool _unlocked\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param _index The element of the observations array to fetch\\n /// @return _blockTimestamp The timestamp of the observation,\\n /// @return _tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// @return _secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// @return _initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 _index)\\n external\\n view\\n returns (\\n uint32 _blockTimestamp,\\n int56 _tickCumulative,\\n uint160 _secondsPerLiquidityCumulativeX128,\\n bool _initialized\\n );\\n\\n // EVENTS\\n\\n /// @notice Emitted when the pool information is verified\\n /// @param _poolSalt Identifier of the pool and the oracle\\n /// @param _token0 The contract address of either token0 or token1\\n /// @param _token1 The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n event PoolInfoInitialized(bytes32 indexed _poolSalt, address _token0, address _token1, uint24 _fee);\\n\\n /// @notice Emitted by the oracle to hint indexers that the pool state has changed\\n /// @dev Imported from IUniswapV3PoolEvents (semi-compatible)\\n /// @param _sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param _tick The log base 1.0001 of price of the pool after the swap\\n event Swap(address indexed, address indexed, int256, int256, uint160 _sqrtPriceX96, uint128, int24 _tick);\\n\\n /// @notice Emitted by the oracle for increases to the number of observations that can be stored\\n /// @dev Imported from IUniswapV3PoolEvents (fully-compatible)\\n /// @param _observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param _observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(uint16 _observationCardinalityNextOld, uint16 _observationCardinalityNextNew);\\n\\n // ERRORS\\n\\n /// @notice Thrown if the pool info is already initialized or if the observationCardinalityNext is already increased\\n error AI();\\n\\n /// @notice Thrown if the pool info does not correspond to the pool salt\\n error InvalidPool();\\n\\n /// @notice Thrown if the DataReceiver contract is not the one calling for writing observations\\n error OnlyDataReceiver();\\n\\n /// @notice Thrown if the OracleFactory contract is not the one calling for increasing observationCardinalityNext\\n error OnlyFactory();\\n\\n // FUNCTIONS\\n\\n /// @notice Permisionless method to verify token0, token1 and fee\\n /// @dev Before verified, token0 and token1 views will return address(0)\\n /// @param _tokenA The contract address of either token0 or token1\\n /// @param _tokenB The contract address of the other token\\n /// @param _fee The fee denominated in hundredths of a bip\\n function initializePoolInfo(\\n address _tokenA,\\n address _tokenB,\\n uint24 _fee\\n ) external;\\n\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev Imported from UniV3Pool (semi compatible, optimistically extrapolates)\\n /// @param _secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return _tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return _secondsCumulativeX128s Cumulative seconds as of each `secondsAgos` from the current block timestamp\\n function observe(uint32[] calldata _secondsAgos)\\n external\\n view\\n returns (int56[] memory _tickCumulatives, uint160[] memory _secondsCumulativeX128s);\\n\\n /// @notice Permisioned method to push a dataset to update\\n /// @param _observationsData Array of tuples containing the dataset\\n /// @param _poolNonce Nonce of the observation broadcast\\n function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external returns (bool _written);\\n\\n /// @notice Permisioned method to increase the cardinalityNext value\\n /// @param _observationCardinalityNext The new next length of the observations array\\n function increaseObservationCardinalityNext(uint16 _observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa90206e3de00ad866b7f4792ce29220ee0ca561d59629ba638a31c4d6fd3941b\",\"license\":\"MIT\"},\"solidity/interfaces/bridges/IBridgeReceiverAdapter.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport {IDataReceiver} from '../IDataReceiver.sol';\\nimport {IOracleSidechain} from '../IOracleSidechain.sol';\\n\\ninterface IBridgeReceiverAdapter is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @notice Gets the address of the DataReceiver contract\\n /// @return _dataReceiver Address of the DataReceiver contract\\n function dataReceiver() external view returns (IDataReceiver _dataReceiver);\\n\\n /* NOTE: callback methods should be here declared */\\n}\\n\",\"keccak256\":\"0x49e5c9c6a28521933a3f2b01a529fbae9aac1edd71dbe904586a2f06148b1974\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040526005805461ffff1916609017905534801561001e57600080fd5b5060405161278638038061278683398101604081905261003d91610128565b816001600160a01b0381166100655760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b039290921691909117905561008e81610095565b5050610162565b6001600160a01b0381166100bc5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be9060200160405180910390a150565b6001600160a01b038116811461012557600080fd5b50565b6000806040838503121561013b57600080fd5b825161014681610110565b602084015190925061015781610110565b809150509250929050565b612615806101716000396000f3fe60806040523480156200001157600080fd5b5060043610620001095760003560e01c806391a0b97911620000a3578063e8047788116200006e578063e80477881462000247578063ebaa56aa146200025b578063f235757f146200027e578063f6c00927146200029557600080fd5b806391a0b97914620001cd57806397862d6d14620001d757806399df712014620001ee578063e3056a34146200023357600080fd5b80631698ee8211620000e45780631698ee8214620001625780633c1a17ff14620001795780635cc1fd36146200019f57806384b6db1414620001b657600080fd5b806307d5851a146200010e5780630c340a24146200012757806313f6986d1462000158575b600080fd5b620001256200011f36600462000892565b620002ac565b005b6000546200013b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b62000125620002e6565b6200013b62000173366004620008cd565b6200031e565b620001906200018a366004620008cd565b62000344565b6040519081526020016200014f565b6200013b620001b03660046200091b565b620003bf565b62000125620001c73660046200095d565b620004c8565b6200019062000568565b62000125620001e836600462000983565b62000597565b6003546004546200020f919062ffffff8116906301000000900461ffff1683565b6040805193845262ffffff909216602084015261ffff16908201526060016200014f565b6001546200013b906001600160a01b031681565b6002546200013b906001600160a01b031681565b6005546200026a9061ffff1681565b60405161ffff90911681526020016200014f565b620001256200028f36600462000892565b62000634565b6200013b620002a6366004620009a1565b6200066b565b6000546001600160a01b03163314620002d85760405163070545c960e51b815260040160405180910390fd5b620002e38162000714565b50565b6001546001600160a01b031633146200031257604051639ba0305d60e01b815260040160405180910390fd5b6200031c6200078b565b565b6000806200032e85858562000344565b90506200033b816200066b565b95945050505050565b6000806000846001600160a01b0316866001600160a01b0316106200036b5784866200036e565b85855b604080516001600160a01b03808516602083015283169181019190915262ffffff87166060820152919350915060800160405160208183030381529060405280519060200120925050509392505050565b6002546000906001600160a01b03163314620003ee57604051638e5b30cb60e01b815260040160405180910390fd5b6040805160608101825284815262ffffff84166020820181905260055461ffff1691830182905260038690556004805464ffffffffff1916909117630100000090920291909117905551839062000445906200086e565b8190604051809103906000f590508015801562000466573d6000803e3d6000fd5b5060006003556004805464ffffffffff1916905560405162ffffff841681529091506001600160a01b0382169084907f5b7d803564bd9c17d971ee338d1e9ffafd2aa0a8dbd7065f9d3900ecf7a842149060200160405180910390a392915050565b6000546001600160a01b03163314620004f45760405163070545c960e51b815260040160405180910390fd5b600062000501836200066b565b6040516332148f6760e01b815261ffff841660048201529091506001600160a01b038216906332148f6790602401600060405180830381600087803b1580156200054a57600080fd5b505af11580156200055f573d6000803e3d6000fd5b50505050505050565b60405162000579602082016200086e565b6020820181038252601f19601f820116604052508051906020012081565b6000546001600160a01b03163314620005c35760405163070545c960e51b815260040160405180910390fd5b8061ffff16600003620005e957604051631f2a200560e01b815260040160405180910390fd5b6005805461ffff191661ffff83169081179091556040519081527fec9fa937c26cb048aac5fc5992eaace52f38cd13c8da22f42630090bd258261f906020015b60405180910390a150565b6000546001600160a01b03163314620006605760405163070545c960e51b815260040160405180910390fd5b620002e381620007e9565b6000620006f230836040518060200162000685906200086e565b601f1982820381018352601f90910116604081815282516020938401206001600160f81b03198385015260609590951b6bffffffffffffffffffffffff19166021830152603582019390935260558082019490945282518082039094018452607501909152815191012090565b9050806001600160a01b03163b6000036200070f57506000919050565b919050565b6001600160a01b0381166200073c5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be9060200162000629565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6001600160a01b038116620008115760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910162000629565b611c2480620009bc83390190565b6001600160a01b0381168114620002e357600080fd5b600060208284031215620008a557600080fd5b8135620008b2816200087c565b9392505050565b803562ffffff811681146200070f57600080fd5b600080600060608486031215620008e357600080fd5b8335620008f0816200087c565b9250602084013562000902816200087c565b91506200091260408501620008b9565b90509250925092565b600080604083850312156200092f57600080fd5b823591506200094160208401620008b9565b90509250929050565b803561ffff811681146200070f57600080fd5b600080604083850312156200097157600080fd5b8235915062000941602084016200094a565b6000602082840312156200099657600080fd5b620008b2826200094a565b600060208284031215620009b457600080fd5b503591905056fe60c06040523480156200001157600080fd5b50336080819052604080516304cefb8960e51b81529051600092916399df71209160048083019260609291908290030181865afa15801562000057573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200007d9190620001bb565b62010000805462ffffff191662ffffff939093169290921790915560a0919091526040805160e081018252600080825260208201529192508101620000c460018462000210565b61ffff90811682529283166020808301829052604080840192909252600060608085018290526001608095860152855182549387015194870151918701519587015160a088015160c0909801511515600160f01b0260ff60f01b1960ff99909916600160e81b0260ff60e81b19928b16600160d81b029290921662ffffff60d81b19988b16600160c81b0261ffff60c81b1995909b16600160b81b029490941663ffffffff60b81b1962ffffff909816600160a01b026001600160b81b03199097166001600160a01b0390941693909317959095179590951617969096179390931694909417179190911691909117905562000242565b600080600060608486031215620001d157600080fd5b83519250602084015162ffffff81168114620001ec57600080fd5b604085015190925061ffff811681146200020557600080fd5b809150509250925092565b600061ffff838116908316818110156200023a57634e487b7160e01b600052601160045260246000fd5b039392505050565b60805160a0516119a0620002846000396000818161027a01528181610694015261074b0152600081816102af01528181610302015261052b01526119a06000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063883bdbfd11610071578063883bdbfd1461022f5780639fdbd4d714610250578063c1c9115a14610275578063c45a0155146102aa578063d21220a7146102d1578063ddca3f43146102e657600080fd5b80630dfe1681146100b957806323e512d4146100f2578063252c09d71461011557806332148f67146101625780633453952f146101775780633850c7bd1461018a575b600080fd5b62010000546100d590630100000090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610105610100366004611658565b6102fe565b60405190151581526020016100e9565b610128610123366004611759565b6104db565b6040805163ffffffff909516855260069390930b60208501526001600160a01b0390911691830191909152151560608201526080016100e9565b610175610170366004611772565b610520565b005b6101756101853660046117ae565b6105fc565b6000546101de906001600160a01b03811690600160a01b810460020b9061ffff600160b81b8204811691600160c81b8104821691600160d81b8204169060ff600160e81b8204811691600160f01b90041687565b604080516001600160a01b03909816885260029690960b602088015261ffff94851695870195909552918316606086015291909116608084015260ff1660a0830152151560c082015260e0016100e9565b61024261023d3660046117f5565b61079f565b6040516100e992919061186a565b62010000546102619062ffffff1681565b60405162ffffff90911681526020016100e9565b61029c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100e9565b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b62010001546100d5906001600160a01b031681565b620100015461026190600160a01b900462ffffff1681565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e80477886040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038291906118f1565b6001600160a01b0316336001600160a01b0316146103b357604051638e5b30cb60e01b815260040160405180910390fd5b620100005462ffffff8381169116146103ce575060006104d5565b62010000805462ffffff169060006103e58361190e565b91906101000a81548162ffffff021916908362ffffff1602179055505060008351905060005b8181101561043d576104358582815181106104285761042861193e565b6020026020010151610810565b60010161040b565b5060005461045490600160a01b900460020b6108b0565b600080546001600160a01b0319166001600160a01b039290921691821780825560408051838152602081018490529081019390935260608301829052600160a01b900460020b60808301529081907fc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca679060a00160405180910390a360019150505b92915050565b60018161ffff81106104ec57600080fd5b015463ffffffff81169150600160201b810460060b90600160581b81046001600160a01b031690600160f81b900460ff1684565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461056957604051630636a15760e11b815260040160405180910390fd5b60005461ffff600160d81b9091048116908216811061059b5760405163139816ff60e31b815260040160405180910390fd5b6000805461ffff60d81b1916600160d81b61ffff8581169182029290921790925560408051918416825260208201929092527fac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a910160405180910390a15050565b600054600160f01b900460ff166106265760405163139816ff60e31b815260040160405180910390fd5b600080836001600160a01b0316856001600160a01b03161061064957838561064c565b84845b604080516001600160a01b03808516602083015283169181019190915262ffffff861660608201529193509150608001604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000146106d05760405162820f3560e61b815260040160405180910390fd5b6201000080546301000000600160b81b03191663010000006001600160a01b03858116918202929092179092556201000180549184166001600160b81b03199092168217600160a01b62ffffff8816908102919091179091556000805460ff60f01b19169055604080519384526020840192909252908201527f0000000000000000000000000000000000000000000000000000000000000000907fb50ab96cf9f83d6c076a0d2a6e27a65bf1242920ba414829aa618d57d4a263739060600160405180910390a25050505050565b6060806108054285858080602002602001604051908101604052809392919081815260200183836020028082843760009201829052508054600196959450600160a01b810460020b935061ffff600160b81b820481169350600160c81b90910416610bd2565b915091509250929050565b60008054825182916108529160019161ffff600160b81b820481169291600160a01b810460020b918791600160c81b8104821691600160d81b90910416610d1d565b600080546020969096015163ffffffff60b81b19909616600160c81b61ffff9384160261ffff60b81b191617600160b81b93909216929092021762ffffff60a01b1916600160a01b62ffffff90951694909402939093179092555050565b60008060008360020b126108c7578260020b6108cf565b8260020b6000035b9050620d89e88111156108f5576040516315e4079d60e11b815260040160405180910390fd5b60008160011660000361090c57600160801b61091e565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615610952576ffff97272373d413259a46990580e213a0260801c5b6004821615610971576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610990576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b60108216156109af576fffcb9843d60f6159c9db58835c9266440260801c5b60208216156109ce576fff973b41fa98c081472e6896dfb254c00260801c5b60408216156109ed576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610a0c576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610a2c576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610a4c576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610a6c576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610a8c576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610aac576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610acc576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610aec576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610b0c576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610b2d576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610b4d576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610b6c576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610b89576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610baa578060001981610ba657610ba6611954565b0490505b600160201b810615610bbd576001610bc0565b60005b60ff16602082901c0192505050919050565b60608060008361ffff1611610bfa57604051636b93000360e11b815260040160405180910390fd5b865167ffffffffffffffff811115610c1457610c146115d0565b604051908082528060200260200182016040528015610c3d578160200160208202803683370190505b509150865167ffffffffffffffff811115610c5a57610c5a6115d0565b604051908082528060200260200182016040528015610c83578160200160208202803683370190505b50905060005b8751811015610d1057610cba8a8a8a8481518110610ca957610ca961193e565b60200260200101518a8a8a8a610ea5565b848381518110610ccc57610ccc61193e565b60200260200101848481518110610ce557610ce561193e565b6001600160a01b039093166020938402919091019092019190915260069190910b9052600101610c89565b5097509795505050505050565b6000806000898961ffff1661ffff8110610d3957610d3961193e565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff161515606083015290925089169003610da25788859250925050610e99565b8461ffff168461ffff16118015610dc357506001850361ffff168961ffff16145b15610dd057839150610dd4565b8491505b8161ffff168960010161ffff1681610dee57610dee611954565b069250610dfd81898989611054565b8a8461ffff1661ffff8110610e1457610e1461193e565b825191018054602084015160408501516060909501511515600160f81b026001600160f81b036001600160a01b03909616600160581b02959095166affffffffffffffffffffff66ffffffffffffff909216600160201b026affffffffffffffffffffff1990931663ffffffff90951694909417919091171691909117919091179055505b97509795505050505050565b6000808663ffffffff16600003610f4e576000898661ffff1661ffff8110610ecf57610ecf61193e565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff16151560608301529092508a1614610f3a57610f37818a8988611054565b90505b806020015181604001519250925050610e99565b868803600080610f638c8c858c8c8c8c611119565b91509150816000015163ffffffff168363ffffffff1603610f94578160200151826040015194509450505050610e99565b806000015163ffffffff168363ffffffff1603610fc1578060200151816040015194509450505050610e99565b60008260000151826000015103905060008360000151850390508063ffffffff168263ffffffff1660060b856020015185602001510360060b8161100757611007611954565b05028460200151018263ffffffff168263ffffffff1686604001518660400151036001600160a01b0316028161103f5761103f611954565b04856040015101965096505050505050610e99565b604080516080810182526000808252602082018190529181018290526060810191909152600085600001518503905060405180608001604052808663ffffffff1681526020018263ffffffff168660020b0288602001510160060b81526020016000856001600160801b0316116110cc5760016110ce565b845b6001600160801b031663ffffffff60801b608085901b16816110f2576110f2611954565b048860400151016001600160a01b0316815260200160011515815250915050949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152888561ffff1661ffff81106111785761117861193e565b60408051608081018252919092015463ffffffff8116808352600160201b820460060b6020840152600160581b82046001600160a01b031693830193909352600160f81b900460ff161515606082015292506111d690899089611325565b1561120257815163ffffffff888116911614610e9957816111f983898988611054565b91509150610e99565b888361ffff168660010161ffff168161121d5761121d611954565b0661ffff1661ffff81106112335761123361193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529092506112dc57604080516080810182528a5463ffffffff81168252600160201b810460060b6020830152600160581b81046001600160a01b031692820192909252600160f81b90910460ff161515606082015291505b6112eb88836000015189611325565b611308576040516327e8e87560e01b815260040160405180910390fd5b61131589898988876113e8565b9150915097509795505050505050565b60008363ffffffff168363ffffffff161115801561134f57508363ffffffff168263ffffffff1611155b1561136b578163ffffffff168363ffffffff16111590506113e1565b60008463ffffffff168463ffffffff1611611392578363ffffffff16600160201b0161139a565b8363ffffffff165b64ffffffffff16905060008563ffffffff168463ffffffff16116113ca578363ffffffff16600160201b016113d2565b8363ffffffff165b64ffffffffff16909111159150505b9392505050565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260008361ffff168560010161ffff168161144c5761144c611954565b0661ffff169050600060018561ffff16830103905060005b506002818301048961ffff8716828161147f5761147f611954565b0661ffff81106114915761149161193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529095506114f557806001019250611464565b898661ffff16826001018161150c5761150c611954565b0661ffff811061151e5761151e61193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b90910416151560608201528551909450600090611582908b908b611325565b905080801561159b575061159b8a8a8760000151611325565b156115a657506115c3565b806115b6576001820392506115bd565b8160010193505b50611464565b5050509550959350505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611609576116096115d0565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611638576116386115d0565b604052919050565b803562ffffff8116811461165357600080fd5b919050565b600080604080848603121561166c57600080fd5b833567ffffffffffffffff8082111561168457600080fd5b818601915086601f83011261169857600080fd5b81356020828211156116ac576116ac6115d0565b6116ba818360051b0161160f565b828152818101935060069290921b8401810191898311156116da57600080fd5b938101935b8285101561173e5785858b0312156116f75760008081fd5b6116ff6115e6565b853563ffffffff811681146117145760008081fd5b815285830135600281900b811461172b5760008081fd5b81840152845293850193928101926116df565b965061174b888201611640565b955050505050509250929050565b60006020828403121561176b57600080fd5b5035919050565b60006020828403121561178457600080fd5b813561ffff811681146113e157600080fd5b6001600160a01b03811681146117ab57600080fd5b50565b6000806000606084860312156117c357600080fd5b83356117ce81611796565b925060208401356117de81611796565b91506117ec60408501611640565b90509250925092565b6000806020838503121561180857600080fd5b823567ffffffffffffffff8082111561182057600080fd5b818501915085601f83011261183457600080fd5b81358181111561184357600080fd5b8660208260051b850101111561185857600080fd5b60209290920196919550909350505050565b604080825283519082018190526000906020906060840190828701845b828110156118a657815160060b84529284019290840190600101611887565b5050508381038285015284518082528583019183019060005b818110156118e45783516001600160a01b0316835292840192918401916001016118bf565b5090979650505050505050565b60006020828403121561190357600080fd5b81516113e181611796565b600062ffffff80831681810361193457634e487b7160e01b600052601160045260246000fd5b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fdfea264697066735822122048903427db1b98c0cd97b26ab800e55a51c8b5b98cd5a363f22490c0ac241d1b64736f6c634300080f0033a2646970667358221220c1e84aa1e8d7c1251c18a95b48835b3934b1d40ccda3e8d1ccc7bd7d096c898964736f6c634300080f0033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620001095760003560e01c806391a0b97911620000a3578063e8047788116200006e578063e80477881462000247578063ebaa56aa146200025b578063f235757f146200027e578063f6c00927146200029557600080fd5b806391a0b97914620001cd57806397862d6d14620001d757806399df712014620001ee578063e3056a34146200023357600080fd5b80631698ee8211620000e45780631698ee8214620001625780633c1a17ff14620001795780635cc1fd36146200019f57806384b6db1414620001b657600080fd5b806307d5851a146200010e5780630c340a24146200012757806313f6986d1462000158575b600080fd5b620001256200011f36600462000892565b620002ac565b005b6000546200013b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b62000125620002e6565b6200013b62000173366004620008cd565b6200031e565b620001906200018a366004620008cd565b62000344565b6040519081526020016200014f565b6200013b620001b03660046200091b565b620003bf565b62000125620001c73660046200095d565b620004c8565b6200019062000568565b62000125620001e836600462000983565b62000597565b6003546004546200020f919062ffffff8116906301000000900461ffff1683565b6040805193845262ffffff909216602084015261ffff16908201526060016200014f565b6001546200013b906001600160a01b031681565b6002546200013b906001600160a01b031681565b6005546200026a9061ffff1681565b60405161ffff90911681526020016200014f565b620001256200028f36600462000892565b62000634565b6200013b620002a6366004620009a1565b6200066b565b6000546001600160a01b03163314620002d85760405163070545c960e51b815260040160405180910390fd5b620002e38162000714565b50565b6001546001600160a01b031633146200031257604051639ba0305d60e01b815260040160405180910390fd5b6200031c6200078b565b565b6000806200032e85858562000344565b90506200033b816200066b565b95945050505050565b6000806000846001600160a01b0316866001600160a01b0316106200036b5784866200036e565b85855b604080516001600160a01b03808516602083015283169181019190915262ffffff87166060820152919350915060800160405160208183030381529060405280519060200120925050509392505050565b6002546000906001600160a01b03163314620003ee57604051638e5b30cb60e01b815260040160405180910390fd5b6040805160608101825284815262ffffff84166020820181905260055461ffff1691830182905260038690556004805464ffffffffff1916909117630100000090920291909117905551839062000445906200086e565b8190604051809103906000f590508015801562000466573d6000803e3d6000fd5b5060006003556004805464ffffffffff1916905560405162ffffff841681529091506001600160a01b0382169084907f5b7d803564bd9c17d971ee338d1e9ffafd2aa0a8dbd7065f9d3900ecf7a842149060200160405180910390a392915050565b6000546001600160a01b03163314620004f45760405163070545c960e51b815260040160405180910390fd5b600062000501836200066b565b6040516332148f6760e01b815261ffff841660048201529091506001600160a01b038216906332148f6790602401600060405180830381600087803b1580156200054a57600080fd5b505af11580156200055f573d6000803e3d6000fd5b50505050505050565b60405162000579602082016200086e565b6020820181038252601f19601f820116604052508051906020012081565b6000546001600160a01b03163314620005c35760405163070545c960e51b815260040160405180910390fd5b8061ffff16600003620005e957604051631f2a200560e01b815260040160405180910390fd5b6005805461ffff191661ffff83169081179091556040519081527fec9fa937c26cb048aac5fc5992eaace52f38cd13c8da22f42630090bd258261f906020015b60405180910390a150565b6000546001600160a01b03163314620006605760405163070545c960e51b815260040160405180910390fd5b620002e381620007e9565b6000620006f230836040518060200162000685906200086e565b601f1982820381018352601f90910116604081815282516020938401206001600160f81b03198385015260609590951b6bffffffffffffffffffffffff19166021830152603582019390935260558082019490945282518082039094018452607501909152815191012090565b9050806001600160a01b03163b6000036200070f57506000919050565b919050565b6001600160a01b0381166200073c5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f23ab7a40fedc3062f72fa590994df2ec8e49b54309a22df0ad3790dbc56346be9060200162000629565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6001600160a01b038116620008115760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec910162000629565b611c2480620009bc83390190565b6001600160a01b0381168114620002e357600080fd5b600060208284031215620008a557600080fd5b8135620008b2816200087c565b9392505050565b803562ffffff811681146200070f57600080fd5b600080600060608486031215620008e357600080fd5b8335620008f0816200087c565b9250602084013562000902816200087c565b91506200091260408501620008b9565b90509250925092565b600080604083850312156200092f57600080fd5b823591506200094160208401620008b9565b90509250929050565b803561ffff811681146200070f57600080fd5b600080604083850312156200097157600080fd5b8235915062000941602084016200094a565b6000602082840312156200099657600080fd5b620008b2826200094a565b600060208284031215620009b457600080fd5b503591905056fe60c06040523480156200001157600080fd5b50336080819052604080516304cefb8960e51b81529051600092916399df71209160048083019260609291908290030181865afa15801562000057573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200007d9190620001bb565b62010000805462ffffff191662ffffff939093169290921790915560a0919091526040805160e081018252600080825260208201529192508101620000c460018462000210565b61ffff90811682529283166020808301829052604080840192909252600060608085018290526001608095860152855182549387015194870151918701519587015160a088015160c0909801511515600160f01b0260ff60f01b1960ff99909916600160e81b0260ff60e81b19928b16600160d81b029290921662ffffff60d81b19988b16600160c81b0261ffff60c81b1995909b16600160b81b029490941663ffffffff60b81b1962ffffff909816600160a01b026001600160b81b03199097166001600160a01b0390941693909317959095179590951617969096179390931694909417179190911691909117905562000242565b600080600060608486031215620001d157600080fd5b83519250602084015162ffffff81168114620001ec57600080fd5b604085015190925061ffff811681146200020557600080fd5b809150509250925092565b600061ffff838116908316818110156200023a57634e487b7160e01b600052601160045260246000fd5b039392505050565b60805160a0516119a0620002846000396000818161027a01528181610694015261074b0152600081816102af01528181610302015261052b01526119a06000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063883bdbfd11610071578063883bdbfd1461022f5780639fdbd4d714610250578063c1c9115a14610275578063c45a0155146102aa578063d21220a7146102d1578063ddca3f43146102e657600080fd5b80630dfe1681146100b957806323e512d4146100f2578063252c09d71461011557806332148f67146101625780633453952f146101775780633850c7bd1461018a575b600080fd5b62010000546100d590630100000090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610105610100366004611658565b6102fe565b60405190151581526020016100e9565b610128610123366004611759565b6104db565b6040805163ffffffff909516855260069390930b60208501526001600160a01b0390911691830191909152151560608201526080016100e9565b610175610170366004611772565b610520565b005b6101756101853660046117ae565b6105fc565b6000546101de906001600160a01b03811690600160a01b810460020b9061ffff600160b81b8204811691600160c81b8104821691600160d81b8204169060ff600160e81b8204811691600160f01b90041687565b604080516001600160a01b03909816885260029690960b602088015261ffff94851695870195909552918316606086015291909116608084015260ff1660a0830152151560c082015260e0016100e9565b61024261023d3660046117f5565b61079f565b6040516100e992919061186a565b62010000546102619062ffffff1681565b60405162ffffff90911681526020016100e9565b61029c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100e9565b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b62010001546100d5906001600160a01b031681565b620100015461026190600160a01b900462ffffff1681565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e80477886040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038291906118f1565b6001600160a01b0316336001600160a01b0316146103b357604051638e5b30cb60e01b815260040160405180910390fd5b620100005462ffffff8381169116146103ce575060006104d5565b62010000805462ffffff169060006103e58361190e565b91906101000a81548162ffffff021916908362ffffff1602179055505060008351905060005b8181101561043d576104358582815181106104285761042861193e565b6020026020010151610810565b60010161040b565b5060005461045490600160a01b900460020b6108b0565b600080546001600160a01b0319166001600160a01b039290921691821780825560408051838152602081018490529081019390935260608301829052600160a01b900460020b60808301529081907fc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca679060a00160405180910390a360019150505b92915050565b60018161ffff81106104ec57600080fd5b015463ffffffff81169150600160201b810460060b90600160581b81046001600160a01b031690600160f81b900460ff1684565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461056957604051630636a15760e11b815260040160405180910390fd5b60005461ffff600160d81b9091048116908216811061059b5760405163139816ff60e31b815260040160405180910390fd5b6000805461ffff60d81b1916600160d81b61ffff8581169182029290921790925560408051918416825260208201929092527fac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a910160405180910390a15050565b600054600160f01b900460ff166106265760405163139816ff60e31b815260040160405180910390fd5b600080836001600160a01b0316856001600160a01b03161061064957838561064c565b84845b604080516001600160a01b03808516602083015283169181019190915262ffffff861660608201529193509150608001604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000146106d05760405162820f3560e61b815260040160405180910390fd5b6201000080546301000000600160b81b03191663010000006001600160a01b03858116918202929092179092556201000180549184166001600160b81b03199092168217600160a01b62ffffff8816908102919091179091556000805460ff60f01b19169055604080519384526020840192909252908201527f0000000000000000000000000000000000000000000000000000000000000000907fb50ab96cf9f83d6c076a0d2a6e27a65bf1242920ba414829aa618d57d4a263739060600160405180910390a25050505050565b6060806108054285858080602002602001604051908101604052809392919081815260200183836020028082843760009201829052508054600196959450600160a01b810460020b935061ffff600160b81b820481169350600160c81b90910416610bd2565b915091509250929050565b60008054825182916108529160019161ffff600160b81b820481169291600160a01b810460020b918791600160c81b8104821691600160d81b90910416610d1d565b600080546020969096015163ffffffff60b81b19909616600160c81b61ffff9384160261ffff60b81b191617600160b81b93909216929092021762ffffff60a01b1916600160a01b62ffffff90951694909402939093179092555050565b60008060008360020b126108c7578260020b6108cf565b8260020b6000035b9050620d89e88111156108f5576040516315e4079d60e11b815260040160405180910390fd5b60008160011660000361090c57600160801b61091e565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615610952576ffff97272373d413259a46990580e213a0260801c5b6004821615610971576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610990576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b60108216156109af576fffcb9843d60f6159c9db58835c9266440260801c5b60208216156109ce576fff973b41fa98c081472e6896dfb254c00260801c5b60408216156109ed576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610a0c576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610a2c576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610a4c576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610a6c576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610a8c576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610aac576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610acc576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610aec576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610b0c576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610b2d576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610b4d576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610b6c576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610b89576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610baa578060001981610ba657610ba6611954565b0490505b600160201b810615610bbd576001610bc0565b60005b60ff16602082901c0192505050919050565b60608060008361ffff1611610bfa57604051636b93000360e11b815260040160405180910390fd5b865167ffffffffffffffff811115610c1457610c146115d0565b604051908082528060200260200182016040528015610c3d578160200160208202803683370190505b509150865167ffffffffffffffff811115610c5a57610c5a6115d0565b604051908082528060200260200182016040528015610c83578160200160208202803683370190505b50905060005b8751811015610d1057610cba8a8a8a8481518110610ca957610ca961193e565b60200260200101518a8a8a8a610ea5565b848381518110610ccc57610ccc61193e565b60200260200101848481518110610ce557610ce561193e565b6001600160a01b039093166020938402919091019092019190915260069190910b9052600101610c89565b5097509795505050505050565b6000806000898961ffff1661ffff8110610d3957610d3961193e565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff161515606083015290925089169003610da25788859250925050610e99565b8461ffff168461ffff16118015610dc357506001850361ffff168961ffff16145b15610dd057839150610dd4565b8491505b8161ffff168960010161ffff1681610dee57610dee611954565b069250610dfd81898989611054565b8a8461ffff1661ffff8110610e1457610e1461193e565b825191018054602084015160408501516060909501511515600160f81b026001600160f81b036001600160a01b03909616600160581b02959095166affffffffffffffffffffff66ffffffffffffff909216600160201b026affffffffffffffffffffff1990931663ffffffff90951694909417919091171691909117919091179055505b97509795505050505050565b6000808663ffffffff16600003610f4e576000898661ffff1661ffff8110610ecf57610ecf61193e565b60408051608081018252919092015463ffffffff808216808452600160201b830460060b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff16151560608301529092508a1614610f3a57610f37818a8988611054565b90505b806020015181604001519250925050610e99565b868803600080610f638c8c858c8c8c8c611119565b91509150816000015163ffffffff168363ffffffff1603610f94578160200151826040015194509450505050610e99565b806000015163ffffffff168363ffffffff1603610fc1578060200151816040015194509450505050610e99565b60008260000151826000015103905060008360000151850390508063ffffffff168263ffffffff1660060b856020015185602001510360060b8161100757611007611954565b05028460200151018263ffffffff168263ffffffff1686604001518660400151036001600160a01b0316028161103f5761103f611954565b04856040015101965096505050505050610e99565b604080516080810182526000808252602082018190529181018290526060810191909152600085600001518503905060405180608001604052808663ffffffff1681526020018263ffffffff168660020b0288602001510160060b81526020016000856001600160801b0316116110cc5760016110ce565b845b6001600160801b031663ffffffff60801b608085901b16816110f2576110f2611954565b048860400151016001600160a01b0316815260200160011515815250915050949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152888561ffff1661ffff81106111785761117861193e565b60408051608081018252919092015463ffffffff8116808352600160201b820460060b6020840152600160581b82046001600160a01b031693830193909352600160f81b900460ff161515606082015292506111d690899089611325565b1561120257815163ffffffff888116911614610e9957816111f983898988611054565b91509150610e99565b888361ffff168660010161ffff168161121d5761121d611954565b0661ffff1661ffff81106112335761123361193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529092506112dc57604080516080810182528a5463ffffffff81168252600160201b810460060b6020830152600160581b81046001600160a01b031692820192909252600160f81b90910460ff161515606082015291505b6112eb88836000015189611325565b611308576040516327e8e87560e01b815260040160405180910390fd5b61131589898988876113e8565b9150915097509795505050505050565b60008363ffffffff168363ffffffff161115801561134f57508363ffffffff168263ffffffff1611155b1561136b578163ffffffff168363ffffffff16111590506113e1565b60008463ffffffff168463ffffffff1611611392578363ffffffff16600160201b0161139a565b8363ffffffff165b64ffffffffff16905060008563ffffffff168463ffffffff16116113ca578363ffffffff16600160201b016113d2565b8363ffffffff165b64ffffffffff16909111159150505b9392505050565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260008361ffff168560010161ffff168161144c5761144c611954565b0661ffff169050600060018561ffff16830103905060005b506002818301048961ffff8716828161147f5761147f611954565b0661ffff81106114915761149161193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082018190529095506114f557806001019250611464565b898661ffff16826001018161150c5761150c611954565b0661ffff811061151e5761151e61193e565b60408051608081018252929091015463ffffffff81168352600160201b810460060b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b90910416151560608201528551909450600090611582908b908b611325565b905080801561159b575061159b8a8a8760000151611325565b156115a657506115c3565b806115b6576001820392506115bd565b8160010193505b50611464565b5050509550959350505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611609576116096115d0565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611638576116386115d0565b604052919050565b803562ffffff8116811461165357600080fd5b919050565b600080604080848603121561166c57600080fd5b833567ffffffffffffffff8082111561168457600080fd5b818601915086601f83011261169857600080fd5b81356020828211156116ac576116ac6115d0565b6116ba818360051b0161160f565b828152818101935060069290921b8401810191898311156116da57600080fd5b938101935b8285101561173e5785858b0312156116f75760008081fd5b6116ff6115e6565b853563ffffffff811681146117145760008081fd5b815285830135600281900b811461172b5760008081fd5b81840152845293850193928101926116df565b965061174b888201611640565b955050505050509250929050565b60006020828403121561176b57600080fd5b5035919050565b60006020828403121561178457600080fd5b813561ffff811681146113e157600080fd5b6001600160a01b03811681146117ab57600080fd5b50565b6000806000606084860312156117c357600080fd5b83356117ce81611796565b925060208401356117de81611796565b91506117ec60408501611640565b90509250925092565b6000806020838503121561180857600080fd5b823567ffffffffffffffff8082111561182057600080fd5b818501915085601f83011261183457600080fd5b81358181111561184357600080fd5b8660208260051b850101111561185857600080fd5b60209290920196919550909350505050565b604080825283519082018190526000906020906060840190828701845b828110156118a657815160060b84529284019290840190600101611887565b5050508381038285015284518082528583019183019060005b818110156118e45783516001600160a01b0316835292840192918401916001016118bf565b5090979650505050505050565b60006020828403121561190357600080fd5b81516113e181611796565b600062ffffff80831681810361193457634e487b7160e01b600052601160045260246000fd5b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fdfea264697066735822122048903427db1b98c0cd97b26ab800e55a51c8b5b98cd5a363f22490c0ac241d1b64736f6c634300080f0033a2646970667358221220c1e84aa1e8d7c1251c18a95b48835b3934b1d40ccda3e8d1ccc7bd7d096c898964736f6c634300080f0033", + "devdoc": { + "kind": "dev", + "methods": { + "deployOracle(bytes32,uint24)": { + "details": "Requires that the salt has not been deployed before", + "params": { + "_poolSalt": "Pool salt that deterministically binds an oracle with a pool" + }, + "returns": { + "_oracle": "The address of the newly deployed oracle" + } + }, + "getPool(address,address,uint24)": { + "params": { + "_fee": "The fee denominated in hundredths of a bip", + "_tokenA": "The contract address of either token0 or token1", + "_tokenB": "The contract address of the other token" + }, + "returns": { + "_oracle": "The oracle address" + } + }, + "getPool(bytes32)": { + "params": { + "_poolSalt": "Identifier of both the pool and the oracle" + }, + "returns": { + "_oracle": "The address (if deployed) of the correspondant oracle" + } + }, + "getPoolSalt(address,address,uint24)": { + "params": { + "_fee": "The fee denominated in hundredths of a bip", + "_tokenA": "The contract address of either token0 or token1", + "_tokenB": "The contract address of the other token" + }, + "returns": { + "_poolSalt": "Pool salt for inquired parameters" + } + }, + "setDataReceiver(address)": { + "details": "Will disallow the previous dataReceiver", + "params": { + "_dataReceiver": "The address of the new allowed dataReceiver" + } + }, + "setInitialCardinality(uint16)": { + "params": { + "_initialCardinality": "The initial size of the observations memory storage for newly deployed pools" + } + }, + "setPendingGovernor(address)": { + "params": { + "_pendingGovernor": "Address of the proposed new governor" + } + } + }, + "stateVariables": { + "ORACLE_INIT_CODE_HASH": { + "return": "The oracle creation code hash used to calculate their address", + "returns": { + "_0": "The oracle creation code hash used to calculate their address" + } + }, + "dataReceiver": { + "return": "The address of the DataReceiver for the oracles to consult", + "returns": { + "_0": "The address of the DataReceiver for the oracles to consult" + } + }, + "initialCardinality": { + "return": "The initial size of the observations memory storage for newly deployed pools", + "returns": { + "_0": "The initial size of the observations memory storage for newly deployed pools" + } + }, + "oracleParameters": { + "returns": { + "cardinality": "The size of the observations memory storage", + "poolNonce": "The initial nonce of the pool data", + "poolSalt": "The id of both the oracle and the pool" + } + } + }, + "title": "The OracleFactory contract", + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidAddress()": [ + { + "notice": "Thrown if an address is invalid" + } + ], + "InvalidAmount()": [ + { + "notice": "Thrown if an amount is invalid" + } + ], + "LengthMismatch()": [ + { + "notice": "Thrown if the lengths of a set of lists mismatch" + } + ], + "OnlyDataReceiver()": [ + { + "notice": "Thrown when a contract other than the DataReceiver tries to deploy an oracle" + } + ], + "OnlyGovernor()": [ + { + "notice": "Thrown if a non-governor user tries to call a OnlyGovernor function" + } + ], + "OnlyPendingGovernor()": [ + { + "notice": "Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function" + } + ], + "ZeroAddress()": [ + { + "notice": "Thrown if an address is the zero address" + } + ], + "ZeroAmount()": [ + { + "notice": "Thrown if an amount is zero" + } + ] + }, + "events": { + "DataReceiverSet(address)": { + "notice": "Emitted when a new DataReceiver is set" + }, + "InitialCardinalitySet(uint16)": { + "notice": "Emitted when a new initial oracle cardinality is set" + }, + "OracleDeployed(bytes32,address,uint24)": { + "notice": "Emitted when a new oracle is deployed" + }, + "PendingGovernorAccepted(address)": { + "notice": "Emitted when a new governor is set" + }, + "PendingGovernorSet(address,address)": { + "notice": "Emitted when a new pending governor is set" + } + }, + "kind": "user", + "methods": { + "acceptPendingGovernor()": { + "notice": "Allows a proposed governor to accept the governance" + }, + "deployOracle(bytes32,uint24)": { + "notice": "Deploys a new oracle given an inputted salt" + }, + "getPool(address,address,uint24)": { + "notice": "Overrides UniV3Factory getPool mapping" + }, + "getPool(bytes32)": { + "notice": "Tracks the addresses of the oracle by poolSalt" + }, + "setDataReceiver(address)": { + "notice": "Allows governor to set a new allowed dataReceiver" + }, + "setInitialCardinality(uint16)": { + "notice": "Allows governor to set a new initial cardinality for new oracles" + }, + "setPendingGovernor(address)": { + "notice": "Allows a governor to propose a new governor" + } + }, + "notice": "Handles the deployment of new OracleSidechains", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8014, + "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", + "label": "governor", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 8017, + "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", + "label": "pendingGovernor", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 15437, + "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", + "label": "dataReceiver", + "offset": 0, + "slot": "2", + "type": "t_contract(IDataReceiver)18039" + }, + { + "astId": 15441, + "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", + "label": "oracleParameters", + "offset": 0, + "slot": "3", + "type": "t_struct(OracleParameters)18056_storage" + }, + { + "astId": 15445, + "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", + "label": "initialCardinality", + "offset": 0, + "slot": "5", + "type": "t_uint16" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IDataReceiver)18039": { + "encoding": "inplace", + "label": "contract IDataReceiver", + "numberOfBytes": "20" + }, + "t_struct(OracleParameters)18056_storage": { + "encoding": "inplace", + "label": "struct IOracleFactory.OracleParameters", + "members": [ + { + "astId": 18051, + "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", + "label": "poolSalt", + "offset": 0, + "slot": "0", + "type": "t_bytes32" + }, + { + "astId": 18053, + "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", + "label": "poolNonce", + "offset": 0, + "slot": "1", + "type": "t_uint24" + }, + { + "astId": 18055, + "contract": "solidity/contracts/OracleFactory.sol:OracleFactory", + "label": "cardinality", + "offset": 3, + "slot": "1", + "type": "t_uint16" + } + ], + "numberOfBytes": "64" + }, + "t_uint16": { + "encoding": "inplace", + "label": "uint16", + "numberOfBytes": "2" + }, + "t_uint24": { + "encoding": "inplace", + "label": "uint24", + "numberOfBytes": "3" + } + } + } +} \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index d7b7d5e..8b12f7e 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -33,6 +33,7 @@ const networks: NetworksUserConfig = chainId: 1, companionNetworks: { receiver: 'optimism', + // receiver: 'polygon', // Uncomment to select as sidechain }, }, optimism: { @@ -41,6 +42,12 @@ const networks: NetworksUserConfig = chainId: 10, companionNetworks: { sender: 'ethereum' }, }, + polygon: { + url: env.getNodeUrl('polygon'), + accounts: env.getAccounts('ethereum'), + chainId: 137, + companionNetworks: { sender: 'ethereum' }, + }, sepolia: { url: env.getNodeUrl('sepolia'), accounts: env.getAccounts('test'), @@ -108,7 +115,17 @@ const config: HardhatUserConfig = { onlyCalledMethods: false, }, etherscan: { - apiKey: env.getEtherscanAPIKeys(['ethereum', 'optimisticEthereum', 'sepolia', 'optimisticSepolia']), + apiKey: env.getEtherscanAPIKeys(['ethereum', 'optimisticEthereum', 'polygon', 'sepolia', 'optimisticSepolia']), + customChains: [ + { + network: 'optimisticSepolia', + chainId: 11155420, + urls: { + apiURL: 'https://api-sepolia-optimistic.etherscan.io/api', + browserURL: 'https://sepolia-optimism.etherscan.io', + }, + }, + ], }, typechain: { outDir: 'typechained', diff --git a/solidity/contracts/DataReceiver.sol b/solidity/contracts/DataReceiver.sol index 060228f..fd3d458 100644 --- a/solidity/contracts/DataReceiver.sol +++ b/solidity/contracts/DataReceiver.sol @@ -17,11 +17,14 @@ contract DataReceiver is IDataReceiver, Governable { /// @inheritdoc IDataReceiver mapping(IBridgeReceiverAdapter => bool) public whitelistedAdapters; + mapping(bytes32 => mapping(uint24 => IOracleSidechain.ObservationData[])) internal _cachedObservations; + constructor(address _governor, IOracleFactory _oracleFactory) Governable(_governor) { if (address(_oracleFactory) == address(0)) revert ZeroAddress(); oracleFactory = _oracleFactory; } + /// @inheritdoc IDataReceiver function addObservations( IOracleSidechain.ObservationData[] memory _observationsData, bytes32 _poolSalt, @@ -46,12 +49,65 @@ contract DataReceiver is IDataReceiver, Governable { } // Try to write observations data into oracle if (_oracle.write(_observationsData, _poolNonce)) { - emit ObservationsAdded(_poolSalt, _poolNonce, _observationsData, msg.sender); + emit ObservationsAdded(_poolSalt, _poolNonce, msg.sender); } else { - revert ObservationsNotWritable(); + // Query pool's current nonce + uint24 _currentNonce = _oracle.poolNonce(); + // Discard old observations (already written in the oracle) + // NOTE: if _currentNonce == _poolNonce it shouldn't reach this else block + if (_currentNonce > _poolNonce) revert ObservationsNotWritable(); + + IOracleSidechain.ObservationData[] storage _cachedObservationsData = _cachedObservations[_poolSalt][_poolNonce]; + // Store not-added observations to cachedObservations mapping + if (_cachedObservationsData.length == 0) { + // NOTE: memory to storage is not supported + for (uint256 _i; _i < _observationsData.length; ++_i) { + _cachedObservationsData.push(_observationsData[_i]); + } + emit ObservationsCached(_poolSalt, _poolNonce, msg.sender); + } + while (_currentNonce <= _poolNonce) { + // Try backfilling pending observations (from current to {sent|first empty} nonce) + _observationsData = _cachedObservations[_poolSalt][_currentNonce]; + // If the struct is not empty, write it into the oracle + if (_observationsData.length > 0) { + // Since observation nonce == oracle nonce, we can safely write the observations + _oracle.write(_observationsData, _currentNonce); + emit ObservationsAdded(_poolSalt, _currentNonce, msg.sender); + // Clear out the written observations + delete _cachedObservations[_poolSalt][_currentNonce]; + _currentNonce++; + } else { + // When an empty nonce is found, break the loop + break; + } + } + } + } + + /// @inheritdoc IDataReceiver + function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external { + IOracleSidechain _oracle = deployedOracles[_poolSalt]; + if (address(_oracle) == address(0)) revert ZeroAddress(); + IOracleSidechain.ObservationData[] memory _cachedObservationsData; + uint24 _currentNonce = _oracle.poolNonce(); + uint256 _i; + while (_maxObservations == 0 || _i < _maxObservations) { + _cachedObservationsData = _cachedObservations[_poolSalt][_currentNonce]; + if (_cachedObservationsData.length > 0) { + _oracle.write(_cachedObservationsData, _currentNonce); + emit ObservationsAdded(_poolSalt, _currentNonce, msg.sender); + delete _cachedObservations[_poolSalt][_currentNonce]; + _currentNonce++; + _i++; + } else { + break; + } } + if (_i == 0) revert ObservationsNotWritable(); } + /// @inheritdoc IDataReceiver function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor { _whitelistAdapter(_receiverAdapter, _isWhitelisted); } diff --git a/solidity/contracts/OracleSidechain.sol b/solidity/contracts/OracleSidechain.sol index afe1751..5090df0 100644 --- a/solidity/contracts/OracleSidechain.sol +++ b/solidity/contracts/OracleSidechain.sol @@ -113,7 +113,8 @@ contract OracleSidechain is IOracleSidechain { /// @inheritdoc IOracleSidechain function write(ObservationData[] memory _observationsData, uint24 _poolNonce) external onlyDataReceiver returns (bool _written) { - if (_poolNonce != poolNonce++) return false; + if (_poolNonce != poolNonce) return false; + poolNonce++; uint256 _observationsDataLength = _observationsData.length; for (uint256 _i; _i < _observationsDataLength; ) { diff --git a/solidity/interfaces/IDataReceiver.sol b/solidity/interfaces/IDataReceiver.sol index 27605fe..bc40570 100644 --- a/solidity/interfaces/IDataReceiver.sol +++ b/solidity/interfaces/IDataReceiver.sol @@ -27,14 +27,14 @@ interface IDataReceiver is IGovernable { /// @notice Emitted when a broadcast observation is succesfully processed /// @param _poolSalt Identifier of the pool to fetch /// @return _poolNonce Nonce of the observation broadcast - /// @return _observationsData Array of tuples containing the dataset /// @return _receiverAdapter Handler of the broadcast - event ObservationsAdded( - bytes32 indexed _poolSalt, - uint24 _poolNonce, - IOracleSidechain.ObservationData[] _observationsData, - address _receiverAdapter - ); + event ObservationsAdded(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter); + + /// @notice Emitted when a broadcast observation is cached for later processing + /// @param _poolSalt Identifier of the pool to fetch + /// @return _poolNonce Nonce of the observation broadcast + /// @return _receiverAdapter Handler of the broadcast + event ObservationsCached(bytes32 indexed _poolSalt, uint24 _poolNonce, address _receiverAdapter); /// @notice Emitted when a new adapter whitelisting rule is set /// @param _adapter Address of the adapter @@ -61,6 +61,12 @@ interface IDataReceiver is IGovernable { uint24 _poolNonce ) external; + /// @notice Allows any address to attempt to insert cached observations + /// @param _poolSalt Identifier of the pool to fetch + /// @param _maxObservations Maximum number of observations to process + /// @dev Use _maxObservations = 0 to process all possible cached observations + function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external; + /// @notice Allows governance to set an adapter whitelisted state /// @param _receiverAdapter Address of the adapter /// @param _isWhitelisted New whitelisting status diff --git a/test/e2e/data-receiver.spec.ts b/test/e2e/data-receiver.spec.ts index e6c734a..cfec0e9 100644 --- a/test/e2e/data-receiver.spec.ts +++ b/test/e2e/data-receiver.spec.ts @@ -26,7 +26,7 @@ describe('@skip-on-coverage DataReceiver.sol', () => { let tx: ContractTransaction; let snapshotId: string; - const nonce = 1; + const nonce = 42; before(async () => { await evm.reset({ @@ -69,12 +69,15 @@ describe('@skip-on-coverage DataReceiver.sol', () => { }); context('when an oracle is registered', () => { + let caller: string; + beforeEach(async () => { - await dataReceiver.addObservations(observationsData, salt, nonce - 1); + caller = connextReceiverAdapter.address; + await dataReceiver.addObservations([[0, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce); }); it('should add the observations', async () => { - tx = await dataReceiver.addObservations(observationsData, salt, nonce); + tx = await dataReceiver.addObservations(observationsData, salt, nonce + 1); ({ oracleSidechain } = await getOracle(oracleFactory.address, tokenA.address, tokenB.address, fee)); const slot0 = await oracleSidechain.slot0(); @@ -84,9 +87,49 @@ describe('@skip-on-coverage DataReceiver.sol', () => { .to.emit(oracleSidechain, 'Swap') .withArgs(...SWAP_EVENT_ARGS); - await expect(tx).to.emit(dataReceiver, 'ObservationsAdded'); //.withArgs(connextReceiverAdapter.address, salt, nonce, observationsData); - let eventData = await readArgFromEvent(tx, 'ObservationsAdded', '_observationsData'); - expect(observationsData).to.eql(eventData); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 1, caller); + }); + + it('should remember observations that arrived disordered', async () => { + const obs1 = [[1, 100]] as IOracleSidechain.ObservationDataStructOutput[]; + const obs2 = [[2, 100]] as IOracleSidechain.ObservationDataStructOutput[]; + const obs3 = [[3, 100]] as IOracleSidechain.ObservationDataStructOutput[]; + const obs4 = [[4, 100]] as IOracleSidechain.ObservationDataStructOutput[]; + + /* + - Creates a setup in which an observation arrives (3) before the previous nonce (2) has been processed. + - In this case, the observation should be cached and processed later (as long as the previous nonce is already processed). + - In this setup, observations arrive in the order (1), (3), (2), (4) and expected to be processed in numerical order. + - This will happen in the following way: + - (1) is processed immediately. + - then (3) is cached (current is 1). + - (2) is processed immediately. + - (4) is cached (current is 2). + - (3) is processed. + - (4) is processed (current is 3). + */ + + const tx1 = await dataReceiver.addObservations(obs1, salt, nonce + 1); // initial + const tx2 = await dataReceiver.addObservations(obs3, salt, nonce + 3); // disordered (before 2) + const tx3 = await dataReceiver.addObservations(obs2, salt, nonce + 2); // ordered (after 1) + const tx4 = await dataReceiver.addObservations(obs4, salt, nonce + 4); // should include 3 + + await expect(tx1) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 1, caller); + await expect(tx2).to.emit(dataReceiver, 'ObservationsCached'); + await expect(tx2).not.to.emit(dataReceiver, 'ObservationsAdded'); + await expect(tx3) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 2, caller); + await expect(tx4) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 3, caller); + await expect(tx4) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 4, caller); }); }); @@ -101,10 +144,7 @@ describe('@skip-on-coverage DataReceiver.sol', () => { ({ oracleSidechain } = await getOracle(oracleFactory.address, tokenA.address, tokenB.address, fee)); - // TODO: fix event params with withNamedArgs (ethereum-waffle ^4.0.0) - await expect(tx).to.emit(dataReceiver, 'ObservationsAdded'); //.withArgs(salt, nonce, observationsData, connextReceiverAdapter.address); - let eventData = await readArgFromEvent(tx, 'ObservationsAdded', '_observationsData'); - expect(observationsData).to.eql(eventData); + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(salt, nonce, connextReceiverAdapter.address); }); }); @@ -122,11 +162,82 @@ describe('@skip-on-coverage DataReceiver.sol', () => { ({ oracleSidechain } = await getOracle(oracleFactory.address, tokenA.address, tokenB.address, fee)); - await expect(tx).to.emit(dataReceiver, 'ObservationsAdded'); //.withArgs(salt, nonce, observationsData, connextReceiverAdapter.address); - let eventData = await readArgFromEvent(tx, 'ObservationsAdded', '_observationsData'); - expect(observationsData).to.eql(eventData); + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(salt, nonce, connextReceiverAdapter.address); }); }); }); }); + + describe('syncing observations', () => { + let connextReceiverAdapterSigner: JsonRpcSigner; + let dataReceiverSigner: JsonRpcSigner; + let blockTimestamp1 = 1000000; + let tick1 = 100; + let observationData1 = [blockTimestamp1, tick1] as IOracleSidechain.ObservationDataStructOutput; + let blockTimestamp2 = 3000000; + let tick2 = 300; + let observationData2 = [blockTimestamp2, tick2] as IOracleSidechain.ObservationDataStructOutput; + let observationsData = [observationData1, observationData2]; + + beforeEach(async () => { + connextReceiverAdapterSigner = await wallet.impersonate(connextReceiverAdapter.address); + dataReceiverSigner = await wallet.impersonate(dataReceiver.address); + await wallet.setBalance(connextReceiverAdapter.address, toUnit(10)); + await wallet.setBalance(dataReceiver.address, toUnit(10)); + dataReceiver = dataReceiver.connect(connextReceiverAdapterSigner); + oracleFactory = oracleFactory.connect(dataReceiverSigner); + }); + + context('when an oracle is registered', () => { + let caller: string; + + beforeEach(async () => { + caller = connextReceiverAdapter.address; + await dataReceiver.addObservations([[0, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce - 2); + }); + + context('when the cache at pool nonce is empty', () => { + it('should do nothing', async () => { + await expect(dataReceiver.syncObservations(salt, 0)).to.be.revertedWith('ObservationsNotWritable()'); + }); + }); + + context('when the cache is populated', () => { + beforeEach(async () => { + await dataReceiver.addObservations([[0, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce + 2); + await dataReceiver.addObservations([[1, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce + 1); + await dataReceiver.addObservations([[2, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce); + await dataReceiver.addObservations([[3, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce - 1); + // NOTE: dataReceiver should be at poolNonce == nonce by now (with nonce, nonce+1 & nonce+2 in cache) + }); + + it('should add all cached observations when called without max', async () => { + tx = await dataReceiver.syncObservations(salt, 0); + + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(salt, nonce, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 1, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 2, caller); + }); + + it('should add cached observations limited by max argument', async () => { + tx = await dataReceiver.syncObservations(salt, 2); + + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(salt, nonce, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 1, caller); + }); + }); + }); + + context('when an oracle is not registered', () => { + it('should revert', async () => { + await expect(dataReceiver.syncObservations(salt, 0)).to.be.revertedWith('ZeroAddress()'); + }); + }); + }); }); diff --git a/test/unit/DataReceiver.spec.ts b/test/unit/DataReceiver.spec.ts index 35bc298..ef33d17 100644 --- a/test/unit/DataReceiver.spec.ts +++ b/test/unit/DataReceiver.spec.ts @@ -16,6 +16,7 @@ describe('DataReceiver.sol', () => { let governor: SignerWithAddress; let fakeAdapter: SignerWithAddress; let randomAdapter: SignerWithAddress; + let randomWallet: SignerWithAddress; let dataReceiver: MockContract; let dataReceiverFactory: MockContractFactory; let oracleFactory: FakeContract; @@ -27,7 +28,7 @@ describe('DataReceiver.sol', () => { const randomNonce = 420; before(async () => { - [, governor, fakeAdapter, randomAdapter] = await ethers.getSigners(); + [randomWallet, governor, fakeAdapter, randomAdapter] = await ethers.getSigners(); oracleFactory = await smock.fake('IOracleFactory'); oracleSidechain = await smock.fake('IOracleSidechain'); @@ -57,13 +58,10 @@ describe('DataReceiver.sol', () => { }); describe('addObservations(...)', () => { - let blockTimestamp1 = 1000000; - let tick1 = 100; - let observationData1 = [blockTimestamp1, tick1]; - let blockTimestamp2 = 3000000; - let tick2 = 300; - let observationData2 = [blockTimestamp2, tick2]; - let observationsData = [observationData1, observationData2]; + let observationsData = [ + [1000000, 100], + [300, 3000000], + ] as IOracleSidechain.ObservationDataStructOutput[]; beforeEach(async () => { await dataReceiver.connect(governor).whitelistAdapter(fakeAdapter.address, true); @@ -90,6 +88,7 @@ describe('DataReceiver.sol', () => { it('should revert if the observations are not writable', async () => { oracleSidechain.write.whenCalledWith(observationsData, randomNonce).returns(false); + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce + 1); await expect(dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce)).to.be.revertedWith( 'ObservationsNotWritable()' ); @@ -100,12 +99,10 @@ describe('DataReceiver.sol', () => { let eventAdapter = await readArgFromEvent(tx, 'ObservationsAdded', '_receiverAdapter'); let eventSalt = await readArgFromEvent(tx, 'ObservationsAdded', '_poolSalt'); let eventNonce = await readArgFromEvent(tx, 'ObservationsAdded', '_poolNonce'); - let eventObservationsData = await readArgFromEvent(tx, 'ObservationsAdded', '_observationsData'); expect(eventAdapter).to.eq(fakeAdapter.address); expect(eventSalt).to.eq(randomSalt); expect(eventNonce).to.eq(randomNonce); - expect(eventObservationsData).to.eql(observationsData); }); }); @@ -124,6 +121,7 @@ describe('DataReceiver.sol', () => { it('should revert if the observations are not writable', async () => { oracleSidechain.write.whenCalledWith(observationsData, randomNonce).returns(false); + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce + 1); await expect(dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce)).to.be.revertedWith( 'ObservationsNotWritable()' ); @@ -131,11 +129,7 @@ describe('DataReceiver.sol', () => { it('should emit ObservationsAdded', async () => { tx = await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce); - let eventAdapter = await readArgFromEvent(tx, 'ObservationsAdded', '_receiverAdapter'); - let eventObservationsData = await readArgFromEvent(tx, 'ObservationsAdded', '_observationsData'); - - expect(eventAdapter).to.eq(fakeAdapter.address); - expect(eventObservationsData).to.eql(observationsData); + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(randomSalt, randomNonce, fakeAdapter.address); }); }); @@ -153,6 +147,7 @@ describe('DataReceiver.sol', () => { it('should revert if the observations are not writable', async () => { oracleSidechain.write.whenCalledWith(observationsData, randomNonce).returns(false); + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce + 1); await expect(dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce)).to.be.revertedWith( 'ObservationsNotWritable()' ); @@ -160,16 +155,228 @@ describe('DataReceiver.sol', () => { it('should emit ObservationsAdded', async () => { tx = await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce); - let eventAdapter = await readArgFromEvent(tx, 'ObservationsAdded', '_receiverAdapter'); - let eventObservationsData = await readArgFromEvent(tx, 'ObservationsAdded', '_observationsData'); + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(randomSalt, randomNonce, fakeAdapter.address); + }); + }); + }); + + context('when observations arrive', () => { + beforeEach(async () => { + // normal case scenario (irrelevant to the test) + await dataReceiver.setVariable('deployedOracles', { [randomSalt]: oracleSidechain.address }); + }); + + context('when an observation arrives with a past nonce', () => { + beforeEach(async () => { + await dataReceiver.setVariable('deployedOracles', { [randomSalt]: oracleSidechain.address }); + oracleSidechain.write.whenCalledWith(observationsData, randomNonce).returns(false); + oracleSidechain.poolNonce.returns(randomNonce + 1); + }); + + it('should revert', async () => { + await expect(dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce)).to.be.revertedWith( + 'ObservationsNotWritable()' + ); + }); + }); + + context('when an observation arrives with the correct nonce', () => { + beforeEach(async () => { + await dataReceiver.setVariable('deployedOracles', { [randomSalt]: oracleSidechain.address }); + oracleSidechain.write.whenCalledWith(observationsData, randomNonce).returns(true); + }); + + it('should write observations', async () => { + expect(oracleSidechain.write).to.have.been.calledWith(observationsData, randomNonce); + + tx = await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce); + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(randomSalt, randomNonce, fakeAdapter.address); + }); + }); + + context('when an observation arrives with a future nonce', () => { + beforeEach(async () => { + oracleSidechain.write.reset(); + await dataReceiver.setVariable('deployedOracles', { [randomSalt]: oracleSidechain.address }); + oracleSidechain.write.whenCalledWith(observationsData, randomNonce).returns(false); + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce - 2); + }); + + it('should cache the received observation', async () => { + tx = await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce); + await expect(tx).to.emit(dataReceiver, 'ObservationsCached').withArgs(randomSalt, randomNonce, fakeAdapter.address); + await expect(tx).not.to.emit(dataReceiver, 'ObservationsAdded'); + }); + + it('should cache the first received observation and ignore the following', async () => { + tx = await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce); + await expect(tx).to.emit(dataReceiver, 'ObservationsCached').withArgs(randomSalt, randomNonce, fakeAdapter.address); + await expect(tx).not.to.emit(dataReceiver, 'ObservationsAdded'); + + tx = await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce); + await expect(tx).not.to.emit(dataReceiver, 'ObservationsCached').withArgs(randomSalt, randomNonce, fakeAdapter.address); + await expect(tx).not.to.emit(dataReceiver, 'ObservationsAdded'); + }); - expect(eventAdapter).to.eq(fakeAdapter.address); - expect(eventObservationsData).to.eql(observationsData); + context('when the cache is populated', () => { + beforeEach(async () => { + // Cache observations + // NOTE: smock doesn't support setting internal mapping(bytes32 => mapping(uint => Struct)) (yet) + oracleSidechain.poolNonce.whenCalledWith().returns(0); + await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce + 2); + await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce + 1); + await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce - 1); + await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce - 2); + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce - 2); + // oracleSidechain is at poolNonce = randomNonce - 2 and cache is populated with -2, -1, +1 , +2 (nonce is empty) + + oracleSidechain.write.reset(); + }); + + it('should add the cached observations', async () => { + tx = await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce); + + await expect(tx).to.emit(dataReceiver, 'ObservationsCached').withArgs(randomSalt, randomNonce, fakeAdapter.address); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce - 2, fakeAdapter.address); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce - 1, fakeAdapter.address); + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(randomSalt, randomNonce, fakeAdapter.address); + }); + + it('should add the cached observations up until the inputted observation nonce', async () => { + tx = await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce); + + expect(oracleSidechain.write).to.have.been.calledWith(observationsData, randomNonce - 2); + expect(oracleSidechain.write).to.have.been.calledWith(observationsData, randomNonce - 1); + expect(oracleSidechain.write).to.have.been.calledWith(observationsData, randomNonce); + expect(oracleSidechain.write).not.to.have.been.calledWith(observationsData, randomNonce + 1); + expect(oracleSidechain.write).not.to.have.been.calledWith(observationsData, randomNonce + 2); + + await expect(tx).to.emit(dataReceiver, 'ObservationsCached').withArgs(randomSalt, randomNonce, fakeAdapter.address); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce - 2, fakeAdapter.address); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce - 1, fakeAdapter.address); + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(randomSalt, randomNonce, fakeAdapter.address); + }); + + it('should add the cached observations up until the first empty nonce', async () => { + const tx = await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce + 1); + + expect(oracleSidechain.write).not.to.have.been.calledWith(observationsData, randomNonce); + expect(oracleSidechain.write).to.have.been.calledWith(observationsData, randomNonce - 2); + expect(oracleSidechain.write).to.have.been.calledWith(observationsData, randomNonce - 1); + await expect(tx).not.to.emit(dataReceiver, 'ObservationsCached'); // `randomNonce + 1` is cached in beforeEach + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce - 2, fakeAdapter.address); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce - 1, fakeAdapter.address); + }); }); }); }); }); + describe('syncObservations(...)', () => { + const observationsDataA = [[1, 10]] as IOracleSidechain.ObservationDataStructOutput[]; + const observationsDataB = [[2, 20]] as IOracleSidechain.ObservationDataStructOutput[]; + const observationsDataC = [[3, 30]] as IOracleSidechain.ObservationDataStructOutput[]; + + let caller: string; + + beforeEach(async () => { + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce); + caller = randomWallet.address; + }); + + context('when an oracle is registered', () => { + beforeEach(async () => { + await dataReceiver.setVariable('deployedOracles', { [randomSalt]: oracleSidechain.address }); + }); + + it('should revert when the cache is empty at the oracle nonce', async () => { + await expect(dataReceiver.syncObservations(randomSalt, 0)).to.be.revertedWith('ObservationsNotWritable()'); + }); + + context('when the cache is populated', () => { + beforeEach(async () => { + // Cache observations + // NOTE: smock doesn't support setting internal mapping(bytes32 => mapping(uint => Struct)) (yet) + oracleSidechain.poolNonce.whenCalledWith().returns(0); + await dataReceiver.connect(governor).whitelistAdapter(fakeAdapter.address, true); + await dataReceiver.connect(fakeAdapter).addObservations(observationsDataA, randomSalt, randomNonce); + await dataReceiver.connect(fakeAdapter).addObservations(observationsDataB, randomSalt, randomNonce + 1); + await dataReceiver.connect(fakeAdapter).addObservations(observationsDataC, randomSalt, randomNonce + 2); + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce); + // oracleSidechain is at poolNonce = randomNonce and cache is populated with nonce, +1, +2 + + oracleSidechain.write.reset(); + }); + + it('should revert when the cache at pool nonce is empty', async () => { + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce + 42); + await expect(dataReceiver.syncObservations(randomSalt, 0)).to.be.revertedWith('ObservationsNotWritable()'); + }); + + it('should add cached observations limited by max argument', async () => { + tx = await dataReceiver.syncObservations(randomSalt, 2); + + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataA, randomNonce); + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataB, randomNonce + 1); + expect(oracleSidechain.write).not.to.have.been.calledWith(observationsDataC, randomNonce + 2); + + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(randomSalt, randomNonce, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce + 1, caller); + }); + + it('should add all cached observations when called without max', async () => { + tx = await dataReceiver.syncObservations(randomSalt, 0); + + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataA, randomNonce); + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataB, randomNonce + 1); + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataC, randomNonce + 2); + + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(randomSalt, randomNonce, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce + 1, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce + 2, caller); + }); + + it.skip('should delete added cache observations', async () => { + // should sync nonce and nonce + 1 (nonce + 2 should remain in cache) + await dataReceiver.syncObservations(randomSalt, 2); + + // NOTE: smock having issues with internal mapping structs + const postCacheA = await dataReceiver.getVariable('_cachedObservations', [randomSalt, randomNonce.toString()]); + const postCacheB = await dataReceiver.getVariable('_cachedObservations', [randomSalt, (randomNonce + 1).toString()]); + const postCacheC = await dataReceiver.getVariable('_cachedObservations', [randomSalt, (randomNonce + 2).toString()]); + + expect(postCacheA).to.be.undefined; + expect(postCacheB).to.be.undefined; + expect(postCacheC).to.deep.eq(observationsDataC); + }); + }); + }); + + context('when an oracle is not registered', () => { + it('should revert', async () => { + await expect(dataReceiver.syncObservations(randomSalt, 0)).to.be.revertedWith('ZeroAddress()'); + }); + }); + }); + describe('whitelistAdapter(...)', () => { onlyGovernor( () => dataReceiver, diff --git a/utils/constants.ts b/utils/constants.ts index 3285258..a7276aa 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -22,9 +22,11 @@ export const addressRegistry = { 11155111: '0x0227628f3F023bb0B980b67D528571c95c6DaC1c', }, // CONNEXT DEPLOYMENTS + // source: https://docs.connext.network/resources/deployments connextHandler: { 1: '0x8898B472C54c31894e3B9bb83cEA802a5d0e63C6', 10: '0x8f7492DE823025b4CfaAB1D34c58963F2af5DEDA', + 137: '0x11984dc4465481512eb5b777E44061C158CF2259', 11155111: '0x445fbf9cCbaf7d557fd771d56937E94397f43965', 11155420: '0x8247ed6d0a344eeae4edBC7e44572F1B70ECA82A', }, @@ -42,6 +44,7 @@ export const addressRegistry = { export const domainId: IDomainIDRecord = { 1: 6648936, 10: 1869640809, + 137: 1886350457, 11155111: 1936027759, 11155420: 1869640549, 42069: 42069, diff --git a/yarn.lock b/yarn.lock index 271d2b6..913970c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1595,6 +1595,18 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@nomicfoundation/ethereumjs-block@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.2.2.tgz#f317078c810a54381c682d0c12e1e81acfc11599" + integrity sha512-atjpt4gc6ZGZUPHBAQaUJsm1l/VCo7FmyQ780tMGO8QStjLdhz09dXynmhwVTy5YbRr0FOh/uX3QaEM0yIB2Zg== + dependencies: + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-trie" "5.0.5" + "@nomicfoundation/ethereumjs-tx" "4.1.2" + "@nomicfoundation/ethereumjs-util" "8.0.6" + ethereum-cryptography "0.1.3" + "@nomicfoundation/ethereumjs-block@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz#fdd5c045e7baa5169abeed0e1202bf94e4481c49" @@ -1607,6 +1619,24 @@ "@nomicfoundation/ethereumjs-util" "^8.0.0" ethereum-cryptography "0.1.3" +"@nomicfoundation/ethereumjs-blockchain@6.2.2": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.2.2.tgz#9f79dd2b3dc73f5d5a220f7d8a734330c4c26320" + integrity sha512-6AIB2MoTEPZJLl6IRKcbd8mUmaBAQ/NMe3O7OsAOIiDjMNPPH5KaUQiLfbVlegT4wKIg/GOsFH7XlH2KDVoJNg== + dependencies: + "@nomicfoundation/ethereumjs-block" "4.2.2" + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-ethash" "2.0.5" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-trie" "5.0.5" + "@nomicfoundation/ethereumjs-util" "8.0.6" + abstract-level "^1.0.3" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + level "^8.0.0" + lru-cache "^5.1.1" + memory-level "^1.0.0" + "@nomicfoundation/ethereumjs-blockchain@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz#1a8c243a46d4d3691631f139bfb3a4a157187b0c" @@ -1625,6 +1655,14 @@ lru-cache "^5.1.1" memory-level "^1.0.0" +"@nomicfoundation/ethereumjs-common@3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.1.2.tgz#041086da66ed40f2bf2a2116a1f2f0fcf33fb80d" + integrity sha512-JAEBpIua62dyObHM9KI2b4wHZcRQYYge9gxiygTWa3lNCr2zo+K0TbypDpgiNij5MCGNWP1eboNfNfx1a3vkvA== + dependencies: + "@nomicfoundation/ethereumjs-util" "8.0.6" + crc-32 "^1.2.0" + "@nomicfoundation/ethereumjs-common@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz#f6bcc7753994555e49ab3aa517fc8bcf89c280b9" @@ -1633,6 +1671,18 @@ "@nomicfoundation/ethereumjs-util" "^8.0.0" crc-32 "^1.2.0" +"@nomicfoundation/ethereumjs-ethash@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.5.tgz#0c605812f6f4589a9f6d597db537bbf3b86469db" + integrity sha512-xlLdcICGgAYyYmnI3r1t0R5fKGBJNDQSOQxXNjVO99JmxJIdXR5MgPo5CSJO1RpyzKOgzi3uIFn8agv564dZEQ== + dependencies: + "@nomicfoundation/ethereumjs-block" "4.2.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-util" "8.0.6" + abstract-level "^1.0.3" + bigint-crypto-utils "^3.0.23" + ethereum-cryptography "0.1.3" + "@nomicfoundation/ethereumjs-ethash@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz#11539c32fe0990e1122ff987d1b84cfa34774e81" @@ -1645,7 +1695,21 @@ bigint-crypto-utils "^3.0.23" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-evm@^1.0.0", "@nomicfoundation/ethereumjs-evm@^1.0.0-rc.3": +"@nomicfoundation/ethereumjs-evm@1.3.2", "@nomicfoundation/ethereumjs-evm@^1.0.0-rc.3": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.3.2.tgz#f9d6bafd5c23d07ab75b8649d589af1a43b60bfc" + integrity sha512-I00d4MwXuobyoqdPe/12dxUQxTYzX8OckSaWsMcWAfQhgVDvBx6ffPyP/w1aL0NW7MjyerySPcSVfDJAMHjilw== + dependencies: + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-util" "8.0.6" + "@types/async-eventemitter" "^0.2.1" + async-eventemitter "^0.2.4" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/ethereumjs-evm@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz#99cd173c03b59107c156a69c5e215409098a370b" integrity sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q== @@ -1659,11 +1723,29 @@ mcl-wasm "^0.7.1" rustbn.js "~0.2.0" +"@nomicfoundation/ethereumjs-rlp@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.3.tgz#8d9147fbd0d49e8f4c5ce729d226694a8fe03eb8" + integrity sha512-DZMzB/lqPK78T6MluyXqtlRmOMcsZbTTbbEyAjo0ncaff2mqu/k8a79PBcyvpgAhWD/R59Fjq/x3ro5Lof0AtA== + "@nomicfoundation/ethereumjs-rlp@^4.0.0", "@nomicfoundation/ethereumjs-rlp@^4.0.0-beta.2": version "4.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz#d9a9c5f0f10310c8849b6525101de455a53e771d" integrity sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw== +"@nomicfoundation/ethereumjs-statemanager@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.5.tgz#951cc9ff2c421d40233d2e9d0fe033db2391ee44" + integrity sha512-CAhzpzTR5toh/qOJIZUUOnWekUXuRqkkzaGAQrVcF457VhtCmr+ddZjjK50KNZ524c1XP8cISguEVNqJ6ij1sA== + dependencies: + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-trie" "5.0.5" + "@nomicfoundation/ethereumjs-util" "8.0.6" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + functional-red-black-tree "^1.0.1" + "@nomicfoundation/ethereumjs-statemanager@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz#14a9d4e1c828230368f7ab520c144c34d8721e4b" @@ -1677,6 +1759,16 @@ ethereum-cryptography "0.1.3" functional-red-black-tree "^1.0.1" +"@nomicfoundation/ethereumjs-trie@5.0.5": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.5.tgz#bf31c9306dcbba2007fad668e96109ddb147040c" + integrity sha512-+8sNZrXkzvA1NH5F4kz5RSYl1I6iaRz7mAZRsyxOm0IVY4UaP43Ofvfp/TwOalFunurQrYB5pRO40+8FBcxFMA== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-util" "8.0.6" + ethereum-cryptography "0.1.3" + readable-stream "^3.6.0" + "@nomicfoundation/ethereumjs-trie@^5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz#dcfbe3be53a94bc061c9767a396c16702bc2f5b7" @@ -1687,6 +1779,16 @@ ethereum-cryptography "0.1.3" readable-stream "^3.6.0" +"@nomicfoundation/ethereumjs-tx@4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.1.2.tgz#8659fad7f9094b7eb82aa6cc3c8097cb1c42ff31" + integrity sha512-emJBJZpmTdUa09cqxQqHaysbBI9Od353ZazeH7WgPb35miMgNY6mb7/3vBA98N5lUW/rgkiItjX0KZfIzihSoQ== + dependencies: + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-util" "8.0.6" + ethereum-cryptography "0.1.3" + "@nomicfoundation/ethereumjs-tx@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz#59dc7452b0862b30342966f7052ab9a1f7802f52" @@ -1697,7 +1799,15 @@ "@nomicfoundation/ethereumjs-util" "^8.0.0" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-util@^8.0.0", "@nomicfoundation/ethereumjs-util@^8.0.0-rc.3": +"@nomicfoundation/ethereumjs-util@8.0.6", "@nomicfoundation/ethereumjs-util@^8.0.0-rc.3": + version "8.0.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.6.tgz#dbce5d258b017b37aa58b3a7c330ad59d10ccf0b" + integrity sha512-jOQfF44laa7xRfbfLXojdlcpkvxeHrE2Xu7tSeITsWFgoII163MzjOwFEzSNozHYieFysyoEMhCdP+NY5ikstw== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-util@^8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz#deb2b15d2c308a731e82977aefc4e61ca0ece6c5" integrity sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A== @@ -1705,7 +1815,7 @@ "@nomicfoundation/ethereumjs-rlp" "^4.0.0-beta.2" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-vm@^6.0.0", "@nomicfoundation/ethereumjs-vm@^6.0.0-rc.3": +"@nomicfoundation/ethereumjs-vm@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz#2bb50d332bf41790b01a3767ffec3987585d1de6" integrity sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w== @@ -1727,6 +1837,28 @@ mcl-wasm "^0.7.1" rustbn.js "~0.2.0" +"@nomicfoundation/ethereumjs-vm@^6.0.0-rc.3": + version "6.4.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.4.2.tgz#af1cf62e6c0054bc2b7febc8556d032433d1b18c" + integrity sha512-PRTyxZMP6kx+OdAzBhuH1LD2Yw+hrSpaytftvaK//thDy2OI07S0nrTdbrdk7b8ZVPAc9H9oTwFBl3/wJ3w15g== + dependencies: + "@nomicfoundation/ethereumjs-block" "4.2.2" + "@nomicfoundation/ethereumjs-blockchain" "6.2.2" + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-evm" "1.3.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-statemanager" "1.0.5" + "@nomicfoundation/ethereumjs-trie" "5.0.5" + "@nomicfoundation/ethereumjs-tx" "4.1.2" + "@nomicfoundation/ethereumjs-util" "8.0.6" + "@types/async-eventemitter" "^0.2.1" + async-eventemitter "^0.2.4" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + functional-red-black-tree "^1.0.1" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + "@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz#83a7367342bd053a76d04bbcf4f373fef07cf760"