diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/events.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/events.sol new file mode 100644 index 00000000..1e369a0e --- /dev/null +++ b/contracts/arbitrum/connectors/uniswap-sell-beta/events.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.7.0; + +contract Events { + event LogSell( + uint24 fee, + uint256 amountIn, + uint256 amountOut, + uint256 amountOutMinimum, + bool zeroForOne + ); +} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/helpers.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/helpers.sol index 56e396d9..879445b0 100644 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/helpers.sol +++ b/contracts/arbitrum/connectors/uniswap-sell-beta/helpers.sol @@ -1,7 +1,6 @@ pragma solidity ^0.7.6; pragma abicoder v2; -import "hardhat/console.sol"; import {UniswapV3Pool, ISwapRouter} from "./interface.sol"; import {SqrtPriceMath} from "./libraries/SqrtPriceMath.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/BitMath.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/BitMath.sol deleted file mode 100644 index 3a7216c7..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/BitMath.sol +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title BitMath -/// @dev This library provides functionality for computing bit properties of an unsigned integer -library BitMath { - /// @notice Returns the index of the most significant bit of the number, - /// where the least significant bit is at index 0 and the most significant bit is at index 255 - /// @dev The function satisfies the property: - /// x >= 2**mostSignificantBit(x) and x < 2**(mostSignificantBit(x)+1) - /// @param x the value for which to compute the most significant bit, must be greater than 0 - /// @return r the index of the most significant bit - function mostSignificantBit(uint256 x) internal pure returns (uint8 r) { - require(x > 0); - - if (x >= 0x100000000000000000000000000000000) { - x >>= 128; - r += 128; - } - if (x >= 0x10000000000000000) { - x >>= 64; - r += 64; - } - if (x >= 0x100000000) { - x >>= 32; - r += 32; - } - if (x >= 0x10000) { - x >>= 16; - r += 16; - } - if (x >= 0x100) { - x >>= 8; - r += 8; - } - if (x >= 0x10) { - x >>= 4; - r += 4; - } - if (x >= 0x4) { - x >>= 2; - r += 2; - } - if (x >= 0x2) r += 1; - } - - /// @notice Returns the index of the least significant bit of the number, - /// where the least significant bit is at index 0 and the most significant bit is at index 255 - /// @dev The function satisfies the property: - /// (x & 2**leastSignificantBit(x)) != 0 and (x & (2**(leastSignificantBit(x)) - 1)) == 0) - /// @param x the value for which to compute the least significant bit, must be greater than 0 - /// @return r the index of the least significant bit - function leastSignificantBit(uint256 x) internal pure returns (uint8 r) { - require(x > 0); - - r = 255; - if (x & type(uint128).max > 0) { - r -= 128; - } else { - x >>= 128; - } - if (x & type(uint64).max > 0) { - r -= 64; - } else { - x >>= 64; - } - if (x & type(uint32).max > 0) { - r -= 32; - } else { - x >>= 32; - } - if (x & type(uint16).max > 0) { - r -= 16; - } else { - x >>= 16; - } - if (x & type(uint8).max > 0) { - r -= 8; - } else { - x >>= 8; - } - if (x & 0xf > 0) { - r -= 4; - } else { - x >>= 4; - } - if (x & 0x3 > 0) { - r -= 2; - } else { - x >>= 2; - } - if (x & 0x1 > 0) r -= 1; - } -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/FixedPoint128.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/FixedPoint128.sol deleted file mode 100644 index 6d6948b1..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/FixedPoint128.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.4.0; - -/// @title FixedPoint128 -/// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format) -library FixedPoint128 { - uint256 internal constant Q128 = 0x100000000000000000000000000000000; -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/IERC20Minimal.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/IERC20Minimal.sol deleted file mode 100644 index 62477df5..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/IERC20Minimal.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Minimal ERC20 interface for Uniswap -/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3 -interface IERC20Minimal { - /// @notice Returns the balance of a token - /// @param account The account for which to look up the number of tokens it has, i.e. its balance - /// @return The number of tokens held by the account - function balanceOf(address account) external view returns (uint256); - - /// @notice Transfers the amount of token from the `msg.sender` to the recipient - /// @param recipient The account that will receive the amount transferred - /// @param amount The number of tokens to send from the sender to the recipient - /// @return Returns true for a successful transfer, false for an unsuccessful transfer - function transfer(address recipient, uint256 amount) - external - returns (bool); - - /// @notice Returns the current allowance given to a spender by an owner - /// @param owner The account of the token owner - /// @param spender The account of the token spender - /// @return The current allowance granted by `owner` to `spender` - function allowance(address owner, address spender) - external - view - returns (uint256); - - /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount` - /// @param spender The account which will be allowed to spend a given amount of the owners tokens - /// @param amount The amount of tokens allowed to be used by `spender` - /// @return Returns true for a successful approval, false for unsuccessful - function approve(address spender, uint256 amount) external returns (bool); - - /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender` - /// @param sender The account from which the transfer will be initiated - /// @param recipient The recipient of the transfer - /// @param amount The amount of the transfer - /// @return Returns true for a successful transfer, false for unsuccessful - function transferFrom( - address sender, - address recipient, - uint256 amount - ) external returns (bool); - - /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`. - /// @param from The account from which the tokens were sent, i.e. the balance decreased - /// @param to The account to which the tokens were sent, i.e. the balance increased - /// @param value The amount of tokens that were transferred - event Transfer(address indexed from, address indexed to, uint256 value); - - /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes. - /// @param owner The account that approved spending of its tokens - /// @param spender The account for which the spending allowance was modified - /// @param value The new allowance from the owner to the spender - event Approval( - address indexed owner, - address indexed spender, - uint256 value - ); -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/LICENSE_GPL b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/LICENSE_GPL deleted file mode 100644 index ecbc0593..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/LICENSE_GPL +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. \ No newline at end of file diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/LICENSE_MIT b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/LICENSE_MIT deleted file mode 100644 index bf4f90a2..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/LICENSE_MIT +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2021 Remco Bloemen - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/LiquidityMath.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/LiquidityMath.sol deleted file mode 100644 index d5e23032..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/LiquidityMath.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Math library for liquidity -library LiquidityMath { - /// @notice Add a signed liquidity delta to liquidity and revert if it overflows or underflows - /// @param x The liquidity before change - /// @param y The delta by which liquidity should be changed - /// @return z The liquidity delta - function addDelta(uint128 x, int128 y) internal pure returns (uint128 z) { - if (y < 0) { - require((z = x - uint128(-y)) < x, 'LS'); - } else { - require((z = x + uint128(y)) >= x, 'LA'); - } - } -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/Oracle.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/Oracle.sol deleted file mode 100644 index 3f6b3f32..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/Oracle.sol +++ /dev/null @@ -1,325 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -/// @title Oracle -/// @notice Provides price and liquidity data useful for a wide variety of system designs -/// @dev Instances of stored oracle data, "observations", are collected in the oracle array -/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the -/// maximum length of the oracle array. New slots will be added when the array is fully populated. -/// Observations are overwritten when the full length of the oracle array is populated. -/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe() -library Oracle { - struct Observation { - // the block timestamp of the observation - uint32 blockTimestamp; - // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized - int56 tickCumulative; - // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized - uint160 secondsPerLiquidityCumulativeX128; - // whether or not the observation is initialized - bool initialized; - } - - /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values - /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows - /// @param last The specified observation to be transformed - /// @param blockTimestamp The timestamp of the new observation - /// @param tick The active tick at the time of the new observation - /// @param liquidity The total in-range liquidity at the time of the new observation - /// @return Observation The newly populated observation - function transform( - Observation memory last, - uint32 blockTimestamp, - int24 tick, - uint128 liquidity - ) private pure returns (Observation memory) { - uint32 delta = blockTimestamp - last.blockTimestamp; - return - Observation({ - blockTimestamp: blockTimestamp, - tickCumulative: last.tickCumulative + int56(tick) * delta, - secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 + - ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)), - initialized: true - }); - } - - /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array - /// @param self The stored oracle array - /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32 - /// @return cardinality The number of populated elements in the oracle array - /// @return cardinalityNext The new length of the oracle array, independent of population - function initialize(Observation[65535] storage self, uint32 time) - internal - returns (uint16 cardinality, uint16 cardinalityNext) - { - self[0] = Observation({ - blockTimestamp: time, - tickCumulative: 0, - secondsPerLiquidityCumulativeX128: 0, - initialized: true - }); - return (1, 1); - } - - /// @notice Writes an oracle observation to the array - /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally. - /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality - /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering. - /// @param self The stored oracle array - /// @param index The index of the observation that was most recently written to the observations array - /// @param blockTimestamp The timestamp of the new observation - /// @param tick The active tick at the time of the new observation - /// @param liquidity The total in-range liquidity at the time of the new observation - /// @param cardinality The number of populated elements in the oracle array - /// @param cardinalityNext The new length of the oracle array, independent of population - /// @return indexUpdated The new index of the most recently written element in the oracle array - /// @return cardinalityUpdated The new cardinality of the oracle array - function write( - Observation[65535] storage self, - uint16 index, - uint32 blockTimestamp, - int24 tick, - uint128 liquidity, - uint16 cardinality, - uint16 cardinalityNext - ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) { - Observation memory last = self[index]; - - // early return if we've already written an observation this block - if (last.blockTimestamp == blockTimestamp) return (index, cardinality); - - // if the conditions are right, we can bump the cardinality - if (cardinalityNext > cardinality && index == (cardinality - 1)) { - cardinalityUpdated = cardinalityNext; - } else { - cardinalityUpdated = cardinality; - } - - indexUpdated = (index + 1) % cardinalityUpdated; - self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity); - } - - /// @notice Prepares the oracle array to store up to `next` observations - /// @param self The stored oracle array - /// @param current The current next cardinality of the oracle array - /// @param next The proposed next cardinality which will be populated in the oracle array - /// @return next The next cardinality which will be populated in the oracle array - function grow( - Observation[65535] storage self, - uint16 current, - uint16 next - ) internal returns (uint16) { - require(current > 0, 'I'); - // no-op if the passed next value isn't greater than the current next value - if (next <= current) return current; - // store in each slot to prevent fresh SSTOREs in swaps - // this data will not be used because the initialized boolean is still false - for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1; - return next; - } - - /// @notice comparator for 32-bit timestamps - /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time - /// @param time A timestamp truncated to 32 bits - /// @param a A comparison timestamp from which to determine the relative position of `time` - /// @param b From which to determine the relative position of `time` - /// @return bool Whether `a` is chronologically <= `b` - function lte( - uint32 time, - uint32 a, - uint32 b - ) private pure returns (bool) { - // if there hasn't been overflow, no need to adjust - if (a <= time && b <= time) return a <= b; - - uint256 aAdjusted = a > time ? a : a + 2**32; - uint256 bAdjusted = b > time ? b : b + 2**32; - - return aAdjusted <= bAdjusted; - } - - /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied. - /// The result may be the same observation, or adjacent observations. - /// @dev The answer must be contained in the array, used when the target is located within the stored observation - /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation - /// @param self The stored oracle array - /// @param time The current block.timestamp - /// @param target The timestamp at which the reserved observation should be for - /// @param index The index of the observation that was most recently written to the observations array - /// @param cardinality The number of populated elements in the oracle array - /// @return beforeOrAt The observation recorded before, or at, the target - /// @return atOrAfter The observation recorded at, or after, the target - function binarySearch( - Observation[65535] storage self, - uint32 time, - uint32 target, - uint16 index, - uint16 cardinality - ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) { - uint256 l = (index + 1) % cardinality; // oldest observation - uint256 r = l + cardinality - 1; // newest observation - uint256 i; - while (true) { - i = (l + r) / 2; - - beforeOrAt = self[i % cardinality]; - - // we've landed on an uninitialized tick, keep searching higher (more recently) - if (!beforeOrAt.initialized) { - l = i + 1; - continue; - } - - atOrAfter = self[(i + 1) % cardinality]; - - bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target); - - // check if we've found the answer! - if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break; - - if (!targetAtOrAfter) r = i - 1; - else l = i + 1; - } - } - - /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied - /// @dev Assumes there is at least 1 initialized observation. - /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp. - /// @param self The stored oracle array - /// @param time The current block.timestamp - /// @param target The timestamp at which the reserved observation should be for - /// @param tick The active tick at the time of the returned or simulated observation - /// @param index The index of the observation that was most recently written to the observations array - /// @param liquidity The total pool liquidity at the time of the call - /// @param cardinality The number of populated elements in the oracle array - /// @return beforeOrAt The observation which occurred at, or before, the given timestamp - /// @return atOrAfter The observation which occurred at, or after, the given timestamp - function getSurroundingObservations( - Observation[65535] storage self, - uint32 time, - uint32 target, - int24 tick, - uint16 index, - uint128 liquidity, - uint16 cardinality - ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) { - // optimistically set before to the newest observation - beforeOrAt = self[index]; - - // if the target is chronologically at or after the newest observation, we can early return - if (lte(time, beforeOrAt.blockTimestamp, target)) { - if (beforeOrAt.blockTimestamp == target) { - // if newest observation equals target, we're in the same block, so we can ignore atOrAfter - return (beforeOrAt, atOrAfter); - } else { - // otherwise, we need to transform - return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity)); - } - } - - // now, set before to the oldest observation - beforeOrAt = self[(index + 1) % cardinality]; - if (!beforeOrAt.initialized) beforeOrAt = self[0]; - - // ensure that the target is chronologically at or after the oldest observation - require(lte(time, beforeOrAt.blockTimestamp, target), 'OLD'); - - // if we've reached this point, we have to binary search - return binarySearch(self, time, target, index, cardinality); - } - - /// @dev Reverts if an observation at or before the desired observation timestamp does not exist. - /// 0 may be passed as `secondsAgo' to return the current cumulative values. - /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values - /// at exactly the timestamp between the two observations. - /// @param self The stored oracle array - /// @param time The current block timestamp - /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation - /// @param tick The current tick - /// @param index The index of the observation that was most recently written to the observations array - /// @param liquidity The current in-range pool liquidity - /// @param cardinality The number of populated elements in the oracle array - /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo` - /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo` - function observeSingle( - Observation[65535] storage self, - uint32 time, - uint32 secondsAgo, - int24 tick, - uint16 index, - uint128 liquidity, - uint16 cardinality - ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) { - if (secondsAgo == 0) { - Observation memory last = self[index]; - if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity); - return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128); - } - - uint32 target = time - secondsAgo; - - (Observation memory beforeOrAt, Observation memory atOrAfter) = - getSurroundingObservations(self, time, target, tick, index, liquidity, cardinality); - - if (target == beforeOrAt.blockTimestamp) { - // we're at the left boundary - return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128); - } else if (target == atOrAfter.blockTimestamp) { - // we're at the right boundary - return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128); - } else { - // we're in the middle - uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp; - uint32 targetDelta = target - beforeOrAt.blockTimestamp; - return ( - beforeOrAt.tickCumulative + - ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / observationTimeDelta) * - targetDelta, - beforeOrAt.secondsPerLiquidityCumulativeX128 + - uint160( - (uint256( - atOrAfter.secondsPerLiquidityCumulativeX128 - beforeOrAt.secondsPerLiquidityCumulativeX128 - ) * targetDelta) / observationTimeDelta - ) - ); - } - } - - /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos` - /// @dev Reverts if `secondsAgos` > oldest observation - /// @param self The stored oracle array - /// @param time The current block.timestamp - /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation - /// @param tick The current tick - /// @param index The index of the observation that was most recently written to the observations array - /// @param liquidity The current in-range pool liquidity - /// @param cardinality The number of populated elements in the oracle array - /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo` - /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo` - function observe( - Observation[65535] storage self, - uint32 time, - uint32[] memory secondsAgos, - int24 tick, - uint16 index, - uint128 liquidity, - uint16 cardinality - ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) { - require(cardinality > 0, 'I'); - - tickCumulatives = new int56[](secondsAgos.length); - secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length); - for (uint256 i = 0; i < secondsAgos.length; i++) { - (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle( - self, - time, - secondsAgos[i], - tick, - index, - liquidity, - cardinality - ); - } - } -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/PoolAddress.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/PoolAddress.sol deleted file mode 100644 index 16dfb6e9..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/PoolAddress.sol +++ /dev/null @@ -1,45 +0,0 @@ -pragma solidity >=0.5.0; - -library PoolAddress { - bytes32 internal constant POOL_INIT_CODE_HASH = - 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54; - - struct PoolKey { - address token0; - address token1; - uint24 fee; - } - - function getPoolKey( - address tokenA, - address tokenB, - uint24 fee - ) internal pure returns (PoolKey memory) { - if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); - return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); - } - - function computeAddress(address factory, PoolKey memory key) - internal - pure - returns (address pool) - { - require(key.token0 < key.token1); - pool = address( - uint160( - uint256( - keccak256( - abi.encodePacked( - hex"ff", - factory, - keccak256( - abi.encode(key.token0, key.token1, key.fee) - ), - POOL_INIT_CODE_HASH - ) - ) - ) - ) - ); - } -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/Position.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/Position.sol deleted file mode 100644 index 1c67c7f2..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/Position.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import './FullMath.sol'; -import './FixedPoint128.sol'; -import './LiquidityMath.sol'; - -/// @title Position -/// @notice Positions represent an owner address' liquidity between a lower and upper tick boundary -/// @dev Positions store additional state for tracking fees owed to the position -library Position { - // info stored for each user's position - struct Info { - // the amount of liquidity owned by this position - uint128 liquidity; - // fee growth per unit of liquidity as of the last update to liquidity or fees owed - uint256 feeGrowthInside0LastX128; - uint256 feeGrowthInside1LastX128; - // the fees owed to the position owner in token0/token1 - uint128 tokensOwed0; - uint128 tokensOwed1; - } - - /// @notice Returns the Info struct of a position, given an owner and position boundaries - /// @param self The mapping containing all user positions - /// @param owner The address of the position owner - /// @param tickLower The lower tick boundary of the position - /// @param tickUpper The upper tick boundary of the position - /// @return position The position info struct of the given owners' position - function get( - mapping(bytes32 => Info) storage self, - address owner, - int24 tickLower, - int24 tickUpper - ) internal view returns (Position.Info storage position) { - position = self[keccak256(abi.encodePacked(owner, tickLower, tickUpper))]; - } - - /// @notice Credits accumulated fees to a user's position - /// @param self The individual position to update - /// @param liquidityDelta The change in pool liquidity as a result of the position update - /// @param feeGrowthInside0X128 The all-time fee growth in token0, per unit of liquidity, inside the position's tick boundaries - /// @param feeGrowthInside1X128 The all-time fee growth in token1, per unit of liquidity, inside the position's tick boundaries - function update( - Info storage self, - int128 liquidityDelta, - uint256 feeGrowthInside0X128, - uint256 feeGrowthInside1X128 - ) internal { - Info memory _self = self; - - uint128 liquidityNext; - if (liquidityDelta == 0) { - require(_self.liquidity > 0, 'NP'); // disallow pokes for 0 liquidity positions - liquidityNext = _self.liquidity; - } else { - liquidityNext = LiquidityMath.addDelta(_self.liquidity, liquidityDelta); - } - - // calculate accumulated fees - uint128 tokensOwed0 = - uint128( - FullMath.mulDiv( - feeGrowthInside0X128 - _self.feeGrowthInside0LastX128, - _self.liquidity, - FixedPoint128.Q128 - ) - ); - uint128 tokensOwed1 = - uint128( - FullMath.mulDiv( - feeGrowthInside1X128 - _self.feeGrowthInside1LastX128, - _self.liquidity, - FixedPoint128.Q128 - ) - ); - - // update the position - if (liquidityDelta != 0) self.liquidity = liquidityNext; - self.feeGrowthInside0LastX128 = feeGrowthInside0X128; - self.feeGrowthInside1LastX128 = feeGrowthInside1X128; - if (tokensOwed0 > 0 || tokensOwed1 > 0) { - // overflow is acceptable, have to withdraw before you hit type(uint128).max fees - self.tokensOwed0 += tokensOwed0; - self.tokensOwed1 += tokensOwed1; - } - } -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/SwapMath.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/SwapMath.sol deleted file mode 100644 index ee176fbe..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/SwapMath.sol +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import './FullMath.sol'; -import './SqrtPriceMath.sol'; - -/// @title Computes the result of a swap within ticks -/// @notice Contains methods for computing the result of a swap within a single tick price range, i.e., a single tick. -library SwapMath { - /// @notice Computes the result of swapping some amount in, or amount out, given the parameters of the swap - /// @dev The fee, plus the amount in, will never exceed the amount remaining if the swap's `amountSpecified` is positive - /// @param sqrtRatioCurrentX96 The current sqrt price of the pool - /// @param sqrtRatioTargetX96 The price that cannot be exceeded, from which the direction of the swap is inferred - /// @param liquidity The usable liquidity - /// @param amountRemaining How much input or output amount is remaining to be swapped in/out - /// @param feePips The fee taken from the input amount, expressed in hundredths of a bip - /// @return sqrtRatioNextX96 The price after swapping the amount in/out, not to exceed the price target - /// @return amountIn The amount to be swapped in, of either token0 or token1, based on the direction of the swap - /// @return amountOut The amount to be received, of either token0 or token1, based on the direction of the swap - /// @return feeAmount The amount of input that will be taken as a fee - function computeSwapStep( - uint160 sqrtRatioCurrentX96, - uint160 sqrtRatioTargetX96, - uint128 liquidity, - int256 amountRemaining, - uint24 feePips - ) - internal - pure - returns ( - uint160 sqrtRatioNextX96, - uint256 amountIn, - uint256 amountOut, - uint256 feeAmount - ) - { - bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96; - bool exactIn = amountRemaining >= 0; - - if (exactIn) { - uint256 amountRemainingLessFee = FullMath.mulDiv(uint256(amountRemaining), 1e6 - feePips, 1e6); - amountIn = zeroForOne - ? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true) - : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true); - if (amountRemainingLessFee >= amountIn) sqrtRatioNextX96 = sqrtRatioTargetX96; - else - sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromInput( - sqrtRatioCurrentX96, - liquidity, - amountRemainingLessFee, - zeroForOne - ); - } else { - amountOut = zeroForOne - ? SqrtPriceMath.getAmount1Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false) - : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false); - if (uint256(-amountRemaining) >= amountOut) sqrtRatioNextX96 = sqrtRatioTargetX96; - else - sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromOutput( - sqrtRatioCurrentX96, - liquidity, - uint256(-amountRemaining), - zeroForOne - ); - } - - bool max = sqrtRatioTargetX96 == sqrtRatioNextX96; - - // get the input/output amounts - if (zeroForOne) { - amountIn = max && exactIn - ? amountIn - : SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true); - amountOut = max && !exactIn - ? amountOut - : SqrtPriceMath.getAmount1Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, false); - } else { - amountIn = max && exactIn - ? amountIn - : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true); - amountOut = max && !exactIn - ? amountOut - : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, false); - } - - // cap the output amount to not exceed the remaining output amount - if (!exactIn && amountOut > uint256(-amountRemaining)) { - amountOut = uint256(-amountRemaining); - } - - if (exactIn && sqrtRatioNextX96 != sqrtRatioTargetX96) { - // we didn't reach the target, so take the remainder of the maximum input as fee - feeAmount = uint256(amountRemaining) - amountIn; - } else { - feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, 1e6 - feePips); - } - } -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/Tick.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/Tick.sol deleted file mode 100644 index fb30bedc..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/Tick.sol +++ /dev/null @@ -1,185 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import './LowGasSafeMath.sol'; -import './SafeCast.sol'; - -import './TickMath.sol'; -import './LiquidityMath.sol'; - -/// @title Tick -/// @notice Contains functions for managing tick processes and relevant calculations -library Tick { - using LowGasSafeMath for int256; - using SafeCast for int256; - - // info stored for each initialized individual tick - struct Info { - // the total position liquidity that references this tick - uint128 liquidityGross; - // amount of net liquidity added (subtracted) when tick is crossed from left to right (right to left), - int128 liquidityNet; - // fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) - // only has relative meaning, not absolute — the value depends on when the tick is initialized - uint256 feeGrowthOutside0X128; - uint256 feeGrowthOutside1X128; - // the cumulative tick value on the other side of the tick - int56 tickCumulativeOutside; - // the seconds per unit of liquidity on the _other_ side of this tick (relative to the current tick) - // only has relative meaning, not absolute — the value depends on when the tick is initialized - uint160 secondsPerLiquidityOutsideX128; - // the seconds spent on the other side of the tick (relative to the current tick) - // only has relative meaning, not absolute — the value depends on when the tick is initialized - uint32 secondsOutside; - // true iff the tick is initialized, i.e. the value is exactly equivalent to the expression liquidityGross != 0 - // these 8 bits are set to prevent fresh sstores when crossing newly initialized ticks - bool initialized; - } - - /// @notice Derives max liquidity per tick from given tick spacing - /// @dev Executed within the pool constructor - /// @param tickSpacing The amount of required tick separation, realized in multiples of `tickSpacing` - /// e.g., a tickSpacing of 3 requires ticks to be initialized every 3rd tick i.e., ..., -6, -3, 0, 3, 6, ... - /// @return The max liquidity per tick - function tickSpacingToMaxLiquidityPerTick(int24 tickSpacing) internal pure returns (uint128) { - int24 minTick = (TickMath.MIN_TICK / tickSpacing) * tickSpacing; - int24 maxTick = (TickMath.MAX_TICK / tickSpacing) * tickSpacing; - uint24 numTicks = uint24((maxTick - minTick) / tickSpacing) + 1; - return type(uint128).max / numTicks; - } - - /// @notice Retrieves fee growth data - /// @param self The mapping containing all tick information for initialized ticks - /// @param tickLower The lower tick boundary of the position - /// @param tickUpper The upper tick boundary of the position - /// @param tickCurrent The current tick - /// @param feeGrowthGlobal0X128 The all-time global fee growth, per unit of liquidity, in token0 - /// @param feeGrowthGlobal1X128 The all-time global fee growth, per unit of liquidity, in token1 - /// @return feeGrowthInside0X128 The all-time fee growth in token0, per unit of liquidity, inside the position's tick boundaries - /// @return feeGrowthInside1X128 The all-time fee growth in token1, per unit of liquidity, inside the position's tick boundaries - function getFeeGrowthInside( - mapping(int24 => Tick.Info) storage self, - int24 tickLower, - int24 tickUpper, - int24 tickCurrent, - uint256 feeGrowthGlobal0X128, - uint256 feeGrowthGlobal1X128 - ) internal view returns (uint256 feeGrowthInside0X128, uint256 feeGrowthInside1X128) { - Info storage lower = self[tickLower]; - Info storage upper = self[tickUpper]; - - // calculate fee growth below - uint256 feeGrowthBelow0X128; - uint256 feeGrowthBelow1X128; - if (tickCurrent >= tickLower) { - feeGrowthBelow0X128 = lower.feeGrowthOutside0X128; - feeGrowthBelow1X128 = lower.feeGrowthOutside1X128; - } else { - feeGrowthBelow0X128 = feeGrowthGlobal0X128 - lower.feeGrowthOutside0X128; - feeGrowthBelow1X128 = feeGrowthGlobal1X128 - lower.feeGrowthOutside1X128; - } - - // calculate fee growth above - uint256 feeGrowthAbove0X128; - uint256 feeGrowthAbove1X128; - if (tickCurrent < tickUpper) { - feeGrowthAbove0X128 = upper.feeGrowthOutside0X128; - feeGrowthAbove1X128 = upper.feeGrowthOutside1X128; - } else { - feeGrowthAbove0X128 = feeGrowthGlobal0X128 - upper.feeGrowthOutside0X128; - feeGrowthAbove1X128 = feeGrowthGlobal1X128 - upper.feeGrowthOutside1X128; - } - - feeGrowthInside0X128 = feeGrowthGlobal0X128 - feeGrowthBelow0X128 - feeGrowthAbove0X128; - feeGrowthInside1X128 = feeGrowthGlobal1X128 - feeGrowthBelow1X128 - feeGrowthAbove1X128; - } - - /// @notice Updates a tick and returns true if the tick was flipped from initialized to uninitialized, or vice versa - /// @param self The mapping containing all tick information for initialized ticks - /// @param tick The tick that will be updated - /// @param tickCurrent The current tick - /// @param liquidityDelta A new amount of liquidity to be added (subtracted) when tick is crossed from left to right (right to left) - /// @param feeGrowthGlobal0X128 The all-time global fee growth, per unit of liquidity, in token0 - /// @param feeGrowthGlobal1X128 The all-time global fee growth, per unit of liquidity, in token1 - /// @param secondsPerLiquidityCumulativeX128 The all-time seconds per max(1, liquidity) of the pool - /// @param tickCumulative The tick * time elapsed since the pool was first initialized - /// @param time The current block timestamp cast to a uint32 - /// @param upper true for updating a position's upper tick, or false for updating a position's lower tick - /// @param maxLiquidity The maximum liquidity allocation for a single tick - /// @return flipped Whether the tick was flipped from initialized to uninitialized, or vice versa - function update( - mapping(int24 => Tick.Info) storage self, - int24 tick, - int24 tickCurrent, - int128 liquidityDelta, - uint256 feeGrowthGlobal0X128, - uint256 feeGrowthGlobal1X128, - uint160 secondsPerLiquidityCumulativeX128, - int56 tickCumulative, - uint32 time, - bool upper, - uint128 maxLiquidity - ) internal returns (bool flipped) { - Tick.Info storage info = self[tick]; - - uint128 liquidityGrossBefore = info.liquidityGross; - uint128 liquidityGrossAfter = LiquidityMath.addDelta(liquidityGrossBefore, liquidityDelta); - - require(liquidityGrossAfter <= maxLiquidity, 'LO'); - - flipped = (liquidityGrossAfter == 0) != (liquidityGrossBefore == 0); - - if (liquidityGrossBefore == 0) { - // by convention, we assume that all growth before a tick was initialized happened _below_ the tick - if (tick <= tickCurrent) { - info.feeGrowthOutside0X128 = feeGrowthGlobal0X128; - info.feeGrowthOutside1X128 = feeGrowthGlobal1X128; - info.secondsPerLiquidityOutsideX128 = secondsPerLiquidityCumulativeX128; - info.tickCumulativeOutside = tickCumulative; - info.secondsOutside = time; - } - info.initialized = true; - } - - info.liquidityGross = liquidityGrossAfter; - - // when the lower (upper) tick is crossed left to right (right to left), liquidity must be added (removed) - info.liquidityNet = upper - ? int256(info.liquidityNet).sub(liquidityDelta).toInt128() - : int256(info.liquidityNet).add(liquidityDelta).toInt128(); - } - - /// @notice Clears tick data - /// @param self The mapping containing all initialized tick information for initialized ticks - /// @param tick The tick that will be cleared - function clear(mapping(int24 => Tick.Info) storage self, int24 tick) internal { - delete self[tick]; - } - - /// @notice Transitions to next tick as needed by price movement - /// @param self The mapping containing all tick information for initialized ticks - /// @param tick The destination tick of the transition - /// @param feeGrowthGlobal0X128 The all-time global fee growth, per unit of liquidity, in token0 - /// @param feeGrowthGlobal1X128 The all-time global fee growth, per unit of liquidity, in token1 - /// @param secondsPerLiquidityCumulativeX128 The current seconds per liquidity - /// @param tickCumulative The tick * time elapsed since the pool was first initialized - /// @param time The current block.timestamp - /// @return liquidityNet The amount of liquidity added (subtracted) when tick is crossed from left to right (right to left) - function cross( - mapping(int24 => Tick.Info) storage self, - int24 tick, - uint256 feeGrowthGlobal0X128, - uint256 feeGrowthGlobal1X128, - uint160 secondsPerLiquidityCumulativeX128, - int56 tickCumulative, - uint32 time - ) internal returns (int128 liquidityNet) { - Tick.Info storage info = self[tick]; - info.feeGrowthOutside0X128 = feeGrowthGlobal0X128 - info.feeGrowthOutside0X128; - info.feeGrowthOutside1X128 = feeGrowthGlobal1X128 - info.feeGrowthOutside1X128; - info.secondsPerLiquidityOutsideX128 = secondsPerLiquidityCumulativeX128 - info.secondsPerLiquidityOutsideX128; - info.tickCumulativeOutside = tickCumulative - info.tickCumulativeOutside; - info.secondsOutside = time - info.secondsOutside; - liquidityNet = info.liquidityNet; - } -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/TickBitmap.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/TickBitmap.sol deleted file mode 100644 index 3c435857..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/TickBitmap.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import './BitMath.sol'; - -/// @title Packed tick initialized state library -/// @notice Stores a packed mapping of tick index to its initialized state -/// @dev The mapping uses int16 for keys since ticks are represented as int24 and there are 256 (2^8) values per word. -library TickBitmap { - /// @notice Computes the position in the mapping where the initialized bit for a tick lives - /// @param tick The tick for which to compute the position - /// @return wordPos The key in the mapping containing the word in which the bit is stored - /// @return bitPos The bit position in the word where the flag is stored - function position(int24 tick) private pure returns (int16 wordPos, uint8 bitPos) { - wordPos = int16(tick >> 8); - bitPos = uint8(tick % 256); - } - - /// @notice Flips the initialized state for a given tick from false to true, or vice versa - /// @param self The mapping in which to flip the tick - /// @param tick The tick to flip - /// @param tickSpacing The spacing between usable ticks - function flipTick( - mapping(int16 => uint256) storage self, - int24 tick, - int24 tickSpacing - ) internal { - require(tick % tickSpacing == 0); // ensure that the tick is spaced - (int16 wordPos, uint8 bitPos) = position(tick / tickSpacing); - uint256 mask = 1 << bitPos; - self[wordPos] ^= mask; - } - - /// @notice Returns the next initialized tick contained in the same word (or adjacent word) as the tick that is either - /// to the left (less than or equal to) or right (greater than) of the given tick - /// @param self The mapping in which to compute the next initialized tick - /// @param tick The starting tick - /// @param tickSpacing The spacing between usable ticks - /// @param lte Whether to search for the next initialized tick to the left (less than or equal to the starting tick) - /// @return next The next initialized or uninitialized tick up to 256 ticks away from the current tick - /// @return initialized Whether the next tick is initialized, as the function only searches within up to 256 ticks - function nextInitializedTickWithinOneWord( - mapping(int16 => uint256) storage self, - int24 tick, - int24 tickSpacing, - bool lte - ) internal view returns (int24 next, bool initialized) { - int24 compressed = tick / tickSpacing; - if (tick < 0 && tick % tickSpacing != 0) compressed--; // round towards negative infinity - - if (lte) { - (int16 wordPos, uint8 bitPos) = position(compressed); - // all the 1s at or to the right of the current bitPos - uint256 mask = (1 << bitPos) - 1 + (1 << bitPos); - uint256 masked = self[wordPos] & mask; - - // if there are no initialized ticks to the right of or at the current tick, return rightmost in the word - initialized = masked != 0; - // overflow/underflow is possible, but prevented externally by limiting both tickSpacing and tick - next = initialized - ? (compressed - int24(bitPos - BitMath.mostSignificantBit(masked))) * tickSpacing - : (compressed - int24(bitPos)) * tickSpacing; - } else { - // start from the word of the next tick, since the current tick state doesn't matter - (int16 wordPos, uint8 bitPos) = position(compressed + 1); - // all the 1s at or to the left of the bitPos - uint256 mask = ~((1 << bitPos) - 1); - uint256 masked = self[wordPos] & mask; - - // if there are no initialized ticks to the left of the current tick, return leftmost in the word - initialized = masked != 0; - // overflow/underflow is possible, but prevented externally by limiting both tickSpacing and tick - next = initialized - ? (compressed + 1 + int24(BitMath.leastSignificantBit(masked) - bitPos)) * tickSpacing - : (compressed + 1 + int24(type(uint8).max - bitPos)) * tickSpacing; - } - } -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/TickMath.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/TickMath.sol deleted file mode 100644 index 378e4452..00000000 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/libraries/TickMath.sol +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Math library for computing sqrt prices from ticks and vice versa -/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports -/// prices between 2**-128 and 2**128 -library TickMath { - /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128 - int24 internal constant MIN_TICK = -887272; - /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128 - int24 internal constant MAX_TICK = -MIN_TICK; - - /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK) - uint160 internal constant MIN_SQRT_RATIO = 4295128739; - /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK) - uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342; - - /// @notice Calculates sqrt(1.0001^tick) * 2^96 - /// @dev Throws if |tick| > max tick - /// @param tick The input tick for the above formula - /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0) - /// at the given tick - function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) { - uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick)); - require(absTick <= uint256(MAX_TICK), 'T'); - - uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000; - if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128; - if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128; - if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128; - if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128; - if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128; - if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128; - if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128; - if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128; - if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128; - if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128; - if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128; - if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128; - if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128; - if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128; - if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128; - if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128; - if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128; - if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128; - if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128; - - if (tick > 0) ratio = type(uint256).max / ratio; - - // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96. - // we then downcast because we know the result always fits within 160 bits due to our tick input constraint - // we round up in the division so getTickAtSqrtRatio of the output price is always consistent - sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)); - } - - /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio - /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may - /// ever return. - /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96 - /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio - function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) { - // second inequality must be < because the price can never reach the price at the max tick - require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R'); - uint256 ratio = uint256(sqrtPriceX96) << 32; - - uint256 r = ratio; - uint256 msb = 0; - - assembly { - let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(5, gt(r, 0xFFFFFFFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(4, gt(r, 0xFFFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(3, gt(r, 0xFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(2, gt(r, 0xF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(1, gt(r, 0x3)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := gt(r, 0x1) - msb := or(msb, f) - } - - if (msb >= 128) r = ratio >> (msb - 127); - else r = ratio << (127 - msb); - - int256 log_2 = (int256(msb) - 128) << 64; - - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(63, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(62, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(61, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(60, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(59, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(58, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(57, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(56, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(55, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(54, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(53, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(52, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(51, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(50, f)) - } - - int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number - - int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128); - int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128); - - tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow; - } -} diff --git a/contracts/arbitrum/connectors/uniswap-sell-beta/main.sol b/contracts/arbitrum/connectors/uniswap-sell-beta/main.sol index 129fd253..c0d692ca 100644 --- a/contracts/arbitrum/connectors/uniswap-sell-beta/main.sol +++ b/contracts/arbitrum/connectors/uniswap-sell-beta/main.sol @@ -2,10 +2,11 @@ pragma solidity ^0.7.6; pragma abicoder v2; import "./helpers.sol"; +import {Events} from "./events.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; -contract uniswapSellBeta is Helpers { +contract uniswapSellBeta is Helpers, Events { using SafeERC20 for IERC20; function sell( @@ -13,20 +14,38 @@ contract uniswapSellBeta is Helpers { address tokenOut, uint24 fee, uint256 amountIn, - uint256 amountOutMinimum - ) external payable returns (uint256 amountOut) { - IERC20(tokenIn).safeApprove(address(router), amountIn); - amountOut = swapSingleInput( + uint256 amountOutMinimum, + bool zeroForOne + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + (address token0, address token1) = SwapTokens( + tokenIn, + tokenOut, + zeroForOne + ); + IERC20(token0).safeApprove(address(router), amountIn); + uint256 amountOut = swapSingleInput( getParams( - tokenIn, - tokenOut, + token0, + token1, address(this), fee, amountIn, amountOutMinimum, - tokenOut > tokenIn + zeroForOne ) ); + _eventName = "LogSell(uint24,uint256,uint256,uint256,bool)"; + _eventParam = abi.encode( + fee, + amountIn, + amountOut, + amountOutMinimum, + zeroForOne + ); } } diff --git a/test/uniswap-sell-beta/uniswap-sell-beta.js b/test/uniswap-sell-beta/uniswap-sell-beta.js index aa7c0012..ef4a94c2 100644 --- a/test/uniswap-sell-beta/uniswap-sell-beta.js +++ b/test/uniswap-sell-beta/uniswap-sell-beta.js @@ -3,40 +3,26 @@ const hre = require("hardhat"); const { web3, deployments, waffle, ethers } = hre; const { provider, deployContract } = waffle; -const FeeAmount = { - LOW: 500, - MEDIUM: 3000, - HIGH: 10000, -}; - -const TICK_SPACINGS = { - 500: 10, - 3000: 60, - 10000: 200, -}; - const USDC_ADDR = "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8"; const WETH_ADDR = "0x82af49447d8a07e3bd95bd0d56f35241523fbab1"; describe("Uniswap-sell-beta", function() { let UniswapSellBeta, uniswapSellBeta; - before(async () => { - const account = "0xce2cc46682e9c6d5f174af598fb4931a9c0be68e"; - [owner, add1, add2] = await ethers.getSigners(); + async function setBalance(address) { + await network.provider.send("hardhat_setBalance", [ + address, + ethers.utils.parseEther("10.0").toHexString(), + ]); + } + + async function impersonate(owner, account, token0, decimals) { const tokenArtifact = await artifacts.readArtifact( "@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20" ); - await network.provider.send("hardhat_setBalance", [ - owner.address, - ethers.utils.parseEther("10.0").toHexString(), - ]); - - await network.provider.send("hardhat_setBalance", [ - account, - ethers.utils.parseEther("10.0").toHexString(), - ]); + setBalance(owner); + setBalance(account); await hre.network.provider.request({ method: "hardhat_impersonateAccount", @@ -46,24 +32,33 @@ describe("Uniswap-sell-beta", function() { const signer = await ethers.getSigner(account); const token = new ethers.Contract( - USDC_ADDR, + token0, tokenArtifact.abi, ethers.provider ); - console.log((await token.balanceOf(account)).toString()); + // console.log((await token.balanceOf(account)).toString()); await token .connect(signer) - .transfer(owner.address, ethers.utils.parseUnits("100", 6)); + .transfer(owner, ethers.utils.parseUnits("10", decimals)); await hre.network.provider.request({ method: "hardhat_stopImpersonatingAccount", params: [account], }); + } + + beforeEach(async () => { + const account0 = "0x36cc7B13029B5DEe4034745FB4F24034f3F2ffc6"; + const account1 = "0xce2cc46682e9c6d5f174af598fb4931a9c0be68e"; + + const [owner, add1, add2] = await ethers.getSigners(); + await impersonate(owner.address, account1, USDC_ADDR, 6); + await impersonate(owner.address, account0, WETH_ADDR, 18); UniswapSellBeta = await ethers.getContractFactory( - "UniswapSellBetaArbitrum" + "ConnectV2UniswapSellBeta" ); uniswapSellBeta = await UniswapSellBeta.deploy(); await uniswapSellBeta.deployed(); @@ -73,7 +68,39 @@ describe("Uniswap-sell-beta", function() { expect(uniswapSellBeta.address).to.exist; }); - it("Should Perfrom a swap", async () => { + it("Should swap WETH with USDC", async () => { + const [owner, add1, add2] = await ethers.getSigners(); + + const tokenArtifact = await artifacts.readArtifact( + "@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20" + ); + + const token = new ethers.Contract( + WETH_ADDR, + tokenArtifact.abi, + ethers.provider + ); + + const signer = await ethers.getSigner(owner.address); + + await token + .connect(signer) + .transfer(uniswapSellBeta.address, ethers.utils.parseUnits("10.0", 18)); + + const tx = await uniswapSellBeta.sell( + WETH_ADDR, + USDC_ADDR, + 3000, + ethers.utils.parseUnits("10.0", 18), + 0, + true + ); + // console.log(tx); + }); + + it("Should swap USDC with WETH", async () => { + const [owner, add1, add2] = await ethers.getSigners(); + const tokenArtifact = await artifacts.readArtifact( "@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20" ); @@ -98,6 +125,6 @@ describe("Uniswap-sell-beta", function() { 0, false ); - console.log(tx); + // console.log(tx); }); });