mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Merge branch 'main' into feat/0x
This commit is contained in:
commit
e35b3d41e3
22
.prettierrc
Normal file
22
.prettierrc
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"printWidth": 120,
|
||||
"singleQuote": false,
|
||||
"useTabs": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "none",
|
||||
"semi": true,
|
||||
"plugins": ["./node_modules/prettier-plugin-solidity"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.sol",
|
||||
"options": {
|
||||
"printWidth": 80,
|
||||
"tabWidth": 4,
|
||||
"useTabs": true,
|
||||
"singleQuote": false,
|
||||
"bracketSpacing": true,
|
||||
"explicitTypes": "always"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
import { DSMath } from "../../../common/math.sol";
|
||||
import { Basic } from "../../../common/basic.sol";
|
||||
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
|
@ -1,6 +1,6 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
|
||||
interface OneInchInterace {
|
||||
function swap(
|
|
@ -2,13 +2,13 @@ pragma solidity ^0.7.0;
|
|||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title 1Inch.
|
||||
* @title 1InchV3.
|
||||
* @dev On-chain DEX Aggregator.
|
||||
*/
|
||||
|
||||
// import files from common directory
|
||||
import { TokenInterface , MemoryInterface } from "../../common/interfaces.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { TokenInterface , MemoryInterface } from "../../../common/interfaces.sol";
|
||||
import { Stores } from "../../../common/stores.sol";
|
||||
import { OneInchInterace, OneInchData } from "./interface.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
@ -123,6 +123,6 @@ abstract contract OneInch is OneInchResolverHelpers {
|
|||
}
|
||||
}
|
||||
|
||||
contract ConnectV2OneInchArbitrum is OneInch {
|
||||
contract ConnectV2OneInchV3Arbitrum is OneInch {
|
||||
string public name = "1Inch-v1.0";
|
||||
}
|
13
contracts/arbitrum/connectors/1inch/1inch-v4/helpers.sol
Normal file
13
contracts/arbitrum/connectors/1inch/1inch-v4/helpers.sol
Normal file
|
@ -0,0 +1,13 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
import { DSMath } from "../../../common/math.sol";
|
||||
import { Basic } from "../../../common/basic.sol";
|
||||
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev 1Inch Address
|
||||
*/
|
||||
address internal constant oneInchAddr = 0x1111111254fb6c44bAC0beD2854e76F90643097d;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
|
||||
interface OneInchInterace {
|
||||
function swap(
|
112
contracts/arbitrum/connectors/1inch/1inch-v4/main.sol
Normal file
112
contracts/arbitrum/connectors/1inch/1inch-v4/main.sol
Normal file
|
@ -0,0 +1,112 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title 1InchV4.
|
||||
* @dev On-chain DEX Aggregator.
|
||||
*/
|
||||
|
||||
// import files from common directory
|
||||
import { TokenInterface , MemoryInterface } from "../../../common/interfaces.sol";
|
||||
import { Stores } from "../../../common/stores.sol";
|
||||
import { OneInchInterace, OneInchData } from "./interface.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract OneInchResolver is Helpers, Events {
|
||||
|
||||
|
||||
/**
|
||||
* @dev 1inch API swap handler
|
||||
* @param oneInchData - contains data returned from 1inch API. Struct defined in interfaces.sol
|
||||
* @param ethAmt - Eth to swap for .value()
|
||||
*/
|
||||
function oneInchSwap(
|
||||
OneInchData memory oneInchData,
|
||||
uint ethAmt
|
||||
) internal returns (uint buyAmt) {
|
||||
TokenInterface buyToken = oneInchData.buyToken;
|
||||
(uint _buyDec, uint _sellDec) = getTokensDec(buyToken, oneInchData.sellToken);
|
||||
uint _sellAmt18 = convertTo18(_sellDec, oneInchData._sellAmt);
|
||||
uint _slippageAmt = convert18ToDec(_buyDec, wmul(oneInchData.unitAmt, _sellAmt18));
|
||||
|
||||
uint initalBal = getTokenBal(buyToken);
|
||||
|
||||
// solium-disable-next-line security/no-call-value
|
||||
(bool success, ) = oneInchAddr.call{value: ethAmt}(oneInchData.callData);
|
||||
if (!success) revert("1Inch-swap-failed");
|
||||
|
||||
uint finalBal = getTokenBal(buyToken);
|
||||
|
||||
buyAmt = sub(finalBal, initalBal);
|
||||
|
||||
require(_slippageAmt <= buyAmt, "Too much slippage");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract contract OneInchResolverHelpers is OneInchResolver {
|
||||
|
||||
/**
|
||||
* @dev Gets the swapping data from 1inch's API.
|
||||
* @param oneInchData Struct with multiple swap data defined in interfaces.sol
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function _sell(
|
||||
OneInchData memory oneInchData,
|
||||
uint setId
|
||||
) internal returns (OneInchData memory) {
|
||||
TokenInterface _sellAddr = oneInchData.sellToken;
|
||||
|
||||
uint ethAmt;
|
||||
if (address(_sellAddr) == ethAddr) {
|
||||
ethAmt = oneInchData._sellAmt;
|
||||
} else {
|
||||
approve(TokenInterface(_sellAddr), oneInchAddr, oneInchData._sellAmt);
|
||||
}
|
||||
|
||||
oneInchData._buyAmt = oneInchSwap(oneInchData, ethAmt);
|
||||
setUint(setId, oneInchData._buyAmt);
|
||||
|
||||
return oneInchData;
|
||||
}
|
||||
}
|
||||
|
||||
abstract contract OneInch is OneInchResolverHelpers {
|
||||
/**
|
||||
* @dev Sell ETH/ERC20_Token using 1Inch.
|
||||
* @notice Swap tokens from exchanges like kyber, 0x etc, with calculation done off-chain.
|
||||
* @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAmt The amount of the token to sell.
|
||||
* @param unitAmt The amount of buyAmt/sellAmt with slippage.
|
||||
* @param callData Data from 1inch API.
|
||||
* @param setId ID stores the amount of token brought.
|
||||
*/
|
||||
function sell(
|
||||
address buyAddr,
|
||||
address sellAddr,
|
||||
uint sellAmt,
|
||||
uint unitAmt,
|
||||
bytes calldata callData,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
OneInchData memory oneInchData = OneInchData({
|
||||
buyToken: TokenInterface(buyAddr),
|
||||
sellToken: TokenInterface(sellAddr),
|
||||
unitAmt: unitAmt,
|
||||
callData: callData,
|
||||
_sellAmt: sellAmt,
|
||||
_buyAmt: 0
|
||||
});
|
||||
|
||||
oneInchData = _sell(oneInchData, setId);
|
||||
|
||||
_eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(buyAddr, sellAddr, oneInchData._buyAmt, oneInchData._sellAmt, 0, setId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2OneInchV4Arbitrum is OneInch {
|
||||
string public name = "1Inch-v4";
|
||||
}
|
|
@ -18,7 +18,7 @@ abstract contract Helpers is DSMath, Basic {
|
|||
|
||||
address internal constant paraswap = 0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57;
|
||||
|
||||
function _swapHelper(SwapData memory swapData, uint256 wmaticAmt) internal returns (uint256 buyAmt) {
|
||||
function _swapHelper(SwapData memory swapData, uint256 wavaxAmt) internal returns (uint256 buyAmt) {
|
||||
TokenInterface buyToken = swapData.buyToken;
|
||||
(uint256 _buyDec, uint256 _sellDec) = getTokensDec(buyToken, swapData.sellToken);
|
||||
uint256 _sellAmt18 = convertTo18(_sellDec, swapData._sellAmt);
|
||||
|
@ -26,7 +26,7 @@ abstract contract Helpers is DSMath, Basic {
|
|||
|
||||
uint256 initalBal = getTokenBal(buyToken);
|
||||
|
||||
(bool success, ) = paraswap.call{value: wmaticAmt}(swapData.callData);
|
||||
(bool success, ) = paraswap.call{value: wavaxAmt}(swapData.callData);
|
||||
if (!success) revert("paraswap-failed");
|
||||
|
||||
uint256 finalBal = getTokenBal(buyToken);
|
||||
|
@ -39,16 +39,16 @@ abstract contract Helpers is DSMath, Basic {
|
|||
function _swap(SwapData memory swapData, uint256 setId) internal returns (SwapData memory) {
|
||||
TokenInterface _sellAddr = swapData.sellToken;
|
||||
|
||||
uint256 maticAmt;
|
||||
uint256 avaxAmt;
|
||||
|
||||
if (address(_sellAddr) == avaxAddr) {
|
||||
maticAmt = swapData._sellAmt;
|
||||
avaxAmt = swapData._sellAmt;
|
||||
} else {
|
||||
address tokenProxy = AugustusSwapperInterface(paraswap).getTokenTransferProxy();
|
||||
approve(TokenInterface(_sellAddr), tokenProxy, swapData._sellAmt);
|
||||
}
|
||||
|
||||
swapData._buyAmt = _swapHelper(swapData, maticAmt);
|
||||
swapData._buyAmt = _swapHelper(swapData, avaxAmt);
|
||||
|
||||
setUint(setId, swapData._buyAmt);
|
||||
|
||||
|
|
|
@ -50,6 +50,6 @@ abstract contract ParaswapResolver is Helpers {
|
|||
}
|
||||
}
|
||||
|
||||
contract ConnectV2ParaswapAvalanche is ParaswapResolver {
|
||||
string public constant name = "Paraswap-v1";
|
||||
contract ConnectV2ParaswapV5Avalanche is ParaswapResolver {
|
||||
string public constant name = "Paraswap-v5";
|
||||
}
|
|
@ -41,6 +41,10 @@ abstract contract Basic is DSMath, Stores {
|
|||
_sell = sell == ethAddr ? TokenInterface(wethAddr) : TokenInterface(sell);
|
||||
}
|
||||
|
||||
function changeEthAddrToWethAddr(address token) internal pure returns(address tokenAddr){
|
||||
tokenAddr = token == ethAddr ? wethAddr : token;
|
||||
}
|
||||
|
||||
function convertEthToWeth(bool isEth, TokenInterface token, uint amount) internal {
|
||||
if(isEth) token.deposit{value: amount}();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ interface TokenInterface {
|
|||
function withdraw(uint) external;
|
||||
function balanceOf(address) external view returns (uint);
|
||||
function decimals() external view returns (uint);
|
||||
function totalSupply() external view returns (uint);
|
||||
}
|
||||
|
||||
interface MemoryInterface {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
import { DSMath } from "../../../common/math.sol";
|
||||
import { Basic } from "../../../common/basic.sol";
|
||||
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
|
@ -1,6 +1,6 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
|
||||
interface OneInchInterace {
|
||||
function swap(
|
|
@ -2,13 +2,13 @@ pragma solidity ^0.7.0;
|
|||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title 1Inch.
|
||||
* @title 1InchV3.
|
||||
* @dev On-chain DEX Aggregator.
|
||||
*/
|
||||
|
||||
// import files from common directory
|
||||
import { TokenInterface , MemoryInterface } from "../../common/interfaces.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { TokenInterface , MemoryInterface } from "../../../common/interfaces.sol";
|
||||
import { Stores } from "../../../common/stores.sol";
|
||||
import { OneInchInterace, OneInchData } from "./interface.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
@ -96,7 +96,7 @@ abstract contract OneInch is OneInchResolverHelpers {
|
|||
* @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAmt The amount of the token to sell.
|
||||
* @param unitAmt The amount of buyAmt/sellAmt with slippage.
|
||||
* @param callData Data from 1inch API.
|
||||
* @param callData Data from 1inch API. You can generate calldata for calling 1inch route for exchange: <a href="https://api.1inch.exchange/swagger/ethereum/#/Swap/SwapFactoryCommonController_getSwap" target="_blank">here </a>
|
||||
* @param setId ID stores the amount of token brought.
|
||||
*/
|
||||
function sell(
|
||||
|
@ -123,6 +123,6 @@ abstract contract OneInch is OneInchResolverHelpers {
|
|||
}
|
||||
}
|
||||
|
||||
contract ConnectV2OneInch is OneInch {
|
||||
contract ConnectV2OneInchV3 is OneInch {
|
||||
string public name = "1Inch-v1.2";
|
||||
}
|
12
contracts/mainnet/connectors/1inch/1inch-v4/events.sol
Normal file
12
contracts/mainnet/connectors/1inch/1inch-v4/events.sol
Normal file
|
@ -0,0 +1,12 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogSell(
|
||||
address indexed buyToken,
|
||||
address indexed sellToken,
|
||||
uint256 buyAmt,
|
||||
uint256 sellAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
}
|
13
contracts/mainnet/connectors/1inch/1inch-v4/helpers.sol
Normal file
13
contracts/mainnet/connectors/1inch/1inch-v4/helpers.sol
Normal file
|
@ -0,0 +1,13 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
import { DSMath } from "../../../common/math.sol";
|
||||
import { Basic } from "../../../common/basic.sol";
|
||||
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev 1Inch Address
|
||||
*/
|
||||
address internal constant oneInchAddr = 0x1111111254fb6c44bAC0beD2854e76F90643097d;
|
||||
}
|
30
contracts/mainnet/connectors/1inch/1inch-v4/interface.sol
Normal file
30
contracts/mainnet/connectors/1inch/1inch-v4/interface.sol
Normal file
|
@ -0,0 +1,30 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
|
||||
interface OneInchInterace {
|
||||
function swap(
|
||||
TokenInterface fromToken,
|
||||
TokenInterface toToken,
|
||||
uint256 fromTokenAmount,
|
||||
uint256 minReturnAmount,
|
||||
uint256 guaranteedAmount,
|
||||
address payable referrer,
|
||||
address[] calldata callAddresses,
|
||||
bytes calldata callDataConcat,
|
||||
uint256[] calldata starts,
|
||||
uint256[] calldata gasLimitsAndValues
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint256 returnAmount);
|
||||
}
|
||||
|
||||
struct OneInchData {
|
||||
TokenInterface sellToken;
|
||||
TokenInterface buyToken;
|
||||
uint _sellAmt;
|
||||
uint _buyAmt;
|
||||
uint unitAmt;
|
||||
bytes callData;
|
||||
}
|
111
contracts/mainnet/connectors/1inch/1inch-v4/main.sol
Normal file
111
contracts/mainnet/connectors/1inch/1inch-v4/main.sol
Normal file
|
@ -0,0 +1,111 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title 1InchV4.
|
||||
* @dev On-chain DEX Aggregator.
|
||||
*/
|
||||
|
||||
// import files from common directory
|
||||
import { TokenInterface , MemoryInterface } from "../../../common/interfaces.sol";
|
||||
import { Stores } from "../../../common/stores.sol";
|
||||
import { OneInchInterace, OneInchData } from "./interface.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract OneInchResolver is Helpers, Events {
|
||||
/**
|
||||
* @dev 1inch API swap handler
|
||||
* @param oneInchData - contains data returned from 1inch API. Struct defined in interfaces.sol
|
||||
* @param ethAmt - Eth to swap for .value()
|
||||
*/
|
||||
function oneInchSwap(
|
||||
OneInchData memory oneInchData,
|
||||
uint ethAmt
|
||||
) internal returns (uint buyAmt) {
|
||||
TokenInterface buyToken = oneInchData.buyToken;
|
||||
(uint _buyDec, uint _sellDec) = getTokensDec(buyToken, oneInchData.sellToken);
|
||||
uint _sellAmt18 = convertTo18(_sellDec, oneInchData._sellAmt);
|
||||
uint _slippageAmt = convert18ToDec(_buyDec, wmul(oneInchData.unitAmt, _sellAmt18));
|
||||
|
||||
uint initalBal = getTokenBal(buyToken);
|
||||
|
||||
// solium-disable-next-line security/no-call-value
|
||||
(bool success, ) = oneInchAddr.call{value: ethAmt}(oneInchData.callData);
|
||||
if (!success) revert("1Inch-swap-failed");
|
||||
|
||||
uint finalBal = getTokenBal(buyToken);
|
||||
|
||||
buyAmt = sub(finalBal, initalBal);
|
||||
|
||||
require(_slippageAmt <= buyAmt, "Too much slippage");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract contract OneInchResolverHelpers is OneInchResolver {
|
||||
|
||||
/**
|
||||
* @dev Gets the swapping data from 1inch's API.
|
||||
* @param oneInchData Struct with multiple swap data defined in interfaces.sol
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function _sell(
|
||||
OneInchData memory oneInchData,
|
||||
uint setId
|
||||
) internal returns (OneInchData memory) {
|
||||
TokenInterface _sellAddr = oneInchData.sellToken;
|
||||
|
||||
uint ethAmt;
|
||||
if (address(_sellAddr) == ethAddr) {
|
||||
ethAmt = oneInchData._sellAmt;
|
||||
} else {
|
||||
approve(TokenInterface(_sellAddr), oneInchAddr, oneInchData._sellAmt);
|
||||
}
|
||||
|
||||
oneInchData._buyAmt = oneInchSwap(oneInchData, ethAmt);
|
||||
setUint(setId, oneInchData._buyAmt);
|
||||
|
||||
return oneInchData;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
abstract contract OneInch is OneInchResolverHelpers {
|
||||
/**
|
||||
* @dev Sell ETH/ERC20_Token using 1Inch.
|
||||
* @notice Swap tokens from exchanges like kyber, 0x etc, with calculation done off-chain.
|
||||
* @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAmt The amount of the token to sell.
|
||||
* @param unitAmt The amount of buyAmt/sellAmt with slippage.
|
||||
* @param callData Data from 1inch API.
|
||||
* @param setId ID stores the amount of token brought.
|
||||
*/
|
||||
function sell(
|
||||
address buyAddr,
|
||||
address sellAddr,
|
||||
uint sellAmt,
|
||||
uint unitAmt,
|
||||
bytes calldata callData,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
OneInchData memory oneInchData = OneInchData({
|
||||
buyToken: TokenInterface(buyAddr),
|
||||
sellToken: TokenInterface(sellAddr),
|
||||
unitAmt: unitAmt,
|
||||
callData: callData,
|
||||
_sellAmt: sellAmt,
|
||||
_buyAmt: 0
|
||||
});
|
||||
|
||||
oneInchData = _sell(oneInchData, setId);
|
||||
|
||||
_eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(buyAddr, sellAddr, oneInchData._buyAmt, oneInchData._sellAmt, 0, setId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2OneInchV4 is OneInch {
|
||||
string public name = "1Inch-v4";
|
||||
}
|
31
contracts/mainnet/connectors/sushi-incentive/events.sol
Normal file
31
contracts/mainnet/connectors/sushi-incentive/events.sol
Normal file
|
@ -0,0 +1,31 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogDeposit(
|
||||
uint256 indexed pid,
|
||||
uint256 indexed version,
|
||||
uint256 amount
|
||||
);
|
||||
event LogWithdraw(
|
||||
uint256 indexed pid,
|
||||
uint256 indexed version,
|
||||
uint256 amount
|
||||
);
|
||||
event LogEmergencyWithdraw(
|
||||
uint256 indexed pid,
|
||||
uint256 indexed version,
|
||||
uint256 lpAmount,
|
||||
uint256 rewardsAmount
|
||||
);
|
||||
event LogHarvest(
|
||||
uint256 indexed pid,
|
||||
uint256 indexed version,
|
||||
uint256 amount
|
||||
);
|
||||
event LogWithdrawAndHarvest(
|
||||
uint256 indexed pid,
|
||||
uint256 indexed version,
|
||||
uint256 widrawAmount,
|
||||
uint256 harvestAmount
|
||||
);
|
||||
}
|
88
contracts/mainnet/connectors/sushi-incentive/helpers.sol
Normal file
88
contracts/mainnet/connectors/sushi-incentive/helpers.sol
Normal file
|
@ -0,0 +1,88 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {DSMath} from "../../common/math.sol";
|
||||
import {Basic} from "../../common/basic.sol";
|
||||
import "./interface.sol";
|
||||
|
||||
contract Helpers is DSMath, Basic {
|
||||
IMasterChefV2 immutable masterChefV2 =
|
||||
IMasterChefV2(0xEF0881eC094552b2e128Cf945EF17a6752B4Ec5d);
|
||||
IMasterChef immutable masterChef =
|
||||
IMasterChef(0xc2EdaD668740f1aA35E4D8f227fB8E17dcA888Cd);
|
||||
ISushiSwapFactory immutable factory =
|
||||
ISushiSwapFactory(0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac);
|
||||
|
||||
function _deposit(uint256 _pid, uint256 _amount, uint256 _version) internal {
|
||||
if(_version == 2)
|
||||
masterChefV2.deposit(_pid, _amount, address(this));
|
||||
else
|
||||
masterChef.deposit(_pid, _amount);
|
||||
}
|
||||
|
||||
function _withdraw(uint256 _pid, uint256 _amount, uint256 _version) internal {
|
||||
if(_version == 2)
|
||||
masterChefV2.withdraw(_pid, _amount, address(this));
|
||||
else
|
||||
masterChef.withdraw(_pid, _amount);
|
||||
}
|
||||
|
||||
function _harvest(uint256 _pid) internal {
|
||||
masterChefV2.harvest(_pid, address(this));
|
||||
}
|
||||
|
||||
function _withdrawAndHarvest(uint256 _pid, uint256 _amount, uint256 _version) internal {
|
||||
if(_version == 2)
|
||||
masterChefV2.withdrawAndHarvest(_pid, _amount, address(this));
|
||||
else _withdraw(_pid, _amount, _version);
|
||||
}
|
||||
|
||||
function _emergencyWithdraw(uint256 _pid, uint256 _version) internal {
|
||||
if(_version == 2)
|
||||
masterChefV2.emergencyWithdraw(_pid, address(this));
|
||||
else
|
||||
masterChef.emergencyWithdraw(_pid, address(this));
|
||||
}
|
||||
|
||||
function _getPoolId(address tokenA, address tokenB)
|
||||
internal
|
||||
view
|
||||
returns (uint256 poolId, uint256 version, address lpToken)
|
||||
{
|
||||
address pair = factory.getPair(tokenA, tokenB);
|
||||
uint256 length = masterChefV2.poolLength();
|
||||
version = 2;
|
||||
poolId = uint256(-1);
|
||||
|
||||
for (uint256 i = 0; i < length; i++) {
|
||||
lpToken = masterChefV2.lpToken(i);
|
||||
if (pair == lpToken) {
|
||||
poolId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint256 lengthV1 = masterChef.poolLength();
|
||||
for (uint256 i = 0; i < lengthV1; i++) {
|
||||
(lpToken, , , ) = masterChef.poolInfo(i);
|
||||
if (pair == lpToken) {
|
||||
poolId = i;
|
||||
version = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _getUserInfo(uint256 _pid, uint256 _version)
|
||||
internal
|
||||
view
|
||||
returns (uint256 lpAmount, uint256 rewardsAmount)
|
||||
{
|
||||
if(_version == 2)
|
||||
(lpAmount, rewardsAmount) = masterChefV2.userInfo(_pid, address(this));
|
||||
else
|
||||
(lpAmount, rewardsAmount) = masterChef.userInfo(_pid, address(this));
|
||||
}
|
||||
}
|
117
contracts/mainnet/connectors/sushi-incentive/interface.sol
Normal file
117
contracts/mainnet/connectors/sushi-incentive/interface.sol
Normal file
|
@ -0,0 +1,117 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
struct UserInfo {
|
||||
uint256 amount;
|
||||
uint256 rewardDebt;
|
||||
}
|
||||
|
||||
struct PoolInfo {
|
||||
IERC20 lpToken; // Address of LP token contract.
|
||||
uint256 allocPoint; // How many allocation points assigned to this pool. SUSHIs to distribute per block.
|
||||
uint256 lastRewardBlock; // Last block number that SUSHIs distribution occurs.
|
||||
uint256 accSushiPerShare; // Accumulated SUSHIs per share, times 1e12. See below.
|
||||
}
|
||||
|
||||
interface IERC20 {
|
||||
function totalSupply() external view returns (uint256);
|
||||
|
||||
function balanceOf(address account) external view returns (uint256);
|
||||
|
||||
function allowance(address owner, address spender) external view returns (uint256);
|
||||
|
||||
function approve(address spender, uint256 amount) external returns (bool);
|
||||
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
|
||||
/// @notice EIP 2612
|
||||
function permit(
|
||||
address owner,
|
||||
address spender,
|
||||
uint256 value,
|
||||
uint256 deadline,
|
||||
uint8 v,
|
||||
bytes32 r,
|
||||
bytes32 s
|
||||
) external;
|
||||
}
|
||||
|
||||
interface IMasterChef {
|
||||
function poolLength() external view returns (uint256);
|
||||
|
||||
function updatePool(uint256 pid) external returns (PoolInfo memory);
|
||||
|
||||
function poolInfo(uint256 pid) external view returns (address, uint256, uint256, uint256);
|
||||
|
||||
function userInfo(uint256 _pid, address _user)
|
||||
external
|
||||
view
|
||||
returns (uint256, uint256);
|
||||
|
||||
function deposit(
|
||||
uint256 pid,
|
||||
uint256 amount
|
||||
) external;
|
||||
|
||||
function withdraw(
|
||||
uint256 pid,
|
||||
uint256 amount
|
||||
) external;
|
||||
|
||||
function emergencyWithdraw(uint256 pid, address to) external;
|
||||
}
|
||||
|
||||
interface IMasterChefV2 {
|
||||
function poolLength() external view returns (uint256);
|
||||
|
||||
function updatePool(uint256 pid) external returns (PoolInfo memory);
|
||||
|
||||
function lpToken(uint256 pid) external view returns (address);
|
||||
|
||||
function userInfo(uint256 _pid, address _user)
|
||||
external
|
||||
view
|
||||
returns (uint256, uint256);
|
||||
|
||||
function deposit(
|
||||
uint256 pid,
|
||||
uint256 amount,
|
||||
address to
|
||||
) external;
|
||||
|
||||
function withdraw(
|
||||
uint256 pid,
|
||||
uint256 amount,
|
||||
address to
|
||||
) external;
|
||||
|
||||
function emergencyWithdraw(uint256 pid, address to) external;
|
||||
|
||||
function harvest(uint256 pid, address to) external;
|
||||
|
||||
function withdrawAndHarvest(
|
||||
uint256 pid,
|
||||
uint256 amount,
|
||||
address to
|
||||
) external;
|
||||
}
|
||||
|
||||
interface ISushiSwapFactory {
|
||||
function getPair(address tokenA, address tokenB)
|
||||
external
|
||||
view
|
||||
returns (address pair);
|
||||
|
||||
function allPairs(uint256) external view returns (address pair);
|
||||
|
||||
function allPairsLength() external view returns (uint256);
|
||||
|
||||
function feeTo() external view returns (address);
|
||||
|
||||
function feeToSetter() external view returns (address);
|
||||
|
||||
function createPair(address tokenA, address tokenB)
|
||||
external
|
||||
returns (address pair);
|
||||
}
|
174
contracts/mainnet/connectors/sushi-incentive/main.sol
Normal file
174
contracts/mainnet/connectors/sushi-incentive/main.sol
Normal file
|
@ -0,0 +1,174 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title SushiSwap Double Incentive.
|
||||
* @dev Decentralized Exchange.
|
||||
*/
|
||||
|
||||
import {TokenInterface} from "../../common/interfaces.sol";
|
||||
import {Helpers} from "./helpers.sol";
|
||||
import {Events} from "./events.sol";
|
||||
|
||||
abstract contract SushipswapIncentiveResolver is Helpers, Events {
|
||||
/**
|
||||
* @dev deposit LP token to masterChef
|
||||
* @notice deposit LP token to masterChef
|
||||
* @param token1 token1 of LP token
|
||||
* @param token2 token2 of LP token
|
||||
* @param amount amount of LP token
|
||||
* @param getId ID to retrieve amount
|
||||
* @param setId ID stores Pool ID
|
||||
*/
|
||||
function deposit(
|
||||
address token1,
|
||||
address token2,
|
||||
uint256 amount,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
token1 = changeEthAddrToWethAddr(token1);
|
||||
token2 = changeEthAddrToWethAddr(token2);
|
||||
amount = getUint(getId, amount);
|
||||
(uint256 _pid, uint256 _version, address lpTokenAddr) = _getPoolId(
|
||||
token1,
|
||||
token2
|
||||
);
|
||||
setUint(setId, _pid);
|
||||
require(_pid != uint256(-1), "pool-does-not-exist");
|
||||
TokenInterface lpToken = TokenInterface(lpTokenAddr);
|
||||
lpToken.approve(address(masterChef), amount);
|
||||
_deposit(_pid, amount, _version);
|
||||
_eventName = "LogDeposit(uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_pid, _version, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev withdraw LP token from masterChef
|
||||
* @notice withdraw LP token from masterChef
|
||||
* @param token1 token1 of LP token
|
||||
* @param token2 token2 of LP token
|
||||
* @param amount amount of LP token
|
||||
* @param getId ID to retrieve amount
|
||||
* @param setId ID stores Pool ID
|
||||
*/
|
||||
function withdraw(
|
||||
address token1,
|
||||
address token2,
|
||||
uint256 amount,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
token1 = changeEthAddrToWethAddr(token1);
|
||||
token2 = changeEthAddrToWethAddr(token2);
|
||||
amount = getUint(getId, amount);
|
||||
(uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2);
|
||||
setUint(setId, _pid);
|
||||
require(_pid != uint256(-1), "pool-does-not-exist");
|
||||
_withdraw(_pid, amount, _version);
|
||||
_eventName = "LogWithdraw(uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_pid, _version, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev harvest from masterChef
|
||||
* @notice harvest from masterChef
|
||||
* @param token1 token1 deposited of LP token
|
||||
* @param token2 token2 deposited LP token
|
||||
* @param setId ID stores Pool ID
|
||||
*/
|
||||
function harvest(
|
||||
address token1,
|
||||
address token2,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
token1 = changeEthAddrToWethAddr(token1);
|
||||
token2 = changeEthAddrToWethAddr(token2);
|
||||
(uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2);
|
||||
setUint(setId, _pid);
|
||||
require(_pid != uint256(-1), "pool-does-not-exist");
|
||||
(, uint256 rewardsAmount) = _getUserInfo(_pid, _version);
|
||||
if (_version == 2) _harvest(_pid);
|
||||
else _withdraw(_pid, 0, _version);
|
||||
_eventName = "LogHarvest(uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_pid, _version, rewardsAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev withdraw LP token and harvest from masterChef
|
||||
* @notice withdraw LP token and harvest from masterChef
|
||||
* @param token1 token1 of LP token
|
||||
* @param token2 token2 of LP token
|
||||
* @param amount amount of LP token
|
||||
* @param getId ID to retrieve amount
|
||||
* @param setId ID stores Pool ID
|
||||
*/
|
||||
function withdrawAndHarvest(
|
||||
address token1,
|
||||
address token2,
|
||||
uint256 amount,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
token1 = changeEthAddrToWethAddr(token1);
|
||||
token2 = changeEthAddrToWethAddr(token2);
|
||||
amount = getUint(getId, amount);
|
||||
(uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2);
|
||||
setUint(setId, _pid);
|
||||
require(_pid != uint256(-1), "pool-does-not-exist");
|
||||
(, uint256 rewardsAmount) = _getUserInfo(_pid, _version);
|
||||
_withdrawAndHarvest(_pid, amount, _version);
|
||||
_eventName = "LogWithdrawAndHarvest(uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_pid, _version, amount, rewardsAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev emergency withdraw from masterChef
|
||||
* @notice emergency withdraw from masterChef
|
||||
* @param token1 token1 deposited of LP token
|
||||
* @param token2 token2 deposited LP token
|
||||
* @param setId ID stores Pool ID
|
||||
*/
|
||||
function emergencyWithdraw(
|
||||
address token1,
|
||||
address token2,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
token1 = changeEthAddrToWethAddr(token1);
|
||||
token2 = changeEthAddrToWethAddr(token2);
|
||||
(uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2);
|
||||
setUint(setId, _pid);
|
||||
require(_pid != uint256(-1), "pool-does-not-exist");
|
||||
(uint256 lpAmount, uint256 rewardsAmount) = _getUserInfo(
|
||||
_pid,
|
||||
_version
|
||||
);
|
||||
_emergencyWithdraw(_pid, _version);
|
||||
_eventName = "LogEmergencyWithdraw(uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_pid, _version, lpAmount, rewardsAmount);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2SushiswapIncentive is SushipswapIncentiveResolver {
|
||||
string public constant name = "SushipswapIncentive-v1.1";
|
||||
}
|
41
contracts/mainnet/connectors/sushiswap/events.sol
Normal file
41
contracts/mainnet/connectors/sushiswap/events.sol
Normal file
|
@ -0,0 +1,41 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogDepositLiquidity(
|
||||
address indexed tokenA,
|
||||
address indexed tokenB,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
uint256 uniAmount,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawLiquidity(
|
||||
address indexed tokenA,
|
||||
address indexed tokenB,
|
||||
uint256 amountA,
|
||||
uint256 amountB,
|
||||
uint256 uniAmount,
|
||||
uint256 getId,
|
||||
uint256[] setId
|
||||
);
|
||||
|
||||
event LogBuy(
|
||||
address indexed buyToken,
|
||||
address indexed sellToken,
|
||||
uint256 buyAmt,
|
||||
uint256 sellAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogSell(
|
||||
address indexed buyToken,
|
||||
address indexed sellToken,
|
||||
uint256 buyAmt,
|
||||
uint256 sellAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
}
|
184
contracts/mainnet/connectors/sushiswap/helpers.sol
Normal file
184
contracts/mainnet/connectors/sushiswap/helpers.sol
Normal file
|
@ -0,0 +1,184 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import {TokenInterface} from "../../common/interfaces.sol";
|
||||
import {DSMath} from "../../common/math.sol";
|
||||
import {Basic} from "../../common/basic.sol";
|
||||
import {ISushiSwapRouter, ISushiSwapFactory} from "./interface.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev ISushiSwapRouter
|
||||
*/
|
||||
ISushiSwapRouter internal constant router =
|
||||
ISushiSwapRouter(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F);
|
||||
|
||||
function getExpectedBuyAmt(address[] memory paths, uint256 sellAmt)
|
||||
internal
|
||||
view
|
||||
returns (uint256 buyAmt)
|
||||
{
|
||||
uint256[] memory amts = router.getAmountsOut(sellAmt, paths);
|
||||
buyAmt = amts[1];
|
||||
}
|
||||
|
||||
function getExpectedSellAmt(address[] memory paths, uint256 buyAmt)
|
||||
internal
|
||||
view
|
||||
returns (uint256 sellAmt)
|
||||
{
|
||||
uint256[] memory amts = router.getAmountsIn(buyAmt, paths);
|
||||
sellAmt = amts[0];
|
||||
}
|
||||
|
||||
function checkPair(address[] memory paths) internal view {
|
||||
address pair = ISushiSwapFactory(router.factory()).getPair(
|
||||
paths[0],
|
||||
paths[1]
|
||||
);
|
||||
require(pair != address(0), "No-exchange-address");
|
||||
}
|
||||
|
||||
function getPaths(address buyAddr, address sellAddr)
|
||||
internal
|
||||
pure
|
||||
returns (address[] memory paths)
|
||||
{
|
||||
paths = new address[](2);
|
||||
paths[0] = address(sellAddr);
|
||||
paths[1] = address(buyAddr);
|
||||
}
|
||||
|
||||
function getMinAmount(
|
||||
TokenInterface token,
|
||||
uint256 amt,
|
||||
uint256 slippage
|
||||
) internal view returns (uint256 minAmt) {
|
||||
uint256 _amt18 = convertTo18(token.decimals(), amt);
|
||||
minAmt = wmul(_amt18, sub(WAD, slippage));
|
||||
minAmt = convert18ToDec(token.decimals(), minAmt);
|
||||
}
|
||||
|
||||
function _addLiquidity(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 _amt,
|
||||
uint256 unitAmt,
|
||||
uint256 slippage
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint256 _amtA,
|
||||
uint256 _amtB,
|
||||
uint256 _liquidity
|
||||
)
|
||||
{
|
||||
(TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(
|
||||
tokenA,
|
||||
tokenB
|
||||
);
|
||||
|
||||
_amtA = _amt == uint256(-1)
|
||||
? getTokenBal(TokenInterface(tokenA))
|
||||
: _amt;
|
||||
_amtB = convert18ToDec(
|
||||
_tokenB.decimals(),
|
||||
wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA))
|
||||
);
|
||||
|
||||
bool isEth = address(_tokenA) == wethAddr;
|
||||
convertEthToWeth(isEth, _tokenA, _amtA);
|
||||
|
||||
isEth = address(_tokenB) == wethAddr;
|
||||
convertEthToWeth(isEth, _tokenB, _amtB);
|
||||
|
||||
approve(_tokenA, address(router), _amtA);
|
||||
approve(_tokenB, address(router), _amtB);
|
||||
|
||||
uint256 minAmtA = getMinAmount(_tokenA, _amtA, slippage);
|
||||
uint256 minAmtB = getMinAmount(_tokenB, _amtB, slippage);
|
||||
(_amtA, _amtB, _liquidity) = router.addLiquidity(
|
||||
address(_tokenA),
|
||||
address(_tokenB),
|
||||
_amtA,
|
||||
_amtB,
|
||||
minAmtA,
|
||||
minAmtB,
|
||||
address(this),
|
||||
block.timestamp + 1
|
||||
);
|
||||
}
|
||||
|
||||
function _removeLiquidity(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 _amt,
|
||||
uint256 unitAmtA,
|
||||
uint256 unitAmtB
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint256 _amtA,
|
||||
uint256 _amtB,
|
||||
uint256 _uniAmt
|
||||
)
|
||||
{
|
||||
TokenInterface _tokenA;
|
||||
TokenInterface _tokenB;
|
||||
(_tokenA, _tokenB, _uniAmt) = _getRemoveLiquidityData(
|
||||
tokenA,
|
||||
tokenB,
|
||||
_amt
|
||||
);
|
||||
{
|
||||
uint256 minAmtA = convert18ToDec(
|
||||
_tokenA.decimals(),
|
||||
wmul(unitAmtA, _uniAmt)
|
||||
);
|
||||
uint256 minAmtB = convert18ToDec(
|
||||
_tokenB.decimals(),
|
||||
wmul(unitAmtB, _uniAmt)
|
||||
);
|
||||
(_amtA, _amtB) = router.removeLiquidity(
|
||||
address(_tokenA),
|
||||
address(_tokenB),
|
||||
_uniAmt,
|
||||
minAmtA,
|
||||
minAmtB,
|
||||
address(this),
|
||||
block.timestamp + 1
|
||||
);
|
||||
}
|
||||
|
||||
bool isEth = address(_tokenA) == wethAddr;
|
||||
convertWethToEth(isEth, _tokenA, _amtA);
|
||||
|
||||
isEth = address(_tokenB) == wethAddr;
|
||||
convertWethToEth(isEth, _tokenB, _amtB);
|
||||
}
|
||||
|
||||
function _getRemoveLiquidityData(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 _amt
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
TokenInterface _tokenA,
|
||||
TokenInterface _tokenB,
|
||||
uint256 _uniAmt
|
||||
)
|
||||
{
|
||||
(_tokenA, _tokenB) = changeEthAddress(tokenA, tokenB);
|
||||
address exchangeAddr = ISushiSwapFactory(router.factory()).getPair(
|
||||
address(_tokenA),
|
||||
address(_tokenB)
|
||||
);
|
||||
require(exchangeAddr != address(0), "pair-not-found.");
|
||||
|
||||
TokenInterface uniToken = TokenInterface(exchangeAddr);
|
||||
_uniAmt = _amt == uint256(-1)
|
||||
? uniToken.balanceOf(address(this))
|
||||
: _amt;
|
||||
approve(uniToken, address(router), _uniAmt);
|
||||
}
|
||||
}
|
57
contracts/mainnet/connectors/sushiswap/interface.sol
Normal file
57
contracts/mainnet/connectors/sushiswap/interface.sol
Normal file
|
@ -0,0 +1,57 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
interface ISushiSwapRouter {
|
||||
function factory() external pure returns (address);
|
||||
function WETH() external pure returns (address);
|
||||
|
||||
function addLiquidity(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint amountADesired,
|
||||
uint amountBDesired,
|
||||
uint amountAMin,
|
||||
uint amountBMin,
|
||||
address to,
|
||||
uint deadline
|
||||
) external returns (uint amountA, uint amountB, uint liquidity);
|
||||
function removeLiquidity(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint liquidity,
|
||||
uint amountAMin,
|
||||
uint amountBMin,
|
||||
address to,
|
||||
uint deadline
|
||||
) external returns (uint amountA, uint amountB);
|
||||
function swapExactTokensForTokens(
|
||||
uint amountIn,
|
||||
uint amountOutMin,
|
||||
address[] calldata path,
|
||||
address to,
|
||||
uint deadline
|
||||
) external returns (uint[] memory amounts);
|
||||
function swapTokensForExactTokens(
|
||||
uint amountOut,
|
||||
uint amountInMax,
|
||||
address[] calldata path,
|
||||
address to,
|
||||
uint deadline
|
||||
) external returns (uint[] memory amounts);
|
||||
|
||||
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
|
||||
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
|
||||
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
|
||||
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
|
||||
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
|
||||
}
|
||||
|
||||
interface ISushiSwapFactory {
|
||||
function getPair(address tokenA, address tokenB) external view returns (address pair);
|
||||
function allPairs(uint) external view returns (address pair);
|
||||
function allPairsLength() external view returns (uint);
|
||||
|
||||
function feeTo() external view returns (address);
|
||||
function feeToSetter() external view returns (address);
|
||||
|
||||
function createPair(address tokenA, address tokenB) external returns (address pair);
|
||||
}
|
196
contracts/mainnet/connectors/sushiswap/main.sol
Normal file
196
contracts/mainnet/connectors/sushiswap/main.sol
Normal file
|
@ -0,0 +1,196 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title SushiSwap.
|
||||
* @dev Decentralized Exchange.
|
||||
*/
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract SushipswapResolver is Helpers, Events {
|
||||
/**
|
||||
* @dev Deposit Liquidity.
|
||||
* @notice Deposit Liquidity to a SushiSwap pool.
|
||||
* @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amtA The amount of A tokens to deposit.
|
||||
* @param unitAmt The unit amount of of amtB/amtA with slippage.
|
||||
* @param slippage Slippage amount.
|
||||
* @param getId ID to retrieve amtA.
|
||||
* @param setId ID stores the amount of pools tokens received.
|
||||
*/
|
||||
function deposit(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 amtA,
|
||||
uint256 unitAmt,
|
||||
uint256 slippage,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amtA);
|
||||
|
||||
(uint _amtA, uint _amtB, uint _uniAmt) = _addLiquidity(
|
||||
tokenA,
|
||||
tokenB,
|
||||
_amt,
|
||||
unitAmt,
|
||||
slippage
|
||||
);
|
||||
setUint(setId, _uniAmt);
|
||||
|
||||
_eventName = "LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw Liquidity.
|
||||
* @notice Withdraw Liquidity from a SushiSwap pool.
|
||||
* @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param uniAmt The amount of pool tokens to withdraw.
|
||||
* @param unitAmtA The unit amount of amtA/uniAmt with slippage.
|
||||
* @param unitAmtB The unit amount of amtB/uniAmt with slippage.
|
||||
* @param getId ID to retrieve uniAmt.
|
||||
* @param setIds Array of IDs to store the amount tokens received.
|
||||
*/
|
||||
function withdraw(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 uniAmt,
|
||||
uint256 unitAmtA,
|
||||
uint256 unitAmtB,
|
||||
uint256 getId,
|
||||
uint256[] calldata setIds
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, uniAmt);
|
||||
|
||||
(uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity(
|
||||
tokenA,
|
||||
tokenB,
|
||||
_amt,
|
||||
unitAmtA,
|
||||
unitAmtB
|
||||
);
|
||||
|
||||
setUint(setIds[0], _amtA);
|
||||
setUint(setIds[1], _amtB);
|
||||
|
||||
_eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])";
|
||||
_eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Buy ETH/ERC20_Token.
|
||||
* @notice Buy a token using a SushiSwap
|
||||
* @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param buyAmt The amount of tokens to buy.
|
||||
* @param unitAmt The unit amount of sellAmt/buyAmt with slippage.
|
||||
* @param getId ID to retrieve buyAmt.
|
||||
* @param setId ID to store the amount of tokens sold.
|
||||
*/
|
||||
function buy(
|
||||
address buyAddr,
|
||||
address sellAddr,
|
||||
uint256 buyAmt,
|
||||
uint256 unitAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _buyAmt = getUint(getId, buyAmt);
|
||||
(TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
|
||||
address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
|
||||
|
||||
uint _slippageAmt = convert18ToDec(_sellAddr.decimals(),
|
||||
wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt))
|
||||
);
|
||||
|
||||
checkPair(paths);
|
||||
uint _expectedAmt = getExpectedSellAmt(paths, _buyAmt);
|
||||
require(_slippageAmt >= _expectedAmt, "Too much slippage");
|
||||
|
||||
bool isEth = address(_sellAddr) == wethAddr;
|
||||
convertEthToWeth(isEth, _sellAddr, _expectedAmt);
|
||||
approve(_sellAddr, address(router), _expectedAmt);
|
||||
|
||||
uint _sellAmt = router.swapTokensForExactTokens(
|
||||
_buyAmt,
|
||||
_expectedAmt,
|
||||
paths,
|
||||
address(this),
|
||||
block.timestamp + 1
|
||||
)[0];
|
||||
|
||||
isEth = address(_buyAddr) == wethAddr;
|
||||
convertWethToEth(isEth, _buyAddr, _buyAmt);
|
||||
|
||||
setUint(setId, _sellAmt);
|
||||
|
||||
_eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sell ETH/ERC20_Token.
|
||||
* @notice Sell a token using a SushiSwap
|
||||
* @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAmt The amount of the token to sell.
|
||||
* @param unitAmt The unit amount of buyAmt/sellAmt with slippage.
|
||||
* @param getId ID to retrieve sellAmt.
|
||||
* @param setId ID stores the amount of token brought.
|
||||
*/
|
||||
function sell(
|
||||
address buyAddr,
|
||||
address sellAddr,
|
||||
uint256 sellAmt,
|
||||
uint256 unitAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _sellAmt = getUint(getId, sellAmt);
|
||||
(TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
|
||||
address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
|
||||
|
||||
if (_sellAmt == uint(-1)) {
|
||||
_sellAmt = sellAddr == ethAddr ?
|
||||
address(this).balance :
|
||||
_sellAddr.balanceOf(address(this));
|
||||
}
|
||||
|
||||
uint _slippageAmt = convert18ToDec(_buyAddr.decimals(),
|
||||
wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt))
|
||||
);
|
||||
|
||||
checkPair(paths);
|
||||
uint _expectedAmt = getExpectedBuyAmt(paths, _sellAmt);
|
||||
require(_slippageAmt <= _expectedAmt, "Too much slippage");
|
||||
|
||||
bool isEth = address(_sellAddr) == wethAddr;
|
||||
convertEthToWeth(isEth, _sellAddr, _sellAmt);
|
||||
approve(_sellAddr, address(router), _sellAmt);
|
||||
|
||||
uint _buyAmt = router.swapExactTokensForTokens(
|
||||
_sellAmt,
|
||||
_expectedAmt,
|
||||
paths,
|
||||
address(this),
|
||||
block.timestamp + 1
|
||||
)[1];
|
||||
|
||||
isEth = address(_buyAddr) == wethAddr;
|
||||
convertWethToEth(isEth, _buyAddr, _buyAmt);
|
||||
|
||||
setUint(setId, _buyAmt);
|
||||
|
||||
_eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2Sushiswap is SushipswapResolver {
|
||||
string public constant name = "Sushipswap-v1.1";
|
||||
}
|
25
contracts/mainnet/connectors/ubiquity/events.sol
Normal file
25
contracts/mainnet/connectors/ubiquity/events.sol
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.7.6;
|
||||
|
||||
contract Events {
|
||||
event LogDeposit(
|
||||
address indexed userAddress,
|
||||
address indexed token,
|
||||
uint256 amount,
|
||||
uint256 indexed bondingShareId,
|
||||
uint256 lpAmount,
|
||||
uint256 durationWeeks,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
event LogWithdraw(
|
||||
address indexed userAddress,
|
||||
uint256 indexed bondingShareId,
|
||||
uint256 lpAmount,
|
||||
uint256 endBlock,
|
||||
address indexed token,
|
||||
uint256 amount,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
}
|
55
contracts/mainnet/connectors/ubiquity/helpers.sol
Normal file
55
contracts/mainnet/connectors/ubiquity/helpers.sol
Normal file
|
@ -0,0 +1,55 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.7.6;
|
||||
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { IUbiquityAlgorithmicDollarManager } from "./interfaces.sol";
|
||||
|
||||
abstract contract Helpers is Basic {
|
||||
/**
|
||||
* @dev Ubiquity Algorithmic Dollar Manager
|
||||
*/
|
||||
IUbiquityAlgorithmicDollarManager internal constant ubiquityManager =
|
||||
IUbiquityAlgorithmicDollarManager(
|
||||
0x4DA97a8b831C345dBe6d16FF7432DF2b7b776d98
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev DAI Address
|
||||
*/
|
||||
address internal constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
|
||||
|
||||
/**
|
||||
* @dev USDC Address
|
||||
*/
|
||||
address internal constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
|
||||
|
||||
/**
|
||||
* @dev USDT Address
|
||||
*/
|
||||
address internal constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
|
||||
|
||||
/**
|
||||
* @dev Curve 3CRV Token Address
|
||||
*/
|
||||
address internal constant CRV3 = 0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490;
|
||||
|
||||
/**
|
||||
* @dev Curve 3Pool Address
|
||||
*/
|
||||
address internal constant Pool3 =
|
||||
0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7;
|
||||
|
||||
/**
|
||||
* @dev Ubiquity Algorithmic Dollar Address
|
||||
*/
|
||||
function getUAD() internal returns (address) {
|
||||
return ubiquityManager.dollarTokenAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Ubiquity Metapool uAD / 3CRV Address
|
||||
*/
|
||||
function getUADCRV3() internal returns (address) {
|
||||
return ubiquityManager.stableSwapMetaPoolAddress();
|
||||
}
|
||||
}
|
63
contracts/mainnet/connectors/ubiquity/interfaces.sol
Normal file
63
contracts/mainnet/connectors/ubiquity/interfaces.sol
Normal file
|
@ -0,0 +1,63 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
interface IUbiquityBondingV2 {
|
||||
struct Bond {
|
||||
address minter;
|
||||
uint256 lpFirstDeposited;
|
||||
uint256 creationBlock;
|
||||
uint256 lpRewardDebt;
|
||||
uint256 endBlock;
|
||||
uint256 lpAmount;
|
||||
}
|
||||
|
||||
function deposit(uint256 lpAmount, uint256 durationWeeks)
|
||||
external
|
||||
returns (uint256 bondingShareId);
|
||||
|
||||
function removeLiquidity(uint256 lpAmount, uint256 bondId) external;
|
||||
|
||||
function holderTokens(address) external view returns (uint256[] memory);
|
||||
|
||||
function totalLP() external view returns (uint256);
|
||||
|
||||
function totalSupply() external view returns (uint256);
|
||||
|
||||
function getBond(uint256 bondId) external returns (Bond memory bond);
|
||||
}
|
||||
|
||||
interface IUbiquityMetaPool {
|
||||
function add_liquidity(uint256[2] memory _amounts, uint256 _min_mint_amount)
|
||||
external
|
||||
returns (uint256);
|
||||
|
||||
function remove_liquidity_one_coin(
|
||||
uint256 lpAmount,
|
||||
int128 i,
|
||||
uint256 min_amount
|
||||
) external returns (uint256);
|
||||
}
|
||||
|
||||
interface I3Pool {
|
||||
function add_liquidity(
|
||||
uint256[3] calldata _amounts,
|
||||
uint256 _min_mint_amount
|
||||
) external;
|
||||
|
||||
function remove_liquidity_one_coin(
|
||||
uint256 lpAmount,
|
||||
int128 i,
|
||||
uint256 min_amount
|
||||
) external;
|
||||
}
|
||||
|
||||
interface IUbiquityAlgorithmicDollarManager {
|
||||
function dollarTokenAddress() external returns (address);
|
||||
|
||||
function stableSwapMetaPoolAddress() external returns (address);
|
||||
|
||||
function bondingContractAddress() external returns (address);
|
||||
|
||||
function bondingShareAddress() external returns (address);
|
||||
}
|
222
contracts/mainnet/connectors/ubiquity/main.sol
Normal file
222
contracts/mainnet/connectors/ubiquity/main.sol
Normal file
|
@ -0,0 +1,222 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
/**
|
||||
* @title Ubiquity.
|
||||
* @dev Ubiquity Dollar (uAD).
|
||||
*/
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { IUbiquityBondingV2, IUbiquityMetaPool, I3Pool } from "./interfaces.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract UbiquityResolver is Helpers, Events {
|
||||
/**
|
||||
* @dev Deposit into Ubiquity protocol
|
||||
* @notice 3POOL (DAI / USDC / USDT) => METAPOOL (3CRV / uAD) => uAD3CRV-f => Ubiquity BondingShare
|
||||
* @notice STEP 1 : 3POOL (DAI / USDC / USDT) => 3CRV
|
||||
* @notice STEP 2 : METAPOOL(3CRV / UAD) => uAD3CRV-f
|
||||
* @notice STEP 3 : uAD3CRV-f => Ubiquity BondingShare
|
||||
* @param token Token deposited : DAI, USDC, USDT, 3CRV, uAD or uAD3CRV-f
|
||||
* @param amount Amount of tokens to deposit (For max: `uint256(-1)`)
|
||||
* @param durationWeeks Duration in weeks tokens will be locked (4-208)
|
||||
* @param getId ID to retrieve amt.
|
||||
* @param setId ID stores the bonding share id of tokens deposited.
|
||||
*/
|
||||
function deposit(
|
||||
address token,
|
||||
uint256 amount,
|
||||
uint256 durationWeeks,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
address UAD3CRVf = getUADCRV3();
|
||||
bool[6] memory tok = [
|
||||
token == DAI, // 0
|
||||
token == USDC, // 1
|
||||
token == USDT, // 2
|
||||
token == CRV3, // 3
|
||||
token == getUAD(), // 4
|
||||
token == UAD3CRVf // 5
|
||||
];
|
||||
|
||||
require(
|
||||
// DAI / USDC / USDT / CRV3 / UAD / UAD3CRVF
|
||||
tok[0] || tok[1] || tok[2] || tok[3] || tok[4] || tok[5],
|
||||
"Invalid token: must be DAI, USDC, USDT, 3CRV, uAD or uAD3CRV-f"
|
||||
);
|
||||
|
||||
uint256 _amount = getUint(getId, amount);
|
||||
uint256 lpAmount;
|
||||
|
||||
// Full balance if amount = -1
|
||||
if (_amount == uint256(-1)) {
|
||||
_amount = getTokenBal(TokenInterface(token));
|
||||
}
|
||||
|
||||
// STEP 1 : SwapTo3CRV : Deposit DAI, USDC or USDT into 3Pool to get 3Crv LPs
|
||||
// DAI / USDC / USDT
|
||||
if (tok[0] || tok[1] || tok[2]) {
|
||||
uint256[3] memory amounts1;
|
||||
|
||||
if (tok[0]) amounts1[0] = _amount;
|
||||
else if (tok[1]) amounts1[1] = _amount;
|
||||
else if (tok[2]) amounts1[2] = _amount;
|
||||
|
||||
approve(TokenInterface(token), Pool3, _amount);
|
||||
I3Pool(Pool3).add_liquidity(amounts1, 0);
|
||||
}
|
||||
|
||||
// STEP 2 : ProvideLiquidityToMetapool : Deposit in uAD3CRV pool to get uAD3CRV-f LPs
|
||||
// DAI / USDC / USDT / CRV3 / UAD
|
||||
if (tok[0] || tok[1] || tok[2] || tok[3] || tok[4]) {
|
||||
uint256[2] memory amounts2;
|
||||
address token2 = token;
|
||||
uint256 _amount2;
|
||||
|
||||
if (tok[4]) {
|
||||
_amount2 = _amount;
|
||||
amounts2[0] = _amount2;
|
||||
} else {
|
||||
if (tok[3]) {
|
||||
_amount2 = _amount;
|
||||
} else {
|
||||
token2 = CRV3;
|
||||
_amount2 = getTokenBal(TokenInterface(token2));
|
||||
}
|
||||
amounts2[1] = _amount2;
|
||||
}
|
||||
|
||||
approve(TokenInterface(token2), UAD3CRVf, _amount2);
|
||||
lpAmount = IUbiquityMetaPool(UAD3CRVf).add_liquidity(amounts2, 0);
|
||||
}
|
||||
|
||||
// STEP 3 : Farm/ApeIn : Deposit uAD3CRV-f LPs into UbiquityBondingV2 and get Ubiquity Bonding Shares
|
||||
// UAD3CRVF
|
||||
if (tok[5]) {
|
||||
lpAmount = _amount;
|
||||
}
|
||||
|
||||
address bonding = ubiquityManager.bondingContractAddress();
|
||||
approve(TokenInterface(UAD3CRVf), bonding, lpAmount);
|
||||
uint256 bondingShareId = IUbiquityBondingV2(bonding).deposit(
|
||||
lpAmount,
|
||||
durationWeeks
|
||||
);
|
||||
|
||||
setUint(setId, bondingShareId);
|
||||
|
||||
_eventName = "LogDeposit(address,address,uint256,uint256,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
address(this),
|
||||
token,
|
||||
amount,
|
||||
bondingShareId,
|
||||
lpAmount,
|
||||
durationWeeks,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw from Ubiquity protocol
|
||||
* @notice Ubiquity BondingShare => uAD3CRV-f => METAPOOL (3CRV / uAD) => 3POOL (DAI / USDC / USDT)
|
||||
* @notice STEP 1 : Ubiquity BondingShare => uAD3CRV-f
|
||||
* @notice STEP 2 : uAD3CRV-f => METAPOOL(3CRV / UAD)
|
||||
* @notice STEP 3 : 3CRV => 3POOL (DAI / USDC / USDT)
|
||||
* @param bondingShareId Bonding Share Id to withdraw
|
||||
* @param token Token to withdraw to : DAI, USDC, USDT, 3CRV, uAD or uAD3CRV-f
|
||||
* @param getId ID
|
||||
* @param setId ID
|
||||
*/
|
||||
function withdraw(
|
||||
uint256 bondingShareId,
|
||||
address token,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
address UAD3CRVf = getUADCRV3();
|
||||
bool[6] memory tok = [
|
||||
token == DAI, // 0
|
||||
token == USDC, // 1
|
||||
token == USDT, // 2
|
||||
token == CRV3, // 3
|
||||
token == getUAD(), // 4
|
||||
token == UAD3CRVf // 5
|
||||
];
|
||||
|
||||
require(
|
||||
// DAI / USDC / USDT / CRV3 / UAD / UAD3CRVF
|
||||
tok[0] || tok[1] || tok[2] || tok[3] || tok[4] || tok[5],
|
||||
"Invalid token: must be DAI, USDC, USDT, 3CRV, uAD or uAD3CRV-f"
|
||||
);
|
||||
|
||||
uint256 _bondingShareId = getUint(getId, bondingShareId);
|
||||
|
||||
// Get Bond
|
||||
IUbiquityBondingV2.Bond memory bond = IUbiquityBondingV2(
|
||||
ubiquityManager.bondingShareAddress()
|
||||
).getBond(_bondingShareId);
|
||||
|
||||
require(address(this) == bond.minter, "Not bond owner");
|
||||
|
||||
// STEP 1 : Withdraw Ubiquity Bonding Shares to get back uAD3CRV-f LPs
|
||||
address bonding = ubiquityManager.bondingContractAddress();
|
||||
IUbiquityBondingV2(bonding).removeLiquidity(
|
||||
bond.lpAmount,
|
||||
_bondingShareId
|
||||
);
|
||||
|
||||
// STEP 2 : Withdraw uAD3CRV-f LPs to get back uAD or 3Crv
|
||||
// DAI / USDC / USDT / CRV3 / UAD
|
||||
if (tok[0] || tok[1] || tok[2] || tok[3] || tok[4]) {
|
||||
uint256 amount2 = getTokenBal(TokenInterface(UAD3CRVf));
|
||||
IUbiquityMetaPool(UAD3CRVf).remove_liquidity_one_coin(
|
||||
amount2,
|
||||
tok[4] ? 0 : 1,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
// STEP 3 : Withdraw 3Crv LPs from 3Pool to get back DAI, USDC or USDT
|
||||
// DAI / USDC / USDT
|
||||
if (tok[0] || tok[1] || tok[2]) {
|
||||
uint256 amount1 = getTokenBal(TokenInterface(CRV3));
|
||||
I3Pool(Pool3).remove_liquidity_one_coin(
|
||||
amount1,
|
||||
tok[0] ? 0 : (tok[1] ? 1 : 2),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
uint256 amount = getTokenBal(TokenInterface(token));
|
||||
|
||||
setUint(setId, amount);
|
||||
_eventName = "LogWithdraw(address,uint256,uint256,uint256,address,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
address(this),
|
||||
_bondingShareId,
|
||||
bond.lpAmount,
|
||||
bond.endBlock,
|
||||
token,
|
||||
amount,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2Ubiquity is UbiquityResolver {
|
||||
string public constant name = "Ubiquity-v1";
|
||||
}
|
12
contracts/polygon/connectors/1inch/1inch-v3/events.sol
Normal file
12
contracts/polygon/connectors/1inch/1inch-v3/events.sol
Normal file
|
@ -0,0 +1,12 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogSell(
|
||||
address indexed buyToken,
|
||||
address indexed sellToken,
|
||||
uint256 buyAmt,
|
||||
uint256 sellAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
import { DSMath } from "../../../common/math.sol";
|
||||
import { Basic } from "../../../common/basic.sol";
|
||||
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
30
contracts/polygon/connectors/1inch/1inch-v3/interface.sol
Normal file
30
contracts/polygon/connectors/1inch/1inch-v3/interface.sol
Normal file
|
@ -0,0 +1,30 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
|
||||
interface OneInchInterace {
|
||||
function swap(
|
||||
TokenInterface fromToken,
|
||||
TokenInterface toToken,
|
||||
uint256 fromTokenAmount,
|
||||
uint256 minReturnAmount,
|
||||
uint256 guaranteedAmount,
|
||||
address payable referrer,
|
||||
address[] calldata callAddresses,
|
||||
bytes calldata callDataConcat,
|
||||
uint256[] calldata starts,
|
||||
uint256[] calldata gasLimitsAndValues
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint256 returnAmount);
|
||||
}
|
||||
|
||||
struct OneInchData {
|
||||
TokenInterface sellToken;
|
||||
TokenInterface buyToken;
|
||||
uint _sellAmt;
|
||||
uint _buyAmt;
|
||||
uint unitAmt;
|
||||
bytes callData;
|
||||
}
|
|
@ -2,13 +2,13 @@ pragma solidity ^0.7.0;
|
|||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title 1Inch.
|
||||
* @title 1InchV3.
|
||||
* @dev On-chain DEX Aggregator.
|
||||
*/
|
||||
|
||||
// import files from common directory
|
||||
import { TokenInterface , MemoryInterface } from "../../common/interfaces.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { TokenInterface , MemoryInterface } from "../../../common/interfaces.sol";
|
||||
import { Stores } from "../../../common/stores.sol";
|
||||
import { OneInchInterace, OneInchData } from "./interface.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
@ -123,6 +123,6 @@ abstract contract OneInch is OneInchResolverHelpers {
|
|||
}
|
||||
}
|
||||
|
||||
contract ConnectV2OneInchPolygon is OneInch {
|
||||
contract ConnectV2OneInchV3Polygon is OneInch {
|
||||
string public name = "1Inch-v1";
|
||||
}
|
12
contracts/polygon/connectors/1inch/1inch-v4/events.sol
Normal file
12
contracts/polygon/connectors/1inch/1inch-v4/events.sol
Normal file
|
@ -0,0 +1,12 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogSell(
|
||||
address indexed buyToken,
|
||||
address indexed sellToken,
|
||||
uint256 buyAmt,
|
||||
uint256 sellAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
}
|
13
contracts/polygon/connectors/1inch/1inch-v4/helpers.sol
Normal file
13
contracts/polygon/connectors/1inch/1inch-v4/helpers.sol
Normal file
|
@ -0,0 +1,13 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
import { DSMath } from "../../../common/math.sol";
|
||||
import { Basic } from "../../../common/basic.sol";
|
||||
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev 1Inch Address
|
||||
*/
|
||||
address internal constant oneInchAddr = 0x1111111254fb6c44bAC0beD2854e76F90643097d;
|
||||
}
|
30
contracts/polygon/connectors/1inch/1inch-v4/interface.sol
Normal file
30
contracts/polygon/connectors/1inch/1inch-v4/interface.sol
Normal file
|
@ -0,0 +1,30 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
|
||||
interface OneInchInterace {
|
||||
function swap(
|
||||
TokenInterface fromToken,
|
||||
TokenInterface toToken,
|
||||
uint256 fromTokenAmount,
|
||||
uint256 minReturnAmount,
|
||||
uint256 guaranteedAmount,
|
||||
address payable referrer,
|
||||
address[] calldata callAddresses,
|
||||
bytes calldata callDataConcat,
|
||||
uint256[] calldata starts,
|
||||
uint256[] calldata gasLimitsAndValues
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint256 returnAmount);
|
||||
}
|
||||
|
||||
struct OneInchData {
|
||||
TokenInterface sellToken;
|
||||
TokenInterface buyToken;
|
||||
uint _sellAmt;
|
||||
uint _buyAmt;
|
||||
uint unitAmt;
|
||||
bytes callData;
|
||||
}
|
115
contracts/polygon/connectors/1inch/1inch-v4/main.sol
Normal file
115
contracts/polygon/connectors/1inch/1inch-v4/main.sol
Normal file
|
@ -0,0 +1,115 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title 1InchV4.
|
||||
* @dev On-chain DEX Aggregator.
|
||||
*/
|
||||
|
||||
// import files from common directory
|
||||
import { TokenInterface , MemoryInterface } from "../../../common/interfaces.sol";
|
||||
import { Stores } from "../../../common/stores.sol";
|
||||
import { OneInchInterace, OneInchData } from "./interface.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract OneInchResolver is Helpers, Events {
|
||||
|
||||
|
||||
/**
|
||||
* @dev 1inch API swap handler
|
||||
* @param oneInchData - contains data returned from 1inch API. Struct defined in interfaces.sol
|
||||
* @param ethAmt - Eth to swap for .value()
|
||||
*/
|
||||
function oneInchSwap(
|
||||
OneInchData memory oneInchData,
|
||||
uint ethAmt
|
||||
) internal returns (uint buyAmt) {
|
||||
TokenInterface buyToken = oneInchData.buyToken;
|
||||
(uint _buyDec, uint _sellDec) = getTokensDec(buyToken, oneInchData.sellToken);
|
||||
uint _sellAmt18 = convertTo18(_sellDec, oneInchData._sellAmt);
|
||||
uint _slippageAmt = convert18ToDec(_buyDec, wmul(oneInchData.unitAmt, _sellAmt18));
|
||||
|
||||
uint initalBal = getTokenBal(buyToken);
|
||||
|
||||
// solium-disable-next-line security/no-call-value
|
||||
(bool success, ) = oneInchAddr.call{value: ethAmt}(oneInchData.callData);
|
||||
if (!success) revert("1Inch-swap-failed");
|
||||
|
||||
uint finalBal = getTokenBal(buyToken);
|
||||
|
||||
buyAmt = sub(finalBal, initalBal);
|
||||
|
||||
require(_slippageAmt <= buyAmt, "Too much slippage");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract contract OneInchResolverHelpers is OneInchResolver {
|
||||
|
||||
/**
|
||||
* @dev Gets the swapping data from 1inch's API.
|
||||
* @param oneInchData Struct with multiple swap data defined in interfaces.sol
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function _sell(
|
||||
OneInchData memory oneInchData,
|
||||
uint setId
|
||||
) internal returns (OneInchData memory) {
|
||||
TokenInterface _sellAddr = oneInchData.sellToken;
|
||||
|
||||
uint ethAmt;
|
||||
if (address(_sellAddr) == maticAddr) {
|
||||
ethAmt = oneInchData._sellAmt;
|
||||
} else {
|
||||
approve(TokenInterface(_sellAddr), oneInchAddr, oneInchData._sellAmt);
|
||||
}
|
||||
|
||||
|
||||
oneInchData._buyAmt = oneInchSwap(oneInchData, ethAmt);
|
||||
setUint(setId, oneInchData._buyAmt);
|
||||
|
||||
return oneInchData;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
abstract contract OneInch is OneInchResolverHelpers {
|
||||
/**
|
||||
* @dev Sell ETH/ERC20_Token using 1Inch.
|
||||
* @notice Swap tokens from exchanges like kyber, 0x etc, with calculation done off-chain.
|
||||
* @param buyAddr The address of the token to buy.(For MATIC: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAddr The address of the token to sell.(For MATIC: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAmt The amount of the token to sell.
|
||||
* @param unitAmt The amount of buyAmt/sellAmt with slippage.
|
||||
* @param callData Data from 1inch API.
|
||||
* @param setId ID stores the amount of token brought.
|
||||
*/
|
||||
function sell(
|
||||
address buyAddr,
|
||||
address sellAddr,
|
||||
uint sellAmt,
|
||||
uint unitAmt,
|
||||
bytes calldata callData,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
OneInchData memory oneInchData = OneInchData({
|
||||
buyToken: TokenInterface(buyAddr),
|
||||
sellToken: TokenInterface(sellAddr),
|
||||
unitAmt: unitAmt,
|
||||
callData: callData,
|
||||
_sellAmt: sellAmt,
|
||||
_buyAmt: 0
|
||||
});
|
||||
|
||||
oneInchData = _sell(oneInchData, setId);
|
||||
|
||||
_eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(buyAddr, sellAddr, oneInchData._buyAmt, oneInchData._sellAmt, 0, setId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2OneInchV4Polygon is OneInch {
|
||||
string public name = "1Inch-v4-v1";
|
||||
}
|
|
@ -16,7 +16,7 @@ abstract contract Helpers is DSMath, Basic {
|
|||
bytes callData;
|
||||
}
|
||||
|
||||
address internal constant paraswap = 0x90249ed4d69D70E709fFCd8beE2c5A566f65dADE;
|
||||
address internal constant paraswap = 0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57;
|
||||
|
||||
function _swapHelper(SwapData memory swapData, uint256 wmaticAmt) internal returns (uint256 buyAmt) {
|
||||
TokenInterface buyToken = swapData.buyToken;
|
||||
|
|
|
@ -50,6 +50,6 @@ abstract contract ParaswapResolver is Helpers {
|
|||
}
|
||||
}
|
||||
|
||||
contract ConnectV2Paraswap is ParaswapResolver {
|
||||
string public name = "Paraswap-v1";
|
||||
contract ConnectV2ParaswapV5Polygon is ParaswapResolver {
|
||||
string public name = "Paraswap-v5";
|
||||
}
|
41
contracts/polygon/connectors/quickswap/events.sol
Normal file
41
contracts/polygon/connectors/quickswap/events.sol
Normal file
|
@ -0,0 +1,41 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogDepositLiquidity(
|
||||
address indexed tokenA,
|
||||
address indexed tokenB,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
uint256 uniAmount,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawLiquidity(
|
||||
address indexed tokenA,
|
||||
address indexed tokenB,
|
||||
uint256 amountA,
|
||||
uint256 amountB,
|
||||
uint256 uniAmount,
|
||||
uint256 getId,
|
||||
uint256[] setId
|
||||
);
|
||||
|
||||
event LogBuy(
|
||||
address indexed buyToken,
|
||||
address indexed sellToken,
|
||||
uint256 buyAmt,
|
||||
uint256 sellAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogSell(
|
||||
address indexed buyToken,
|
||||
address indexed sellToken,
|
||||
uint256 buyAmt,
|
||||
uint256 sellAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
}
|
184
contracts/polygon/connectors/quickswap/helpers.sol
Normal file
184
contracts/polygon/connectors/quickswap/helpers.sol
Normal file
|
@ -0,0 +1,184 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { IQuickSwapRouter, IQuickSwapFactory } from "./interface.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev IQuickSwapRouter
|
||||
*/
|
||||
IQuickSwapRouter internal constant router =
|
||||
IQuickSwapRouter(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff);
|
||||
|
||||
function getExpectedBuyAmt(address[] memory paths, uint256 sellAmt)
|
||||
internal
|
||||
view
|
||||
returns (uint256 buyAmt)
|
||||
{
|
||||
uint256[] memory amts = router.getAmountsOut(sellAmt, paths);
|
||||
buyAmt = amts[1];
|
||||
}
|
||||
|
||||
function getExpectedSellAmt(address[] memory paths, uint256 buyAmt)
|
||||
internal
|
||||
view
|
||||
returns (uint256 sellAmt)
|
||||
{
|
||||
uint256[] memory amts = router.getAmountsIn(buyAmt, paths);
|
||||
sellAmt = amts[0];
|
||||
}
|
||||
|
||||
function checkPair(address[] memory paths) internal view {
|
||||
address pair = IQuickSwapFactory(router.factory()).getPair(
|
||||
paths[0],
|
||||
paths[1]
|
||||
);
|
||||
require(pair != address(0), "No-exchange-address");
|
||||
}
|
||||
|
||||
function getPaths(address buyAddr, address sellAddr)
|
||||
internal
|
||||
pure
|
||||
returns (address[] memory paths)
|
||||
{
|
||||
paths = new address[](2);
|
||||
paths[0] = address(sellAddr);
|
||||
paths[1] = address(buyAddr);
|
||||
}
|
||||
|
||||
function getMinAmount(
|
||||
TokenInterface token,
|
||||
uint256 amt,
|
||||
uint256 slippage
|
||||
) internal view returns (uint256 minAmt) {
|
||||
uint256 _amt18 = convertTo18(token.decimals(), amt);
|
||||
minAmt = wmul(_amt18, sub(WAD, slippage));
|
||||
minAmt = convert18ToDec(token.decimals(), minAmt);
|
||||
}
|
||||
|
||||
function _addLiquidity(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 _amt,
|
||||
uint256 unitAmt,
|
||||
uint256 slippage
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint256 _amtA,
|
||||
uint256 _amtB,
|
||||
uint256 _liquidity
|
||||
)
|
||||
{
|
||||
(TokenInterface _tokenA, TokenInterface _tokenB) = changeMaticAddress(
|
||||
tokenA,
|
||||
tokenB
|
||||
);
|
||||
|
||||
_amtA = _amt == uint256(-1)
|
||||
? getTokenBal(TokenInterface(tokenA))
|
||||
: _amt;
|
||||
_amtB = convert18ToDec(
|
||||
_tokenB.decimals(),
|
||||
wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA))
|
||||
);
|
||||
|
||||
bool isMatic = address(_tokenA) == wmaticAddr;
|
||||
convertMaticToWmatic(isMatic, _tokenA, _amtA);
|
||||
|
||||
isMatic = address(_tokenB) == wmaticAddr;
|
||||
convertMaticToWmatic(isMatic, _tokenB, _amtB);
|
||||
|
||||
approve(_tokenA, address(router), _amtA);
|
||||
approve(_tokenB, address(router), _amtB);
|
||||
|
||||
uint256 minAmtA = getMinAmount(_tokenA, _amtA, slippage);
|
||||
uint256 minAmtB = getMinAmount(_tokenB, _amtB, slippage);
|
||||
(_amtA, _amtB, _liquidity) = router.addLiquidity(
|
||||
address(_tokenA),
|
||||
address(_tokenB),
|
||||
_amtA,
|
||||
_amtB,
|
||||
minAmtA,
|
||||
minAmtB,
|
||||
address(this),
|
||||
block.timestamp + 1
|
||||
);
|
||||
}
|
||||
|
||||
function _removeLiquidity(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 _amt,
|
||||
uint256 unitAmtA,
|
||||
uint256 unitAmtB
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint256 _amtA,
|
||||
uint256 _amtB,
|
||||
uint256 _uniAmt
|
||||
)
|
||||
{
|
||||
TokenInterface _tokenA;
|
||||
TokenInterface _tokenB;
|
||||
(_tokenA, _tokenB, _uniAmt) = _getRemoveLiquidityData(
|
||||
tokenA,
|
||||
tokenB,
|
||||
_amt
|
||||
);
|
||||
{
|
||||
uint256 minAmtA = convert18ToDec(
|
||||
_tokenA.decimals(),
|
||||
wmul(unitAmtA, _uniAmt)
|
||||
);
|
||||
uint256 minAmtB = convert18ToDec(
|
||||
_tokenB.decimals(),
|
||||
wmul(unitAmtB, _uniAmt)
|
||||
);
|
||||
(_amtA, _amtB) = router.removeLiquidity(
|
||||
address(_tokenA),
|
||||
address(_tokenB),
|
||||
_uniAmt,
|
||||
minAmtA,
|
||||
minAmtB,
|
||||
address(this),
|
||||
block.timestamp + 1
|
||||
);
|
||||
}
|
||||
|
||||
bool isMatic = address(_tokenA) == wmaticAddr;
|
||||
convertWmaticToMatic(isMatic, _tokenA, _amtA);
|
||||
|
||||
isMatic = address(_tokenB) == wmaticAddr;
|
||||
convertWmaticToMatic(isMatic, _tokenB, _amtB);
|
||||
}
|
||||
|
||||
function _getRemoveLiquidityData(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 _amt
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
TokenInterface _tokenA,
|
||||
TokenInterface _tokenB,
|
||||
uint256 _uniAmt
|
||||
)
|
||||
{
|
||||
(_tokenA, _tokenB) = changeMaticAddress(tokenA, tokenB);
|
||||
address exchangeAddr = IQuickSwapFactory(router.factory()).getPair(
|
||||
address(_tokenA),
|
||||
address(_tokenB)
|
||||
);
|
||||
require(exchangeAddr != address(0), "pair-not-found.");
|
||||
|
||||
TokenInterface uniToken = TokenInterface(exchangeAddr);
|
||||
_uniAmt = _amt == uint256(-1)
|
||||
? uniToken.balanceOf(address(this))
|
||||
: _amt;
|
||||
approve(uniToken, address(router), _uniAmt);
|
||||
}
|
||||
}
|
97
contracts/polygon/connectors/quickswap/interface.sol
Normal file
97
contracts/polygon/connectors/quickswap/interface.sol
Normal file
|
@ -0,0 +1,97 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
interface IQuickSwapRouter {
|
||||
function factory() external pure returns (address);
|
||||
|
||||
function WETH() external pure returns (address);
|
||||
|
||||
function addLiquidity(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 amountADesired,
|
||||
uint256 amountBDesired,
|
||||
uint256 amountAMin,
|
||||
uint256 amountBMin,
|
||||
address to,
|
||||
uint256 deadline
|
||||
)
|
||||
external
|
||||
returns (
|
||||
uint256 amountA,
|
||||
uint256 amountB,
|
||||
uint256 liquidity
|
||||
);
|
||||
|
||||
function removeLiquidity(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 liquidity,
|
||||
uint256 amountAMin,
|
||||
uint256 amountBMin,
|
||||
address to,
|
||||
uint256 deadline
|
||||
) external returns (uint256 amountA, uint256 amountB);
|
||||
|
||||
function swapExactTokensForTokens(
|
||||
uint256 amountIn,
|
||||
uint256 amountOutMin,
|
||||
address[] calldata path,
|
||||
address to,
|
||||
uint256 deadline
|
||||
) external returns (uint256[] memory amounts);
|
||||
|
||||
function swapTokensForExactTokens(
|
||||
uint256 amountOut,
|
||||
uint256 amountInMax,
|
||||
address[] calldata path,
|
||||
address to,
|
||||
uint256 deadline
|
||||
) external returns (uint256[] memory amounts);
|
||||
|
||||
function quote(
|
||||
uint256 amountA,
|
||||
uint256 reserveA,
|
||||
uint256 reserveB
|
||||
) external pure returns (uint256 amountB);
|
||||
|
||||
function getAmountOut(
|
||||
uint256 amountIn,
|
||||
uint256 reserveIn,
|
||||
uint256 reserveOut
|
||||
) external pure returns (uint256 amountOut);
|
||||
|
||||
function getAmountIn(
|
||||
uint256 amountOut,
|
||||
uint256 reserveIn,
|
||||
uint256 reserveOut
|
||||
) external pure returns (uint256 amountIn);
|
||||
|
||||
function getAmountsOut(uint256 amountIn, address[] calldata path)
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory amounts);
|
||||
|
||||
function getAmountsIn(uint256 amountOut, address[] calldata path)
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory amounts);
|
||||
}
|
||||
|
||||
interface IQuickSwapFactory {
|
||||
function getPair(address tokenA, address tokenB)
|
||||
external
|
||||
view
|
||||
returns (address pair);
|
||||
|
||||
function allPairs(uint256) external view returns (address pair);
|
||||
|
||||
function allPairsLength() external view returns (uint256);
|
||||
|
||||
function feeTo() external view returns (address);
|
||||
|
||||
function feeToSetter() external view returns (address);
|
||||
|
||||
function createPair(address tokenA, address tokenB)
|
||||
external
|
||||
returns (address pair);
|
||||
}
|
256
contracts/polygon/connectors/quickswap/main.sol
Normal file
256
contracts/polygon/connectors/quickswap/main.sol
Normal file
|
@ -0,0 +1,256 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title QuickSwap.
|
||||
* @dev Decentralized Exchange.
|
||||
*/
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract QuickpswapResolver is Helpers, Events {
|
||||
/**
|
||||
* @dev Deposit Liquidity.
|
||||
* @notice Deposit Liquidity to a QuickSwap pool.
|
||||
* @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amtA The amount of A tokens to deposit.
|
||||
* @param unitAmt The unit amount of of amtB/amtA with slippage.
|
||||
* @param slippage Slippage amount.
|
||||
* @param getId ID to retrieve amtA.
|
||||
* @param setId ID stores the amount of pools tokens received.
|
||||
*/
|
||||
function deposit(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 amtA,
|
||||
uint256 unitAmt,
|
||||
uint256 slippage,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(getId, amtA);
|
||||
|
||||
(uint256 _amtA, uint256 _amtB, uint256 _uniAmt) = _addLiquidity(
|
||||
tokenA,
|
||||
tokenB,
|
||||
_amt,
|
||||
unitAmt,
|
||||
slippage
|
||||
);
|
||||
setUint(setId, _uniAmt);
|
||||
|
||||
_eventName = "LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
tokenA,
|
||||
tokenB,
|
||||
_amtA,
|
||||
_amtB,
|
||||
_uniAmt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw Liquidity.
|
||||
* @notice Withdraw Liquidity from a QuickSwap pool.
|
||||
* @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param uniAmt The amount of pool tokens to withdraw.
|
||||
* @param unitAmtA The unit amount of amtA/uniAmt with slippage.
|
||||
* @param unitAmtB The unit amount of amtB/uniAmt with slippage.
|
||||
* @param getId ID to retrieve uniAmt.
|
||||
* @param setIds Array of IDs to store the amount tokens received.
|
||||
*/
|
||||
function withdraw(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint256 uniAmt,
|
||||
uint256 unitAmtA,
|
||||
uint256 unitAmtB,
|
||||
uint256 getId,
|
||||
uint256[] calldata setIds
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(getId, uniAmt);
|
||||
|
||||
(uint256 _amtA, uint256 _amtB, uint256 _uniAmt) = _removeLiquidity(
|
||||
tokenA,
|
||||
tokenB,
|
||||
_amt,
|
||||
unitAmtA,
|
||||
unitAmtB
|
||||
);
|
||||
|
||||
setUint(setIds[0], _amtA);
|
||||
setUint(setIds[1], _amtB);
|
||||
|
||||
_eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])";
|
||||
_eventParam = abi.encode(
|
||||
tokenA,
|
||||
tokenB,
|
||||
_amtA,
|
||||
_amtB,
|
||||
_uniAmt,
|
||||
getId,
|
||||
setIds
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Buy ETH/ERC20_Token.
|
||||
* @notice Buy a token using a QuickSwap
|
||||
* @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param buyAmt The amount of tokens to buy.
|
||||
* @param unitAmt The unit amount of sellAmt/buyAmt with slippage.
|
||||
* @param getId ID to retrieve buyAmt.
|
||||
* @param setId ID to store the amount of tokens sold.
|
||||
*/
|
||||
function buy(
|
||||
address buyAddr,
|
||||
address sellAddr,
|
||||
uint256 buyAmt,
|
||||
uint256 unitAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _buyAmt = getUint(getId, buyAmt);
|
||||
(
|
||||
TokenInterface _buyAddr,
|
||||
TokenInterface _sellAddr
|
||||
) = changeMaticAddress(buyAddr, sellAddr);
|
||||
address[] memory paths = getPaths(
|
||||
address(_buyAddr),
|
||||
address(_sellAddr)
|
||||
);
|
||||
|
||||
uint256 _slippageAmt = convert18ToDec(
|
||||
_sellAddr.decimals(),
|
||||
wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt))
|
||||
);
|
||||
|
||||
checkPair(paths);
|
||||
uint256 _expectedAmt = getExpectedSellAmt(paths, _buyAmt);
|
||||
require(_slippageAmt >= _expectedAmt, "Too much slippage");
|
||||
|
||||
bool isEth = address(_sellAddr) == wmaticAddr;
|
||||
convertMaticToWmatic(isEth, _sellAddr, _expectedAmt);
|
||||
approve(_sellAddr, address(router), _expectedAmt);
|
||||
|
||||
uint256 _sellAmt = router.swapTokensForExactTokens(
|
||||
_buyAmt,
|
||||
_expectedAmt,
|
||||
paths,
|
||||
address(this),
|
||||
block.timestamp + 1
|
||||
)[0];
|
||||
|
||||
isEth = address(_buyAddr) == wmaticAddr;
|
||||
convertWmaticToMatic(isEth, _buyAddr, _buyAmt);
|
||||
|
||||
setUint(setId, _sellAmt);
|
||||
|
||||
_eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
buyAddr,
|
||||
sellAddr,
|
||||
_buyAmt,
|
||||
_sellAmt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sell ETH/ERC20_Token.
|
||||
* @notice Sell a token using a QuickSwap
|
||||
* @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param sellAmt The amount of the token to sell.
|
||||
* @param unitAmt The unit amount of buyAmt/sellAmt with slippage.
|
||||
* @param getId ID to retrieve sellAmt.
|
||||
* @param setId ID stores the amount of token brought.
|
||||
*/
|
||||
function sell(
|
||||
address buyAddr,
|
||||
address sellAddr,
|
||||
uint256 sellAmt,
|
||||
uint256 unitAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _sellAmt = getUint(getId, sellAmt);
|
||||
(
|
||||
TokenInterface _buyAddr,
|
||||
TokenInterface _sellAddr
|
||||
) = changeMaticAddress(buyAddr, sellAddr);
|
||||
address[] memory paths = getPaths(
|
||||
address(_buyAddr),
|
||||
address(_sellAddr)
|
||||
);
|
||||
|
||||
if (_sellAmt == uint256(-1)) {
|
||||
_sellAmt = sellAddr == maticAddr
|
||||
? address(this).balance
|
||||
: _sellAddr.balanceOf(address(this));
|
||||
}
|
||||
|
||||
uint256 _slippageAmt = convert18ToDec(
|
||||
_buyAddr.decimals(),
|
||||
wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt))
|
||||
);
|
||||
|
||||
checkPair(paths);
|
||||
uint256 _expectedAmt = getExpectedBuyAmt(paths, _sellAmt);
|
||||
require(_slippageAmt <= _expectedAmt, "Too much slippage");
|
||||
|
||||
bool isEth = address(_sellAddr) == wmaticAddr;
|
||||
convertMaticToWmatic(isEth, _sellAddr, _sellAmt);
|
||||
approve(_sellAddr, address(router), _sellAmt);
|
||||
|
||||
uint256 _buyAmt = router.swapExactTokensForTokens(
|
||||
_sellAmt,
|
||||
_expectedAmt,
|
||||
paths,
|
||||
address(this),
|
||||
block.timestamp + 1
|
||||
)[1];
|
||||
|
||||
isEth = address(_buyAddr) == wmaticAddr;
|
||||
convertWmaticToMatic(isEth, _buyAddr, _buyAmt);
|
||||
|
||||
setUint(setId, _buyAmt);
|
||||
|
||||
_eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
buyAddr,
|
||||
sellAddr,
|
||||
_buyAmt,
|
||||
_sellAmt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2QuickswapPolygon is QuickpswapResolver {
|
||||
string public constant name = "Quickpswap-v1.1";
|
||||
}
|
42
contracts/polygon/connectors/uniswap/v3/events.sol
Normal file
42
contracts/polygon/connectors/uniswap/v3/events.sol
Normal file
|
@ -0,0 +1,42 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogcreateAndInitializePool (
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
address pool,
|
||||
uint24 fee,
|
||||
int24 initialTick
|
||||
);
|
||||
|
||||
event LogMint(
|
||||
uint256 indexed tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
int24 tickLower,
|
||||
int24 tickUpper
|
||||
);
|
||||
|
||||
event LogDeposit(
|
||||
uint256 indexed tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
);
|
||||
|
||||
event LogWithdraw(
|
||||
uint256 indexed tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
);
|
||||
|
||||
event LogCollect(
|
||||
uint256 tokenId,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
);
|
||||
|
||||
event LogBurnPosition(uint256 tokenId);
|
||||
}
|
308
contracts/polygon/connectors/uniswap/v3/helpers.sol
Normal file
308
contracts/polygon/connectors/uniswap/v3/helpers.sol
Normal file
|
@ -0,0 +1,308 @@
|
|||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
import { TokenInterface} from "../../../common/interfaces.sol";
|
||||
import { DSMath } from "../../../common/math.sol";
|
||||
import { Basic } from "../../../common/basic.sol";
|
||||
import "./interface.sol";
|
||||
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
|
||||
import "@uniswap/v3-core/contracts/libraries/TickMath.sol";
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
|
||||
import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev uniswap v3 NFT Position Manager & Swap Router
|
||||
*/
|
||||
INonfungiblePositionManager constant nftManager =
|
||||
INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);
|
||||
ISwapRouter constant swapRouter =
|
||||
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
|
||||
|
||||
struct MintParams {
|
||||
address tokenA;
|
||||
address tokenB;
|
||||
uint24 fee;
|
||||
int24 tickLower;
|
||||
int24 tickUpper;
|
||||
uint256 amtA;
|
||||
uint256 amtB;
|
||||
uint256 slippage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Get Last NFT Index
|
||||
* @param user: User address
|
||||
*/
|
||||
function _getLastNftId(address user)
|
||||
internal
|
||||
view
|
||||
returns (uint256 tokenId)
|
||||
{
|
||||
uint256 len = nftManager.balanceOf(user);
|
||||
tokenId = nftManager.tokenOfOwnerByIndex(user, len - 1);
|
||||
}
|
||||
|
||||
function getMinAmount(
|
||||
TokenInterface token,
|
||||
uint256 amt,
|
||||
uint256 slippage
|
||||
) internal view returns (uint256 minAmt) {
|
||||
uint256 _amt18 = convertTo18(token.decimals(), amt);
|
||||
minAmt = wmul(_amt18, sub(WAD, slippage));
|
||||
minAmt = convert18ToDec(token.decimals(), minAmt);
|
||||
}
|
||||
|
||||
function sortTokenAddress(address _token0, address _token1)
|
||||
internal
|
||||
view
|
||||
returns (address token0, address token1)
|
||||
{
|
||||
if (_token0 > _token1) {
|
||||
(token0, token1) = (_token1, _token0);
|
||||
} else {
|
||||
(token0, token1) = (_token0, _token1);
|
||||
}
|
||||
}
|
||||
|
||||
function _createAndInitializePoolIfNecessary (
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint24 fee,
|
||||
int24 initialTick
|
||||
) internal returns (address pool) {
|
||||
(TokenInterface token0Contract_, TokenInterface token1Contract_) = changeMaticAddress(
|
||||
tokenA,
|
||||
tokenB
|
||||
);
|
||||
|
||||
(address token0_, address token1_) = sortTokenAddress(address(token0Contract_), address(token1Contract_));
|
||||
|
||||
return nftManager.createAndInitializePoolIfNecessary(
|
||||
token0_,
|
||||
token1_,
|
||||
fee,
|
||||
TickMath.getSqrtRatioAtTick(initialTick)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Mint function which interact with Uniswap v3
|
||||
*/
|
||||
function _mint(MintParams memory params)
|
||||
internal
|
||||
returns (
|
||||
uint256 tokenId,
|
||||
uint128 liquidity,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
)
|
||||
{
|
||||
(TokenInterface _token0, TokenInterface _token1) = changeMaticAddress(
|
||||
params.tokenA,
|
||||
params.tokenB
|
||||
);
|
||||
|
||||
uint256 _amount0 = params.amtA == uint256(-1)
|
||||
? getTokenBal(TokenInterface(params.tokenA))
|
||||
: params.amtA;
|
||||
uint256 _amount1 = params.amtB == uint256(-1)
|
||||
? getTokenBal(TokenInterface(params.tokenB))
|
||||
: params.amtB;
|
||||
|
||||
convertMaticToWmatic(address(_token0) == wmaticAddr, _token0, _amount0);
|
||||
convertMaticToWmatic(address(_token1) == wmaticAddr, _token1, _amount1);
|
||||
|
||||
approve(_token0, address(nftManager), _amount0);
|
||||
approve(_token1, address(nftManager), _amount1);
|
||||
|
||||
{
|
||||
(address token0, ) = sortTokenAddress(
|
||||
address(_token0),
|
||||
address(_token1)
|
||||
);
|
||||
|
||||
if (token0 != address(_token0)) {
|
||||
(_token0, _token1) = (_token1, _token0);
|
||||
(_amount0, _amount1) = (_amount1, _amount0);
|
||||
}
|
||||
}
|
||||
uint256 _minAmt0 = getMinAmount(_token0, _amount0, params.slippage);
|
||||
uint256 _minAmt1 = getMinAmount(_token1, _amount1, params.slippage);
|
||||
|
||||
INonfungiblePositionManager.MintParams
|
||||
memory params = INonfungiblePositionManager.MintParams(
|
||||
address(_token0),
|
||||
address(_token1),
|
||||
params.fee,
|
||||
params.tickLower,
|
||||
params.tickUpper,
|
||||
_amount0,
|
||||
_amount1,
|
||||
_minAmt0,
|
||||
_minAmt1,
|
||||
address(this),
|
||||
block.timestamp
|
||||
);
|
||||
|
||||
(tokenId, liquidity, amountA, amountB) = nftManager.mint(params);
|
||||
}
|
||||
|
||||
function getNftTokenPairAddresses(uint256 _tokenId)
|
||||
internal
|
||||
view
|
||||
returns (address token0, address token1)
|
||||
{
|
||||
(bool success, bytes memory data) = address(nftManager).staticcall(
|
||||
abi.encodeWithSelector(nftManager.positions.selector, _tokenId)
|
||||
);
|
||||
require(success, "fetching positions failed");
|
||||
{
|
||||
(, , token0, token1, , , , ) = abi.decode(
|
||||
data,
|
||||
(
|
||||
uint96,
|
||||
address,
|
||||
address,
|
||||
address,
|
||||
uint24,
|
||||
int24,
|
||||
int24,
|
||||
uint128
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Check if token address is maticAddr and convert it to wmatic
|
||||
*/
|
||||
function _checkMATIC(
|
||||
address _token0,
|
||||
address _token1,
|
||||
uint256 _amount0,
|
||||
uint256 _amount1
|
||||
) internal {
|
||||
bool isMatic0 = _token0 == wmaticAddr;
|
||||
bool isMatic1 = _token1 == wmaticAddr;
|
||||
convertMaticToWmatic(isMatic0, TokenInterface(_token0), _amount0);
|
||||
convertMaticToWmatic(isMatic1, TokenInterface(_token1), _amount1);
|
||||
approve(TokenInterface(_token0), address(nftManager), _amount0);
|
||||
approve(TokenInterface(_token1), address(nftManager), _amount1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev addLiquidityWrapper function wrapper of _addLiquidity
|
||||
*/
|
||||
function _addLiquidityWrapper(
|
||||
uint256 tokenId,
|
||||
uint256 amountA,
|
||||
uint256 amountB,
|
||||
uint256 slippage
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint256 liquidity,
|
||||
uint256 amtA,
|
||||
uint256 amtB
|
||||
)
|
||||
{
|
||||
(address token0, address token1) = getNftTokenPairAddresses(tokenId);
|
||||
|
||||
(liquidity, amtA, amtB) = _addLiquidity(
|
||||
tokenId,
|
||||
token0,
|
||||
token1,
|
||||
amountA,
|
||||
amountB,
|
||||
slippage
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev addLiquidity function which interact with Uniswap v3
|
||||
*/
|
||||
function _addLiquidity(
|
||||
uint256 _tokenId,
|
||||
address _token0,
|
||||
address _token1,
|
||||
uint256 _amount0,
|
||||
uint256 _amount1,
|
||||
uint256 _slippage
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
)
|
||||
{
|
||||
_checkMATIC(_token0, _token1, _amount0, _amount1);
|
||||
uint256 _amount0Min = getMinAmount(
|
||||
TokenInterface(_token0),
|
||||
_amount0,
|
||||
_slippage
|
||||
);
|
||||
uint256 _amount1Min = getMinAmount(
|
||||
TokenInterface(_token1),
|
||||
_amount1,
|
||||
_slippage
|
||||
);
|
||||
INonfungiblePositionManager.IncreaseLiquidityParams
|
||||
memory params = INonfungiblePositionManager.IncreaseLiquidityParams(
|
||||
_tokenId,
|
||||
_amount0,
|
||||
_amount1,
|
||||
_amount0Min,
|
||||
_amount1Min,
|
||||
block.timestamp
|
||||
);
|
||||
|
||||
(liquidity, amount0, amount1) = nftManager.increaseLiquidity(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev decreaseLiquidity function which interact with Uniswap v3
|
||||
*/
|
||||
function _decreaseLiquidity(
|
||||
uint256 _tokenId,
|
||||
uint128 _liquidity,
|
||||
uint256 _amount0Min,
|
||||
uint256 _amount1Min
|
||||
) internal returns (uint256 amount0, uint256 amount1) {
|
||||
INonfungiblePositionManager.DecreaseLiquidityParams
|
||||
memory params = INonfungiblePositionManager.DecreaseLiquidityParams(
|
||||
_tokenId,
|
||||
_liquidity,
|
||||
_amount0Min,
|
||||
_amount1Min,
|
||||
block.timestamp
|
||||
);
|
||||
(amount0, amount1) = nftManager.decreaseLiquidity(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev collect function which interact with Uniswap v3
|
||||
*/
|
||||
function _collect(
|
||||
uint256 _tokenId,
|
||||
uint128 _amount0Max,
|
||||
uint128 _amount1Max
|
||||
) internal returns (uint256 amount0, uint256 amount1) {
|
||||
INonfungiblePositionManager.CollectParams
|
||||
memory params = INonfungiblePositionManager.CollectParams(
|
||||
_tokenId,
|
||||
address(this),
|
||||
_amount0Max,
|
||||
_amount1Max
|
||||
);
|
||||
(amount0, amount1) = nftManager.collect(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Burn Function
|
||||
*/
|
||||
function _burn(uint256 _tokenId) internal {
|
||||
nftManager.burn(_tokenId);
|
||||
}
|
||||
}
|
368
contracts/polygon/connectors/uniswap/v3/interface.sol
Normal file
368
contracts/polygon/connectors/uniswap/v3/interface.sol
Normal file
|
@ -0,0 +1,368 @@
|
|||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol";
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol";
|
||||
|
||||
/// @title Callback for IUniswapV3PoolActions#swap
|
||||
/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface
|
||||
interface IUniswapV3SwapCallback {
|
||||
/// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.
|
||||
/// @dev In the implementation you must pay the pool tokens owed for the swap.
|
||||
/// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.
|
||||
/// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
|
||||
/// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by
|
||||
/// the end of the swap. If positive, the callback must send that amount of token0 to the pool.
|
||||
/// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by
|
||||
/// the end of the swap. If positive, the callback must send that amount of token1 to the pool.
|
||||
/// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
|
||||
function uniswapV3SwapCallback(
|
||||
int256 amount0Delta,
|
||||
int256 amount1Delta,
|
||||
bytes calldata data
|
||||
) external;
|
||||
}
|
||||
|
||||
interface ISwapRouter is IUniswapV3SwapCallback {
|
||||
struct ExactInputSingleParams {
|
||||
address tokenIn;
|
||||
address tokenOut;
|
||||
uint24 fee;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
uint256 amountIn;
|
||||
uint256 amountOutMinimum;
|
||||
uint160 sqrtPriceLimitX96;
|
||||
}
|
||||
|
||||
/// @notice Swaps `amountIn` of one token for as much as possible of another token
|
||||
/// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
|
||||
/// @return amountOut The amount of the received token
|
||||
function exactInputSingle(ExactInputSingleParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amountOut);
|
||||
|
||||
struct ExactInputParams {
|
||||
bytes path;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
uint256 amountIn;
|
||||
uint256 amountOutMinimum;
|
||||
}
|
||||
|
||||
/// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
|
||||
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
|
||||
/// @return amountOut The amount of the received token
|
||||
function exactInput(ExactInputParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amountOut);
|
||||
|
||||
struct ExactOutputSingleParams {
|
||||
address tokenIn;
|
||||
address tokenOut;
|
||||
uint24 fee;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
uint256 amountOut;
|
||||
uint256 amountInMaximum;
|
||||
uint160 sqrtPriceLimitX96;
|
||||
}
|
||||
|
||||
/// @notice Swaps as little as possible of one token for `amountOut` of another token
|
||||
/// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
|
||||
/// @return amountIn The amount of the input token
|
||||
function exactOutputSingle(ExactOutputSingleParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amountIn);
|
||||
|
||||
struct ExactOutputParams {
|
||||
bytes path;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
uint256 amountOut;
|
||||
uint256 amountInMaximum;
|
||||
}
|
||||
|
||||
/// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
|
||||
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
|
||||
/// @return amountIn The amount of the input token
|
||||
function exactOutput(ExactOutputParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amountIn);
|
||||
}
|
||||
|
||||
/// @title Creates and initializes V3 Pools
|
||||
/// @notice Provides a method for creating and initializing a pool, if necessary, for bundling with other methods that
|
||||
/// require the pool to exist.
|
||||
interface IPoolInitializer {
|
||||
/// @notice Creates a new pool if it does not exist, then initializes if not initialized
|
||||
/// @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool
|
||||
/// @param token0 The contract address of token0 of the pool
|
||||
/// @param token1 The contract address of token1 of the pool
|
||||
/// @param fee The fee amount of the v3 pool for the specified token pair
|
||||
/// @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value
|
||||
/// @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary
|
||||
function createAndInitializePoolIfNecessary(
|
||||
address token0,
|
||||
address token1,
|
||||
uint24 fee,
|
||||
uint160 sqrtPriceX96
|
||||
) external payable returns (address pool);
|
||||
}
|
||||
|
||||
/// @title Immutable state
|
||||
/// @notice Functions that return immutable state of the router
|
||||
interface IPeripheryImmutableState {
|
||||
/// @return Returns the address of the Uniswap V3 factory
|
||||
function factory() external view returns (address);
|
||||
|
||||
/// @return Returns the address of WETH9
|
||||
function WETH9() external view returns (address);
|
||||
}
|
||||
|
||||
/// @title Periphery Payments
|
||||
/// @notice Functions to ease deposits and withdrawals of ETH
|
||||
interface IPeripheryPayments {
|
||||
/// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH.
|
||||
/// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users.
|
||||
/// @param amountMinimum The minimum amount of WETH9 to unwrap
|
||||
/// @param recipient The address receiving ETH
|
||||
function unwrapWETH9(uint256 amountMinimum, address recipient)
|
||||
external
|
||||
payable;
|
||||
|
||||
/// @notice Refunds any ETH balance held by this contract to the `msg.sender`
|
||||
/// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps
|
||||
/// that use ether for the input amount
|
||||
function refundETH() external payable;
|
||||
|
||||
/// @notice Transfers the full amount of a token held by this contract to recipient
|
||||
/// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users
|
||||
/// @param token The contract address of the token which will be transferred to `recipient`
|
||||
/// @param amountMinimum The minimum amount of token required for a transfer
|
||||
/// @param recipient The destination address of the token
|
||||
function sweepToken(
|
||||
address token,
|
||||
uint256 amountMinimum,
|
||||
address recipient
|
||||
) external payable;
|
||||
}
|
||||
|
||||
/// @title ERC721 with permit
|
||||
/// @notice Extension to ERC721 that includes a permit function for signature based approvals
|
||||
interface IERC721Permit is IERC721 {
|
||||
/// @notice The permit typehash used in the permit signature
|
||||
/// @return The typehash for the permit
|
||||
function PERMIT_TYPEHASH() external pure returns (bytes32);
|
||||
|
||||
/// @notice The domain separator used in the permit signature
|
||||
/// @return The domain seperator used in encoding of permit signature
|
||||
function DOMAIN_SEPARATOR() external view returns (bytes32);
|
||||
|
||||
/// @notice Approve of a specific token ID for spending by spender via signature
|
||||
/// @param spender The account that is being approved
|
||||
/// @param tokenId The ID of the token that is being approved for spending
|
||||
/// @param deadline The deadline timestamp by which the call must be mined for the approve to work
|
||||
/// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`
|
||||
/// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`
|
||||
/// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`
|
||||
function permit(
|
||||
address spender,
|
||||
uint256 tokenId,
|
||||
uint256 deadline,
|
||||
uint8 v,
|
||||
bytes32 r,
|
||||
bytes32 s
|
||||
) external payable;
|
||||
}
|
||||
|
||||
/// @title Non-fungible token for positions
|
||||
/// @notice Wraps Uniswap V3 positions in a non-fungible token interface which allows for them to be transferred
|
||||
/// and authorized.
|
||||
interface INonfungiblePositionManager is
|
||||
IPoolInitializer,
|
||||
IPeripheryPayments,
|
||||
IPeripheryImmutableState,
|
||||
IERC721Metadata,
|
||||
IERC721Enumerable,
|
||||
IERC721Permit
|
||||
{
|
||||
/// @notice Emitted when liquidity is increased for a position NFT
|
||||
/// @dev Also emitted when a token is minted
|
||||
/// @param tokenId The ID of the token for which liquidity was increased
|
||||
/// @param liquidity The amount by which liquidity for the NFT position was increased
|
||||
/// @param amount0 The amount of token0 that was paid for the increase in liquidity
|
||||
/// @param amount1 The amount of token1 that was paid for the increase in liquidity
|
||||
event IncreaseLiquidity(
|
||||
uint256 indexed tokenId,
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
/// @notice Emitted when liquidity is decreased for a position NFT
|
||||
/// @param tokenId The ID of the token for which liquidity was decreased
|
||||
/// @param liquidity The amount by which liquidity for the NFT position was decreased
|
||||
/// @param amount0 The amount of token0 that was accounted for the decrease in liquidity
|
||||
/// @param amount1 The amount of token1 that was accounted for the decrease in liquidity
|
||||
event DecreaseLiquidity(
|
||||
uint256 indexed tokenId,
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
/// @notice Emitted when tokens are collected for a position NFT
|
||||
/// @dev The amounts reported may not be exactly equivalent to the amounts transferred, due to rounding behavior
|
||||
/// @param tokenId The ID of the token for which underlying tokens were collected
|
||||
/// @param recipient The address of the account that received the collected tokens
|
||||
/// @param amount0 The amount of token0 owed to the position that was collected
|
||||
/// @param amount1 The amount of token1 owed to the position that was collected
|
||||
event Collect(
|
||||
uint256 indexed tokenId,
|
||||
address recipient,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
|
||||
/// @notice Returns the position information associated with a given token ID.
|
||||
/// @dev Throws if the token ID is not valid.
|
||||
/// @param tokenId The ID of the token that represents the position
|
||||
/// @return nonce The nonce for permits
|
||||
/// @return operator The address that is approved for spending
|
||||
/// @return token0 The address of the token0 for a specific pool
|
||||
/// @return token1 The address of the token1 for a specific pool
|
||||
/// @return fee The fee associated with the pool
|
||||
/// @return tickLower The lower end of the tick range for the position
|
||||
/// @return tickUpper The higher end of the tick range for the position
|
||||
/// @return liquidity The liquidity of the position
|
||||
/// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position
|
||||
/// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position
|
||||
/// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation
|
||||
/// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation
|
||||
function positions(uint256 tokenId)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint96 nonce,
|
||||
address operator,
|
||||
address token0,
|
||||
address token1,
|
||||
uint24 fee,
|
||||
int24 tickLower,
|
||||
int24 tickUpper,
|
||||
uint128 liquidity,
|
||||
uint256 feeGrowthInside0LastX128,
|
||||
uint256 feeGrowthInside1LastX128,
|
||||
uint128 tokensOwed0,
|
||||
uint128 tokensOwed1
|
||||
);
|
||||
|
||||
struct MintParams {
|
||||
address token0;
|
||||
address token1;
|
||||
uint24 fee;
|
||||
int24 tickLower;
|
||||
int24 tickUpper;
|
||||
uint256 amount0Desired;
|
||||
uint256 amount1Desired;
|
||||
uint256 amount0Min;
|
||||
uint256 amount1Min;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
}
|
||||
|
||||
/// @notice Creates a new position wrapped in a NFT
|
||||
/// @dev Call this when the pool does exist and is initialized. Note that if the pool is created but not initialized
|
||||
/// a method does not exist, i.e. the pool is assumed to be initialized.
|
||||
/// @param params The params necessary to mint a position, encoded as `MintParams` in calldata
|
||||
/// @return tokenId The ID of the token that represents the minted position
|
||||
/// @return liquidity The amount of liquidity for this position
|
||||
/// @return amount0 The amount of token0
|
||||
/// @return amount1 The amount of token1
|
||||
function mint(MintParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (
|
||||
uint256 tokenId,
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
|
||||
struct IncreaseLiquidityParams {
|
||||
uint256 tokenId;
|
||||
uint256 amount0Desired;
|
||||
uint256 amount1Desired;
|
||||
uint256 amount0Min;
|
||||
uint256 amount1Min;
|
||||
uint256 deadline;
|
||||
}
|
||||
|
||||
/// @notice Increases the amount of liquidity in a position, with tokens paid by the `msg.sender`
|
||||
/// @param params tokenId The ID of the token for which liquidity is being increased,
|
||||
/// amount0Desired The desired amount of token0 to be spent,
|
||||
/// amount1Desired The desired amount of token1 to be spent,
|
||||
/// amount0Min The minimum amount of token0 to spend, which serves as a slippage check,
|
||||
/// amount1Min The minimum amount of token1 to spend, which serves as a slippage check,
|
||||
/// deadline The time by which the transaction must be included to effect the change
|
||||
/// @return liquidity The new liquidity amount as a result of the increase
|
||||
/// @return amount0 The amount of token0 to acheive resulting liquidity
|
||||
/// @return amount1 The amount of token1 to acheive resulting liquidity
|
||||
function increaseLiquidity(IncreaseLiquidityParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
|
||||
struct DecreaseLiquidityParams {
|
||||
uint256 tokenId;
|
||||
uint128 liquidity;
|
||||
uint256 amount0Min;
|
||||
uint256 amount1Min;
|
||||
uint256 deadline;
|
||||
}
|
||||
|
||||
/// @notice Decreases the amount of liquidity in a position and accounts it to the position
|
||||
/// @param params tokenId The ID of the token for which liquidity is being decreased,
|
||||
/// amount The amount by which liquidity will be decreased,
|
||||
/// amount0Min The minimum amount of token0 that should be accounted for the burned liquidity,
|
||||
/// amount1Min The minimum amount of token1 that should be accounted for the burned liquidity,
|
||||
/// deadline The time by which the transaction must be included to effect the change
|
||||
/// @return amount0 The amount of token0 accounted to the position's tokens owed
|
||||
/// @return amount1 The amount of token1 accounted to the position's tokens owed
|
||||
function decreaseLiquidity(DecreaseLiquidityParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amount0, uint256 amount1);
|
||||
|
||||
struct CollectParams {
|
||||
uint256 tokenId;
|
||||
address recipient;
|
||||
uint128 amount0Max;
|
||||
uint128 amount1Max;
|
||||
}
|
||||
|
||||
/// @notice Collects up to a maximum amount of fees owed to a specific position to the recipient
|
||||
/// @param params tokenId The ID of the NFT for which tokens are being collected,
|
||||
/// recipient The account that should receive the tokens,
|
||||
/// amount0Max The maximum amount of token0 to collect,
|
||||
/// amount1Max The maximum amount of token1 to collect
|
||||
/// @return amount0 The amount of fees collected in token0
|
||||
/// @return amount1 The amount of fees collected in token1
|
||||
function collect(CollectParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amount0, uint256 amount1);
|
||||
|
||||
/// @notice Burns a token ID, which deletes it from the NFT contract. The token must have 0 liquidity and all tokens
|
||||
/// must be collected first.
|
||||
/// @param tokenId The ID of the token that is being burned
|
||||
function burn(uint256 tokenId) external payable;
|
||||
}
|
247
contracts/polygon/connectors/uniswap/v3/main.sol
Normal file
247
contracts/polygon/connectors/uniswap/v3/main.sol
Normal file
|
@ -0,0 +1,247 @@
|
|||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
/**
|
||||
* @title Uniswap v3.
|
||||
* @dev Decentralized Exchange.
|
||||
*/
|
||||
|
||||
import {TokenInterface} from "../../../common/interfaces.sol";
|
||||
import {Helpers} from "./helpers.sol";
|
||||
import {Events} from "./events.sol";
|
||||
|
||||
abstract contract UniswapResolver is Helpers, Events {
|
||||
|
||||
/**
|
||||
* @dev Create and Initialize pool
|
||||
* @notice Create and Initialize new pool if required
|
||||
* @param tokenA tokenA addreess
|
||||
* @param tokenB tokenB addreess
|
||||
* @param fee fee percentage
|
||||
* @param initialTick Initial tick for the pool
|
||||
*/
|
||||
function createAndInitializePool (
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint24 fee,
|
||||
int24 initialTick
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
|
||||
address pool = _createAndInitializePoolIfNecessary(
|
||||
tokenA,
|
||||
tokenB,
|
||||
fee,
|
||||
initialTick
|
||||
);
|
||||
|
||||
_eventName = "LogcreateAndInitializePool(address,address,address,uint24,int24)";
|
||||
_eventParam = abi.encode(
|
||||
tokenA,
|
||||
tokenB,
|
||||
pool,
|
||||
fee,
|
||||
initialTick
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Mint New Position
|
||||
* @notice Mint New NFT LP Position
|
||||
* @param tokenA tokenA addreess
|
||||
* @param tokenB tokenB addreess
|
||||
* @param fee fee percentage
|
||||
* @param tickLower Lower tick
|
||||
* @param tickUpper Upper tick
|
||||
* @param amtA amount of tokenA
|
||||
* @param amtB amount of tokenB
|
||||
* @param slippage slippage percentage
|
||||
* @param getIds ID to retrieve amtA
|
||||
* @param setId ID stores the amount of LP token
|
||||
*/
|
||||
function mint(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint24 fee,
|
||||
int24 tickLower,
|
||||
int24 tickUpper,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
uint256 slippage,
|
||||
uint256[] calldata getIds,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
|
||||
MintParams memory params;
|
||||
{
|
||||
params = MintParams(
|
||||
tokenA,
|
||||
tokenB,
|
||||
fee,
|
||||
tickLower,
|
||||
tickUpper,
|
||||
amtA,
|
||||
amtB,
|
||||
slippage
|
||||
);
|
||||
}
|
||||
params.amtA = getUint(getIds[0], params.amtA);
|
||||
params.amtB = getUint(getIds[1], params.amtB);
|
||||
|
||||
(
|
||||
uint256 _tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
) = _mint(params);
|
||||
|
||||
setUint(setId, liquidity);
|
||||
|
||||
_eventName = "LogMint(uint256,uint256,uint256,uint256,int24,int24)";
|
||||
_eventParam = abi.encode(
|
||||
_tokenId,
|
||||
liquidity,
|
||||
amountA,
|
||||
amountB,
|
||||
params.tickLower,
|
||||
params.tickUpper
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Increase Liquidity
|
||||
* @notice Increase Liquidity of NFT Position
|
||||
* @param tokenId NFT LP Token ID.
|
||||
* @param amountA tokenA amounts.
|
||||
* @param amountB tokenB amounts.
|
||||
* @param slippage slippage.
|
||||
* @param getIds IDs to retrieve token amounts
|
||||
* @param setId stores the liquidity amount
|
||||
*/
|
||||
function deposit(
|
||||
uint256 tokenId,
|
||||
uint256 amountA,
|
||||
uint256 amountB,
|
||||
uint256 slippage,
|
||||
uint256[] calldata getIds,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (tokenId == 0) tokenId = _getLastNftId(address(this));
|
||||
amountA = getUint(getIds[0], amountA);
|
||||
amountB = getUint(getIds[1], amountB);
|
||||
(
|
||||
uint256 _liquidity,
|
||||
uint256 _amtA,
|
||||
uint256 _amtB
|
||||
) = _addLiquidityWrapper(tokenId, amountA, amountB, slippage);
|
||||
setUint(setId, _liquidity);
|
||||
|
||||
_eventName = "LogDeposit(uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(tokenId, _liquidity, _amtA, _amtB);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Decrease Liquidity
|
||||
* @notice Decrease Liquidity of NFT Position
|
||||
* @param tokenId NFT LP Token ID.
|
||||
* @param liquidity LP Token amount.
|
||||
* @param amountAMin Min amount of tokenA.
|
||||
* @param amountBMin Min amount of tokenB.
|
||||
* @param getId ID to retrieve LP token amounts
|
||||
* @param setIds stores the amount of output tokens
|
||||
*/
|
||||
function withdraw(
|
||||
uint256 tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amountAMin,
|
||||
uint256 amountBMin,
|
||||
uint256 getId,
|
||||
uint256[] calldata setIds
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (tokenId == 0) tokenId = _getLastNftId(address(this));
|
||||
uint128 _liquidity = uint128(getUint(getId, liquidity));
|
||||
|
||||
(uint256 _amtA, uint256 _amtB) = _decreaseLiquidity(
|
||||
tokenId,
|
||||
_liquidity,
|
||||
amountAMin,
|
||||
amountBMin
|
||||
);
|
||||
|
||||
setUint(setIds[0], _amtA);
|
||||
setUint(setIds[1], _amtB);
|
||||
|
||||
_eventName = "LogWithdraw(uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(tokenId, _liquidity, _amtA, _amtB);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Collect function
|
||||
* @notice Collect from NFT Position
|
||||
* @param tokenId NFT LP Token ID.
|
||||
* @param amount0Max Max amount of token0.
|
||||
* @param amount1Max Max amount of token1.
|
||||
* @param getIds IDs to retrieve amounts
|
||||
* @param setIds stores the amount of output tokens
|
||||
*/
|
||||
function collect(
|
||||
uint256 tokenId,
|
||||
uint256 amount0Max,
|
||||
uint256 amount1Max,
|
||||
uint256[] calldata getIds,
|
||||
uint256[] calldata setIds
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (tokenId == 0) tokenId = _getLastNftId(address(this));
|
||||
uint128 _amount0Max = uint128(getUint(getIds[0], amount0Max));
|
||||
uint128 _amount1Max = uint128(getUint(getIds[1], amount1Max));
|
||||
(uint256 amount0, uint256 amount1) = _collect(
|
||||
tokenId,
|
||||
_amount0Max,
|
||||
_amount1Max
|
||||
);
|
||||
|
||||
setUint(setIds[0], amount0);
|
||||
setUint(setIds[1], amount1);
|
||||
_eventName = "LogCollect(uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(tokenId, amount0, amount1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Burn Function
|
||||
* @notice Burn NFT LP Position
|
||||
* @param tokenId NFT LP Token ID
|
||||
*/
|
||||
function burn(uint256 tokenId)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (tokenId == 0) tokenId = _getLastNftId(address(this));
|
||||
_burn(tokenId);
|
||||
_eventName = "LogBurnPosition(uint256)";
|
||||
_eventParam = abi.encode(tokenId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2UniswapV3Polygon is UniswapResolver {
|
||||
string public constant name = "UniswapV3-v1";
|
||||
}
|
29
contracts/polygon/connectors/uniswap/v3_staker/events.sol
Normal file
29
contracts/polygon/connectors/uniswap/v3_staker/events.sol
Normal file
|
@ -0,0 +1,29 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogDeposit(uint256 tokenId);
|
||||
|
||||
event LogDepositAndStake(uint256 tokenId, bytes32 incentiveId);
|
||||
|
||||
event LogWithdraw(uint256 indexed tokenId);
|
||||
|
||||
event LogDepositTransfer(uint256 indexed tokenId, address to);
|
||||
|
||||
event LogStake(uint256 indexed tokenId, bytes32 incentiveId);
|
||||
|
||||
event LogUnstake(uint256 indexed tokenId, bytes32 incentiveId);
|
||||
|
||||
event LogRewardClaimed(
|
||||
address indexed rewardToken,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
event LogIncentiveCreated(
|
||||
bytes32 incentiveId,
|
||||
address poolAddr,
|
||||
address refundee,
|
||||
uint256 startTime,
|
||||
uint256 endTime,
|
||||
uint256 reward
|
||||
);
|
||||
}
|
87
contracts/polygon/connectors/uniswap/v3_staker/helpers.sol
Normal file
87
contracts/polygon/connectors/uniswap/v3_staker/helpers.sol
Normal file
|
@ -0,0 +1,87 @@
|
|||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
import {TokenInterface} from "../../../common/interfaces.sol";
|
||||
import {DSMath} from "../../../common/math.sol";
|
||||
import {Basic} from "../../../common/basic.sol";
|
||||
import "./interface.sol";
|
||||
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
|
||||
import "@uniswap/v3-core/contracts/libraries/TickMath.sol";
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
|
||||
import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev uniswap v3 NFT Position Manager & Swap Router
|
||||
*/
|
||||
INonfungiblePositionManager constant nftManager =
|
||||
INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);
|
||||
IUniswapV3Staker constant staker =
|
||||
IUniswapV3Staker(0x1f98407aaB862CdDeF78Ed252D6f557aA5b0f00d);
|
||||
|
||||
/**
|
||||
* @dev Get Last NFT Index
|
||||
* @param user: User address
|
||||
*/
|
||||
function _getLastNftId(address user)
|
||||
internal
|
||||
view
|
||||
returns (uint256 tokenId)
|
||||
{
|
||||
uint256 len = nftManager.balanceOf(user);
|
||||
tokenId = nftManager.tokenOfOwnerByIndex(user, len - 1);
|
||||
}
|
||||
|
||||
function getPoolAddress(uint256 _tokenId)
|
||||
internal
|
||||
view
|
||||
returns (address pool)
|
||||
{
|
||||
(bool success, bytes memory data) = address(nftManager).staticcall(
|
||||
abi.encodeWithSelector(nftManager.positions.selector, _tokenId)
|
||||
);
|
||||
require(success, "fetching positions failed");
|
||||
{
|
||||
(, , address token0, address token1, uint24 fee, , , ) = abi.decode(
|
||||
data,
|
||||
(
|
||||
uint96,
|
||||
address,
|
||||
address,
|
||||
address,
|
||||
uint24,
|
||||
int24,
|
||||
int24,
|
||||
uint128
|
||||
)
|
||||
);
|
||||
|
||||
pool = PoolAddress.computeAddress(
|
||||
nftManager.factory(),
|
||||
PoolAddress.PoolKey({token0: token0, token1: token1, fee: fee})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function _stake(
|
||||
uint256 _tokenId,
|
||||
IUniswapV3Staker.IncentiveKey memory _incentiveId
|
||||
) internal {
|
||||
staker.stakeToken(_incentiveId, _tokenId);
|
||||
}
|
||||
|
||||
function _unstake(
|
||||
IUniswapV3Staker.IncentiveKey memory _key,
|
||||
uint256 _tokenId
|
||||
) internal {
|
||||
staker.unstakeToken(_key, _tokenId);
|
||||
}
|
||||
|
||||
function _claimRewards(
|
||||
IERC20Minimal _rewardToken,
|
||||
address _to,
|
||||
uint256 _amountRequested
|
||||
) internal returns (uint256 rewards) {
|
||||
rewards = staker.claimReward(_rewardToken, _to, _amountRequested);
|
||||
}
|
||||
}
|
183
contracts/polygon/connectors/uniswap/v3_staker/interface.sol
Normal file
183
contracts/polygon/connectors/uniswap/v3_staker/interface.sol
Normal file
|
@ -0,0 +1,183 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity =0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
import '@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol';
|
||||
|
||||
import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';
|
||||
import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';
|
||||
import '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';
|
||||
|
||||
import '@uniswap/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol';
|
||||
import '@uniswap/v3-periphery/contracts/interfaces/IMulticall.sol';
|
||||
|
||||
/// @title Uniswap V3 Staker Interface
|
||||
/// @notice Allows staking nonfungible liquidity tokens in exchange for reward tokens
|
||||
interface IUniswapV3Staker is IERC721Receiver, IMulticall {
|
||||
/// @param rewardToken The token being distributed as a reward
|
||||
/// @param pool The Uniswap V3 pool
|
||||
/// @param startTime The time when the incentive program begins
|
||||
/// @param endTime The time when rewards stop accruing
|
||||
/// @param refundee The address which receives any remaining reward tokens when the incentive is ended
|
||||
struct IncentiveKey {
|
||||
IERC20Minimal rewardToken;
|
||||
IUniswapV3Pool pool;
|
||||
uint256 startTime;
|
||||
uint256 endTime;
|
||||
address refundee;
|
||||
}
|
||||
|
||||
/// @notice The Uniswap V3 Factory
|
||||
function factory() external view returns (IUniswapV3Factory);
|
||||
|
||||
/// @notice The nonfungible position manager with which this staking contract is compatible
|
||||
function nonfungiblePositionManager() external view returns (INonfungiblePositionManager);
|
||||
|
||||
/// @notice The max duration of an incentive in seconds
|
||||
function maxIncentiveDuration() external view returns (uint256);
|
||||
|
||||
/// @notice The max amount of seconds into the future the incentive startTime can be set
|
||||
function maxIncentiveStartLeadTime() external view returns (uint256);
|
||||
|
||||
/// @notice Represents a staking incentive
|
||||
/// @param incentiveId The ID of the incentive computed from its parameters
|
||||
/// @return totalRewardUnclaimed The amount of reward token not yet claimed by users
|
||||
/// @return totalSecondsClaimedX128 Total liquidity-seconds claimed, represented as a UQ32.128
|
||||
/// @return numberOfStakes The count of deposits that are currently staked for the incentive
|
||||
function incentives(bytes32 incentiveId)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint256 totalRewardUnclaimed,
|
||||
uint160 totalSecondsClaimedX128,
|
||||
uint96 numberOfStakes
|
||||
);
|
||||
|
||||
/// @notice Returns information about a deposited NFT
|
||||
/// @return owner The owner of the deposited NFT
|
||||
/// @return numberOfStakes Counter of how many incentives for which the liquidity is staked
|
||||
/// @return tickLower The lower tick of the range
|
||||
/// @return tickUpper The upper tick of the range
|
||||
function deposits(uint256 tokenId)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
address owner,
|
||||
uint48 numberOfStakes,
|
||||
int24 tickLower,
|
||||
int24 tickUpper
|
||||
);
|
||||
|
||||
/// @notice Returns information about a staked liquidity NFT
|
||||
/// @param tokenId The ID of the staked token
|
||||
/// @param incentiveId The ID of the incentive for which the token is staked
|
||||
/// @return secondsPerLiquidityInsideInitialX128 secondsPerLiquidity represented as a UQ32.128
|
||||
/// @return liquidity The amount of liquidity in the NFT as of the last time the rewards were computed
|
||||
function stakes(uint256 tokenId, bytes32 incentiveId)
|
||||
external
|
||||
view
|
||||
returns (uint160 secondsPerLiquidityInsideInitialX128, uint128 liquidity);
|
||||
|
||||
/// @notice Returns amounts of reward tokens owed to a given address according to the last time all stakes were updated
|
||||
/// @param rewardToken The token for which to check rewards
|
||||
/// @param owner The owner for which the rewards owed are checked
|
||||
/// @return rewardsOwed The amount of the reward token claimable by the owner
|
||||
function rewards(IERC20Minimal rewardToken, address owner) external view returns (uint256 rewardsOwed);
|
||||
|
||||
/// @notice Creates a new liquidity mining incentive program
|
||||
/// @param key Details of the incentive to create
|
||||
/// @param reward The amount of reward tokens to be distributed
|
||||
function createIncentive(IncentiveKey memory key, uint256 reward) external;
|
||||
|
||||
/// @notice Ends an incentive after the incentive end time has passed and all stakes have been withdrawn
|
||||
/// @param key Details of the incentive to end
|
||||
/// @return refund The remaining reward tokens when the incentive is ended
|
||||
function endIncentive(IncentiveKey memory key) external returns (uint256 refund);
|
||||
|
||||
/// @notice Transfers ownership of a deposit from the sender to the given recipient
|
||||
/// @param tokenId The ID of the token (and the deposit) to transfer
|
||||
/// @param to The new owner of the deposit
|
||||
function transferDeposit(uint256 tokenId, address to) external;
|
||||
|
||||
/// @notice Withdraws a Uniswap V3 LP token `tokenId` from this contract to the recipient `to`
|
||||
/// @param tokenId The unique identifier of an Uniswap V3 LP token
|
||||
/// @param to The address where the LP token will be sent
|
||||
/// @param data An optional data array that will be passed along to the `to` address via the NFT safeTransferFrom
|
||||
function withdrawToken(
|
||||
uint256 tokenId,
|
||||
address to,
|
||||
bytes memory data
|
||||
) external;
|
||||
|
||||
/// @notice Stakes a Uniswap V3 LP token
|
||||
/// @param key The key of the incentive for which to stake the NFT
|
||||
/// @param tokenId The ID of the token to stake
|
||||
function stakeToken(IncentiveKey memory key, uint256 tokenId) external;
|
||||
|
||||
/// @notice Unstakes a Uniswap V3 LP token
|
||||
/// @param key The key of the incentive for which to unstake the NFT
|
||||
/// @param tokenId The ID of the token to unstake
|
||||
function unstakeToken(IncentiveKey memory key, uint256 tokenId) external;
|
||||
|
||||
/// @notice Transfers `amountRequested` of accrued `rewardToken` rewards from the contract to the recipient `to`
|
||||
/// @param rewardToken The token being distributed as a reward
|
||||
/// @param to The address where claimed rewards will be sent to
|
||||
/// @param amountRequested The amount of reward tokens to claim. Claims entire reward amount if set to 0.
|
||||
/// @return reward The amount of reward tokens claimed
|
||||
function claimReward(
|
||||
IERC20Minimal rewardToken,
|
||||
address to,
|
||||
uint256 amountRequested
|
||||
) external returns (uint256 reward);
|
||||
|
||||
/// @notice Calculates the reward amount that will be received for the given stake
|
||||
/// @param key The key of the incentive
|
||||
/// @param tokenId The ID of the token
|
||||
/// @return reward The reward accrued to the NFT for the given incentive thus far
|
||||
function getRewardInfo(IncentiveKey memory key, uint256 tokenId)
|
||||
external
|
||||
returns (uint256 reward, uint160 secondsInsideX128);
|
||||
|
||||
/// @notice Event emitted when a liquidity mining incentive has been created
|
||||
/// @param rewardToken The token being distributed as a reward
|
||||
/// @param pool The Uniswap V3 pool
|
||||
/// @param startTime The time when the incentive program begins
|
||||
/// @param endTime The time when rewards stop accruing
|
||||
/// @param refundee The address which receives any remaining reward tokens after the end time
|
||||
/// @param reward The amount of reward tokens to be distributed
|
||||
event IncentiveCreated(
|
||||
IERC20Minimal indexed rewardToken,
|
||||
IUniswapV3Pool indexed pool,
|
||||
uint256 startTime,
|
||||
uint256 endTime,
|
||||
address refundee,
|
||||
uint256 reward
|
||||
);
|
||||
|
||||
/// @notice Event that can be emitted when a liquidity mining incentive has ended
|
||||
/// @param incentiveId The incentive which is ending
|
||||
/// @param refund The amount of reward tokens refunded
|
||||
event IncentiveEnded(bytes32 indexed incentiveId, uint256 refund);
|
||||
|
||||
/// @notice Emitted when ownership of a deposit changes
|
||||
/// @param tokenId The ID of the deposit (and token) that is being transferred
|
||||
/// @param oldOwner The owner before the deposit was transferred
|
||||
/// @param newOwner The owner after the deposit was transferred
|
||||
event DepositTransferred(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner);
|
||||
|
||||
/// @notice Event emitted when a Uniswap V3 LP token has been staked
|
||||
/// @param tokenId The unique identifier of an Uniswap V3 LP token
|
||||
/// @param liquidity The amount of liquidity staked
|
||||
/// @param incentiveId The incentive in which the token is staking
|
||||
event TokenStaked(uint256 indexed tokenId, bytes32 indexed incentiveId, uint128 liquidity);
|
||||
|
||||
/// @notice Event emitted when a Uniswap V3 LP token has been unstaked
|
||||
/// @param tokenId The unique identifier of an Uniswap V3 LP token
|
||||
/// @param incentiveId The incentive in which the token is staking
|
||||
event TokenUnstaked(uint256 indexed tokenId, bytes32 indexed incentiveId);
|
||||
|
||||
/// @notice Event emitted when a reward token has been claimed
|
||||
/// @param to The address where claimed rewards were sent to
|
||||
/// @param reward The amount of reward tokens claimed
|
||||
event RewardClaimed(address indexed to, uint256 reward);
|
||||
}
|
255
contracts/polygon/connectors/uniswap/v3_staker/main.sol
Normal file
255
contracts/polygon/connectors/uniswap/v3_staker/main.sol
Normal file
|
@ -0,0 +1,255 @@
|
|||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
/**
|
||||
* @title Uniswap v3.
|
||||
* @dev Decentralized Exchange.
|
||||
*/
|
||||
|
||||
import {TokenInterface} from "../../../common/interfaces.sol";
|
||||
import "./interface.sol";
|
||||
import {Helpers} from "./helpers.sol";
|
||||
import {Events} from "./events.sol";
|
||||
|
||||
abstract contract UniswapResolver is Helpers, Events {
|
||||
/**
|
||||
* @dev Deposit NFT token
|
||||
* @notice Transfer deposited NFT token
|
||||
* @param _tokenId NFT LP Token ID
|
||||
*/
|
||||
function deposit(uint256 _tokenId)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (_tokenId == 0) _tokenId = _getLastNftId(address(this));
|
||||
nftManager.safeTransferFrom(
|
||||
address(this),
|
||||
address(staker),
|
||||
_tokenId,
|
||||
""
|
||||
);
|
||||
|
||||
_eventName = "LogDeposit(uint256)";
|
||||
_eventParam = abi.encode(_tokenId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deposit and Stake NFT token
|
||||
* @notice To Deposit and Stake NFT for Staking
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _startTime stake start time
|
||||
* @param _endTime stake end time
|
||||
* @param _refundee refundee address
|
||||
* @param _tokenId NFT LP token id
|
||||
*/
|
||||
function depositAndStake (
|
||||
address _rewardToken,
|
||||
uint256 _startTime,
|
||||
uint256 _endTime,
|
||||
address _refundee,
|
||||
uint256 _tokenId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (_tokenId == 0) _tokenId = _getLastNftId(address(this));
|
||||
nftManager.safeTransferFrom(
|
||||
address(this),
|
||||
address(staker),
|
||||
_tokenId,
|
||||
""
|
||||
);
|
||||
|
||||
address poolAddr = getPoolAddress(_tokenId);
|
||||
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(poolAddr);
|
||||
IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker
|
||||
.IncentiveKey(
|
||||
IERC20Minimal(_rewardToken),
|
||||
pool,
|
||||
_startTime,
|
||||
_endTime,
|
||||
_refundee
|
||||
);
|
||||
_stake(_tokenId, _key);
|
||||
|
||||
_eventName = "LogDepositAndStake(uint256,bytes32)";
|
||||
_eventParam = abi.encode(_tokenId, keccak256(abi.encode(_key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deposit Transfer
|
||||
* @notice Transfer deposited NFT token
|
||||
* @param _tokenId NFT LP Token ID
|
||||
* @param _to address to transfer
|
||||
*/
|
||||
function transferDeposit(uint256 _tokenId, address _to)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
staker.transferDeposit(_tokenId, _to);
|
||||
|
||||
_eventName = "LogDepositTransfer(uint256,address)";
|
||||
_eventParam = abi.encode(_tokenId, _to);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw NFT LP token
|
||||
* @notice Withdraw NFT LP token from staking pool
|
||||
* @param _tokenId NFT LP Token ID
|
||||
*/
|
||||
function withdraw(uint256 _tokenId)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
staker.withdrawToken(_tokenId, address(this), "");
|
||||
|
||||
_eventName = "LogWithdraw(uint256)";
|
||||
_eventParam = abi.encode(_tokenId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Stake NFT LP token
|
||||
* @notice Stake NFT LP Position
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _startTime stake start time
|
||||
* @param _endTime stake end time
|
||||
* @param _refundee refundee address
|
||||
* @param _tokenId NFT LP token id
|
||||
*/
|
||||
function stake (
|
||||
address _rewardToken,
|
||||
uint256 _startTime,
|
||||
uint256 _endTime,
|
||||
address _refundee,
|
||||
uint256 _tokenId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
address poolAddr = getPoolAddress(_tokenId);
|
||||
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(poolAddr);
|
||||
IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker
|
||||
.IncentiveKey(
|
||||
IERC20Minimal(_rewardToken),
|
||||
pool,
|
||||
_startTime,
|
||||
_endTime,
|
||||
_refundee
|
||||
);
|
||||
_stake(_tokenId, _key);
|
||||
|
||||
_eventName = "LogStake(uint256,bytes32)";
|
||||
_eventParam = abi.encode(_tokenId, keccak256(abi.encode(_key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Unstake NFT LP token
|
||||
* @notice Unstake NFT LP Position
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _startTime stake start time
|
||||
* @param _endTime stake end time
|
||||
* @param _refundee refundee address
|
||||
* @param _tokenId NFT LP token id
|
||||
*/
|
||||
function unstake(
|
||||
address _rewardToken,
|
||||
uint256 _startTime,
|
||||
uint256 _endTime,
|
||||
address _refundee,
|
||||
uint256 _tokenId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
address poolAddr = getPoolAddress(_tokenId);
|
||||
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(poolAddr);
|
||||
IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker
|
||||
.IncentiveKey(
|
||||
IERC20Minimal(_rewardToken),
|
||||
pool,
|
||||
_startTime,
|
||||
_endTime,
|
||||
_refundee
|
||||
);
|
||||
_unstake(_key, _tokenId);
|
||||
_eventName = "LogUnstake(uint256,bytes32)";
|
||||
_eventParam = abi.encode(_tokenId, keccak256(abi.encode(_key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Claim rewards
|
||||
* @notice Claim rewards
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _amount requested amount
|
||||
*/
|
||||
function claimRewards(
|
||||
address _rewardToken,
|
||||
uint256 _amount
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 rewards = _claimRewards(
|
||||
IERC20Minimal(_rewardToken),
|
||||
address(this),
|
||||
_amount
|
||||
);
|
||||
|
||||
_eventName = "LogRewardClaimed(address,uint256)";
|
||||
_eventParam = abi.encode(_rewardToken, rewards);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Create incentive
|
||||
* @notice Create incentive
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _length incentive length
|
||||
* @param _refundee refundee address
|
||||
* @param _poolAddr Uniswap V3 Pool address
|
||||
* @param _reward reward amount
|
||||
*/
|
||||
function createIncentive(
|
||||
address _rewardToken,
|
||||
uint256 _length,
|
||||
address _refundee,
|
||||
address _poolAddr,
|
||||
uint256 _reward
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(_poolAddr);
|
||||
uint256 _startTime = block.timestamp;
|
||||
uint256 _endTime = _startTime + _length;
|
||||
IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker
|
||||
.IncentiveKey(
|
||||
IERC20Minimal(_rewardToken),
|
||||
pool,
|
||||
_startTime,
|
||||
_endTime,
|
||||
_refundee
|
||||
);
|
||||
if (_rewardToken != maticAddr) {
|
||||
IERC20Minimal(_rewardToken).approve(address(staker), _reward);
|
||||
}
|
||||
staker.createIncentive(_key, _reward);
|
||||
|
||||
_eventName = "LogIncentiveCreated(bytes32,address,address,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(keccak256(abi.encode(_key)), _poolAddr, _refundee, _startTime, _endTime, _reward);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2UniswapV3StakerPolygon is UniswapResolver {
|
||||
string public constant name = "Uniswap-V3-Staker-v1.1";
|
||||
}
|
|
@ -39,6 +39,13 @@ const mnemonic =
|
|||
process.env.MNEMONIC ??
|
||||
"test test test test test test test test test test test junk";
|
||||
|
||||
const networkGasPriceConfig: Record<string, string> = {
|
||||
"mainnet": "160",
|
||||
"polygon": "50",
|
||||
"avalanche": "50",
|
||||
"arbitrum": "2"
|
||||
}
|
||||
|
||||
function createConfig(network: string) {
|
||||
return {
|
||||
url: getNetworkUrl(network),
|
||||
|
@ -47,7 +54,6 @@ function createConfig(network: string) {
|
|||
}
|
||||
|
||||
function getNetworkUrl(networkType: string) {
|
||||
//console.log(process.env);
|
||||
if (networkType === "avalanche")
|
||||
return "https://api.avax.network/ext/bc/C/rpc";
|
||||
else if (networkType === "polygon")
|
||||
|
|
|
@ -57,6 +57,9 @@
|
|||
"hardhat": "^2.7.0",
|
||||
"hardhat-deploy": "^0.9.14",
|
||||
"hardhat-deploy-ethers": "^0.3.0-beta.11",
|
||||
"prettier": "^2.4.1",
|
||||
"prettier-plugin-solidity": "^1.0.0-beta.18",
|
||||
"solhint": "^3.3.6",
|
||||
"husky": "^7.0.4",
|
||||
"solidity-coverage": "0.7.17",
|
||||
"ts-node": "^10.4.0",
|
||||
|
|
|
@ -5,19 +5,24 @@ async function main() {
|
|||
const accounts = await ethers.getSigners();
|
||||
|
||||
const connectMapping: Record<string, string> = {
|
||||
// "1INCH-A": "ConnectV2OneInch",
|
||||
// "1INCH-B": "ConnectV2OneProto",
|
||||
// "AAVE-V1-A": "ConnectV2AaveV1",
|
||||
// "AAVE-V2-A": "ConnectV2AaveV2",
|
||||
// "AUTHORITY-A": "ConnectV2Auth",
|
||||
// "BASIC-A": "ConnectV2Basic",
|
||||
// "COMP-A": "ConnectV2COMP",
|
||||
// "COMPOUND-A": "ConnectV2Compound",
|
||||
// "DYDX-A": "ConnectV2Dydx",
|
||||
// "FEE-A": "ConnectV2Fee",
|
||||
// "GELATO-A": "ConnectV2Gelato",
|
||||
// "MAKERDAO-A": "ConnectV2Maker",
|
||||
// "UNISWAP-A": "ConnectV2UniswapV2",
|
||||
"1INCH-A": "ConnectV2OneInch",
|
||||
"1INCH-B": "ConnectV2OneProto",
|
||||
"AAVE-V1-A": "ConnectV2AaveV1",
|
||||
"AAVE-V2-A": "ConnectV2AaveV2",
|
||||
"AUTHORITY-A": "ConnectV2Auth",
|
||||
"BASIC-A": "ConnectV2Basic",
|
||||
"COMP-A": "ConnectV2COMP",
|
||||
"COMPOUND-A": "ConnectV2Compound",
|
||||
"DYDX-A": "ConnectV2Dydx",
|
||||
"FEE-A": "ConnectV2Fee",
|
||||
"GELATO-A": "ConnectV2Gelato",
|
||||
"MAKERDAO-A": "ConnectV2Maker",
|
||||
"UNISWAP-A": "ConnectV2UniswapV2",
|
||||
"QUICKSWAP-A": "ConnectV2QuickswapPolygon",
|
||||
"UniswapV3-v1" : "ConnectV2UniswapV3Polygon",
|
||||
"Uniswap-V3-Staker-v1.1" : "ConnectV2UniswapV3StakerPolygon",
|
||||
"Paraswap-v5" : "ConnectV2ParaswapV5Polygon"
|
||||
"1INCH-V4" : "ConnectV2OneInchV4Polygon",
|
||||
"ZEROEX-A": "ConnectV2ZeroExAvalanche",
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import { execScript } from "./command";
|
|||
let start: number, end: number;
|
||||
|
||||
async function testRunner() {
|
||||
const chain = ["avalanche", "mainnet", "polygon"];
|
||||
const chain = ["avalanche", "mainnet", "polygon", "arbitrum"];
|
||||
start = Date.now();
|
||||
|
||||
for (let ch of chain) {
|
||||
|
|
|
@ -25,7 +25,7 @@ async function testRunner() {
|
|||
const { testName } = await inquirer.prompt([
|
||||
{
|
||||
name: "testName",
|
||||
message: "For which resolver you want to run the tests?",
|
||||
message: "For which connector you want to run the tests?",
|
||||
type: "list",
|
||||
choices: ["all", ...availableTests],
|
||||
},
|
||||
|
|
147
test/mainnet/sushiswap/sushiswap.test.ts
Normal file
147
test/mainnet/sushiswap/sushiswap.test.ts
Normal file
|
@ -0,0 +1,147 @@
|
|||
import { expect } from "chai";
|
||||
import hre from "hardhat";
|
||||
const { waffle, ethers } = hre;
|
||||
const { provider } = waffle;
|
||||
|
||||
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
|
||||
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
|
||||
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
|
||||
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
|
||||
import { addLiquidity } from "../../../scripts/tests/addLiquidity";
|
||||
|
||||
import { addresses } from "../../../scripts/tests/mainnet/addresses";
|
||||
import { abis } from "../../../scripts/constant/abis";
|
||||
import { ConnectV2Sushiswap__factory, ConnectV2Sushiswap } from "../../../typechain";
|
||||
import type { Signer, Contract } from "ethers";
|
||||
|
||||
const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f";
|
||||
|
||||
describe("Sushiswap", function () {
|
||||
const connectorName = "Sushiswap-v1";
|
||||
|
||||
let dsaWallet0: Contract;
|
||||
let masterSigner: Signer;
|
||||
let instaConnectorsV2: Contract;
|
||||
let connector: Contract;
|
||||
|
||||
const wallets = provider.getWallets();
|
||||
const [wallet0, wallet1, wallet2, wallet3] = wallets;
|
||||
before(async () => {
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_reset",
|
||||
params: [
|
||||
{
|
||||
forking: {
|
||||
// @ts-ignore
|
||||
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
|
||||
blockNumber: 13005785
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
masterSigner = await getMasterSigner();
|
||||
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName,
|
||||
contractArtifact: ConnectV2Sushiswap__factory,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
});
|
||||
console.log("Connector address", connector.address);
|
||||
});
|
||||
|
||||
it("Should have contracts deployed.", async function () {
|
||||
expect(!!instaConnectorsV2.address).to.be.true;
|
||||
expect(!!connector.address).to.be.true;
|
||||
expect(!!(await masterSigner.getAddress())).to.be.true;
|
||||
});
|
||||
|
||||
describe("DSA wallet setup", function () {
|
||||
it("Should build DSA v2", async function () {
|
||||
dsaWallet0 = await buildDSAv2(wallet0.address);
|
||||
expect(!!dsaWallet0.address).to.be.true;
|
||||
});
|
||||
|
||||
it("Deposit ETH & DAI into DSA wallet", async function () {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: ethers.utils.parseEther("10")
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
|
||||
|
||||
await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("100000"));
|
||||
});
|
||||
|
||||
it("Deposit ETH & USDT into DSA wallet", async function () {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: ethers.utils.parseEther("10")
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
|
||||
|
||||
await addLiquidity("usdt", dsaWallet0.address, ethers.utils.parseEther("100000"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("Main", function () {
|
||||
it("Should deposit successfully", async function () {
|
||||
const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH
|
||||
const daiUnitAmount = ethers.utils.parseEther("4000"); // 1 ETH
|
||||
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
||||
|
||||
const getId = "0";
|
||||
const setId = "0";
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, "500000000000000000", getId, setId]
|
||||
}
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
|
||||
let receipt = await tx.wait();
|
||||
}).timeout(10000000000);
|
||||
|
||||
it("Should withdraw successfully", async function () {
|
||||
const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH
|
||||
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
||||
|
||||
const getId = "0";
|
||||
const setIds = ["0", "0"];
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "withdraw",
|
||||
args: [ethAddress, DAI_ADDR, ethAmount, 0, 0, getId, setIds]
|
||||
}
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
|
||||
let receipt = await tx.wait();
|
||||
});
|
||||
|
||||
it("Should buy successfully", async function () {
|
||||
const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH
|
||||
const daiUnitAmount = ethers.utils.parseEther("4000"); // 1 ETH
|
||||
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
||||
|
||||
const getId = "0";
|
||||
const setId = "0";
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "buy",
|
||||
args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, getId, setId]
|
||||
}
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
|
||||
let receipt = await tx.wait();
|
||||
});
|
||||
});
|
||||
});
|
235
test/mainnet/sushiswapIncentive/sushiswapIncentive.test.ts
Normal file
235
test/mainnet/sushiswapIncentive/sushiswapIncentive.test.ts
Normal file
|
@ -0,0 +1,235 @@
|
|||
import { expect } from "chai";
|
||||
import hre from "hardhat";
|
||||
const { waffle, ethers } = hre;
|
||||
const { provider } = waffle
|
||||
|
||||
import {deployAndEnableConnector} from "../../../scripts/tests/deployAndEnableConnector";
|
||||
import {buildDSAv2} from "../../../scripts/tests/buildDSAv2";
|
||||
import {encodeSpells} from "../../../scripts/tests/encodeSpells";
|
||||
import {getMasterSigner} from "../../../scripts/tests/getMasterSigner";
|
||||
import {addLiquidity} from "../../../scripts/tests/addLiquidity";
|
||||
import {addresses} from "../../../scripts/tests/mainnet/addresses";
|
||||
import {abis} from "../../../scripts/constant/abis";
|
||||
|
||||
import { ConnectV2Sushiswap__factory, ConnectV2Sushiswap, ConnectV2SushiswapIncentive, ConnectV2SushiswapIncentive__factory } from "../../../typechain";
|
||||
import { Contract, Signer } from "ethers";
|
||||
|
||||
const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f"
|
||||
const WETH_ADDR = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
||||
|
||||
describe("Sushiswap", function () {
|
||||
const connectorName = "Sushiswap-v1"
|
||||
const incentiveConnectorName = "Sushiswp-Incentive-v1"
|
||||
|
||||
let dsaWallet0: Contract;
|
||||
let masterSigner: Signer;
|
||||
let instaConnectorsV2: Contract;
|
||||
let connector: Contract, connectorIncentive;
|
||||
|
||||
const wallets = provider.getWallets()
|
||||
const [wallet0, wallet1, wallet2, wallet3] = wallets
|
||||
before(async () => {
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_reset",
|
||||
params: [
|
||||
{
|
||||
forking: {
|
||||
// @ts-ignore
|
||||
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
|
||||
blockNumber: 13005785,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
masterSigner = await getMasterSigner()
|
||||
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName,
|
||||
contractArtifact: ConnectV2Sushiswap__factory,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
})
|
||||
console.log("Connector address", connector.address)
|
||||
|
||||
connectorIncentive = await deployAndEnableConnector({
|
||||
connectorName: incentiveConnectorName,
|
||||
contractArtifact: ConnectV2SushiswapIncentive__factory,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
})
|
||||
console.log("Incentive Connector address", connectorIncentive.address)
|
||||
})
|
||||
|
||||
it("Should have contracts deployed.", async function () {
|
||||
expect(!!instaConnectorsV2.address).to.be.true;
|
||||
expect(!!connector.address).to.be.true;
|
||||
expect(!!(await masterSigner.getAddress())).to.be.true;
|
||||
});
|
||||
|
||||
describe("DSA wallet setup", function () {
|
||||
it("Should build DSA v2", async function () {
|
||||
dsaWallet0 = await buildDSAv2(wallet0.address)
|
||||
expect(!!dsaWallet0.address).to.be.true;
|
||||
});
|
||||
|
||||
it("Deposit ETH & DAI into DSA wallet", async function () {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: ethers.utils.parseEther("10")
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
|
||||
|
||||
await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("100000"));
|
||||
});
|
||||
|
||||
it("Deposit ETH & USDT into DSA wallet", async function () {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: ethers.utils.parseEther("10")
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
|
||||
|
||||
await addLiquidity("usdt", dsaWallet0.address, ethers.utils.parseEther("100000"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("Main", function () {
|
||||
it("Should deposit successfully", async function () {
|
||||
const ethAmount = ethers.utils.parseEther("2") // 1 ETH
|
||||
const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH
|
||||
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
||||
|
||||
const getId = "0"
|
||||
const setId = "0"
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: [
|
||||
ethAddress,
|
||||
DAI_ADDR,
|
||||
ethAmount,
|
||||
daiUnitAmount,
|
||||
"500000000000000000",
|
||||
getId,
|
||||
setId
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
await tx.wait()
|
||||
|
||||
describe("Incentive", () => {
|
||||
it("Should deposit successfully", async () => {
|
||||
const getId = 0
|
||||
const setId = 0
|
||||
const spells = [
|
||||
{
|
||||
connector: incentiveConnectorName,
|
||||
method: "deposit",
|
||||
args: [
|
||||
WETH_ADDR,
|
||||
DAI_ADDR,
|
||||
ethers.utils.parseEther("10"),
|
||||
getId,
|
||||
setId
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address)
|
||||
await tx.wait();
|
||||
})
|
||||
|
||||
it("Should harvest successfully", async () => {
|
||||
const setId = 0
|
||||
const spells = [
|
||||
{
|
||||
connector: incentiveConnectorName,
|
||||
method: "harvest",
|
||||
args: [
|
||||
WETH_ADDR,
|
||||
DAI_ADDR,
|
||||
setId
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address)
|
||||
await tx.wait();
|
||||
})
|
||||
|
||||
it("Should harvest and withdraw successfully", async () => {
|
||||
const getId = 0
|
||||
const setId = 0
|
||||
const spells = [
|
||||
{
|
||||
connector: incentiveConnectorName,
|
||||
method: "withdrawAndHarvest",
|
||||
args: [
|
||||
WETH_ADDR,
|
||||
DAI_ADDR,
|
||||
ethers.utils.parseEther("1"),
|
||||
getId,
|
||||
setId
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address)
|
||||
await tx.wait();
|
||||
})
|
||||
|
||||
it("Should withdraw successfully", async () => {
|
||||
const getId = 0
|
||||
const setId = 0
|
||||
const spells = [
|
||||
{
|
||||
connector: incentiveConnectorName,
|
||||
method: "withdraw",
|
||||
args: [
|
||||
WETH_ADDR,
|
||||
DAI_ADDR,
|
||||
ethers.utils.parseEther("1"),
|
||||
getId,
|
||||
setId
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address)
|
||||
await tx.wait();
|
||||
})
|
||||
})
|
||||
}).timeout(10000000000);
|
||||
|
||||
it("Should buy successfully", async function () {
|
||||
const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH
|
||||
const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH
|
||||
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
||||
|
||||
const getId = "0"
|
||||
const setId = "0"
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "buy",
|
||||
args: [
|
||||
ethAddress,
|
||||
DAI_ADDR,
|
||||
ethAmount,
|
||||
daiUnitAmount,
|
||||
getId,
|
||||
setId
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
let receipt = await tx.wait()
|
||||
});
|
||||
});
|
||||
})
|
462
test/mainnet/ubiquity/ubiquity.test.ts
Normal file
462
test/mainnet/ubiquity/ubiquity.test.ts
Normal file
|
@ -0,0 +1,462 @@
|
|||
import { expect } from "chai";
|
||||
import hre from "hardhat";
|
||||
const { waffle, ethers } = hre;
|
||||
const { provider } = waffle;
|
||||
const { BigNumber, utils } = ethers;
|
||||
|
||||
import {deployAndEnableConnector} from "../../../scripts/tests/deployAndEnableConnector";
|
||||
import {buildDSAv2} from "../../../scripts/tests/buildDSAv2";
|
||||
import {encodeSpells} from "../../../scripts/tests/encodeSpells";
|
||||
import {addresses} from "../../../scripts/tests/mainnet/addresses";
|
||||
import {abis} from "../../../scripts/constant/abis";
|
||||
import {impersonateAccounts} from "../../../scripts/tests/impersonate";
|
||||
import type { Signer, Contract, BigNumberish } from "ethers";
|
||||
import {forkReset, sendEth, mineNBlock} from "./utils";
|
||||
import { ConnectV2Ubiquity__factory } from "../../../typechain";
|
||||
|
||||
import { abi as implementationsABI } from "../../../scripts/constant/abi/core/InstaImplementations.json";
|
||||
const implementationsMappingAddr = "0xCBA828153d3a85b30B5b912e1f2daCac5816aE9D";
|
||||
|
||||
describe("Ubiquity", function () {
|
||||
const ubiquityTest = "UBIQUITY-TEST-A";
|
||||
|
||||
const BOND = "0x2dA07859613C14F6f05c97eFE37B9B4F212b5eF5";
|
||||
const UAD = "0x0F644658510c95CB46955e55D7BA9DDa9E9fBEc6";
|
||||
const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
|
||||
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
|
||||
const USDT = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
|
||||
const CRV3 = "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490";
|
||||
const POOL3 = "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7";
|
||||
const UAD3CRVF = "0x20955CB69Ae1515962177D164dfC9522feef567E";
|
||||
|
||||
const ethWhaleAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
|
||||
const uadWhaleAddress = "0xefC0e701A824943b469a694aC564Aa1efF7Ab7dd";
|
||||
|
||||
const blockFork = 13097100;
|
||||
const one = BigNumber.from(10).pow(18);
|
||||
const onep = BigNumber.from(10).pow(6);
|
||||
const ABI = [
|
||||
"function balanceOf(address owner) view returns (uint256)",
|
||||
"function allowance(address owner, address spender) external view returns (uint256)",
|
||||
"function transfer(address to, uint amount) returns (boolean)",
|
||||
"function remove_liquidity_one_coin(uint256 _burn_amount, int128 i, uint256 _min_received) external returns (uint256)",
|
||||
"function add_liquidity(uint256[3],uint256) returns (uint256)",
|
||||
"function approve(address, uint256) external",
|
||||
"function holderTokens(address) view returns (uint256[])",
|
||||
"function getBond(uint256) view returns (tuple(address,uint256,uint256,uint256,uint256,uint256))"
|
||||
];
|
||||
let dsa: Contract;
|
||||
let POOL3Contract: Contract;
|
||||
let CRV3Contract: Contract;
|
||||
let uAD3CRVfContract: Contract;
|
||||
let uADContract: Contract;
|
||||
let DAIContract: Contract;
|
||||
let USDCContract: Contract;
|
||||
let USDTContract: Contract;
|
||||
let BONDContract: Contract;
|
||||
let instaIndex: Contract;
|
||||
let instaConnectorsV2: Contract;
|
||||
let connector: Contract;
|
||||
let instaImplementationsMapping;
|
||||
let InstaAccountV2DefaultImpl;
|
||||
|
||||
let uadWhale;
|
||||
|
||||
const bondingShare = async function (address: any) {
|
||||
let lpAmount = BigNumber.from(0);
|
||||
let lpAmountTotal = BigNumber.from(0);
|
||||
let bondId = -1;
|
||||
|
||||
const bondIds = await BONDContract.holderTokens(address);
|
||||
const bondN = bondIds?.length || 0;
|
||||
|
||||
if (bondN) {
|
||||
for await (bondId of bondIds) {
|
||||
lpAmountTotal = lpAmountTotal.add((await BONDContract.getBond(bondId))[5]);
|
||||
}
|
||||
bondId = Number(bondIds[bondN - 1]);
|
||||
lpAmount = (await BONDContract.getBond(bondId))[5];
|
||||
}
|
||||
return { bondId, bondN, lpAmount, lpAmountTotal };
|
||||
};
|
||||
|
||||
const depositAndGetOneBond = async function () {
|
||||
await dsaDepositUAD3CRVf(100);
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "deposit",
|
||||
args: [UAD3CRVF, one.mul(100), 1, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
);
|
||||
};
|
||||
|
||||
before(async () => {
|
||||
// await forkReset(blockFork);
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_reset",
|
||||
params: [
|
||||
{
|
||||
forking: {
|
||||
// @ts-ignore
|
||||
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
|
||||
blockNumber: 13097100,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
[uadWhale] = await impersonateAccounts([uadWhaleAddress]);
|
||||
const [ethWhale] = await impersonateAccounts([ethWhaleAddress]);
|
||||
|
||||
await sendEth(ethWhale, uadWhaleAddress, 100);
|
||||
POOL3Contract = new ethers.Contract(POOL3, ABI, uadWhale);
|
||||
CRV3Contract = new ethers.Contract(CRV3, ABI, uadWhale);
|
||||
uAD3CRVfContract = new ethers.Contract(UAD3CRVF, ABI, uadWhale);
|
||||
uADContract = new ethers.Contract(UAD, ABI, uadWhale);
|
||||
DAIContract = new ethers.Contract(DAI, ABI, uadWhale);
|
||||
USDCContract = new ethers.Contract(USDC, ABI, uadWhale);
|
||||
USDTContract = new ethers.Contract(USDT, ABI, uadWhale);
|
||||
BONDContract = new ethers.Contract(BOND, ABI, uadWhale);
|
||||
dsa = (await buildDSAv2(uadWhaleAddress)).connect(uadWhale);
|
||||
await sendEth(ethWhale, dsa.address, 100);
|
||||
await sendEth(ethWhale, uadWhaleAddress, 100);
|
||||
|
||||
instaIndex = new ethers.Contract(addresses.core.instaIndex, abis.core.instaIndex, ethWhale);
|
||||
|
||||
const masterAddress = await instaIndex.master();
|
||||
const [master] = await impersonateAccounts([masterAddress]);
|
||||
await sendEth(ethWhale, masterAddress, 100);
|
||||
|
||||
instaConnectorsV2 = new ethers.Contract(addresses.core.connectorsV2, abis.core.connectorsV2);
|
||||
|
||||
instaImplementationsMapping = await ethers.getContractAt(implementationsABI, implementationsMappingAddr);
|
||||
InstaAccountV2DefaultImpl = await ethers.getContractFactory("InstaDefaultImplementation");
|
||||
InstaAccountV2DefaultImpl = await InstaAccountV2DefaultImpl.deploy(addresses.core.instaIndex);
|
||||
await InstaAccountV2DefaultImpl.deployed();
|
||||
await (
|
||||
await instaImplementationsMapping.connect(master).setDefaultImplementation(InstaAccountV2DefaultImpl.address)
|
||||
).wait();
|
||||
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName: ubiquityTest,
|
||||
contractArtifact: ConnectV2Ubiquity__factory,
|
||||
signer: master,
|
||||
connectors: instaConnectorsV2
|
||||
});
|
||||
});
|
||||
|
||||
const logAll = async function () {
|
||||
console.log("dsa eth", utils.formatEther(await ethers.provider.getBalance(dsa.address)));
|
||||
console.log("dsa dai", utils.formatEther(await DAIContract.balanceOf(dsa.address)));
|
||||
console.log("dsa usdc", utils.formatUnits(await USDCContract.balanceOf(dsa.address), 6));
|
||||
console.log("dsa usdt", utils.formatUnits(await USDTContract.balanceOf(dsa.address), 6));
|
||||
console.log("dsa uad", utils.formatEther(await uADContract.balanceOf(dsa.address)));
|
||||
console.log("dsa 3CRV", utils.formatEther(await CRV3Contract.balanceOf(dsa.address)));
|
||||
console.log("dsa uad3CRV-f", utils.formatEther(await uAD3CRVfContract.balanceOf(dsa.address)));
|
||||
const { bondId, bondN, lpAmount, lpAmountTotal } = await bondingShare(dsa.address);
|
||||
console.log("dsa n bonds", utils.formatEther(lpAmountTotal), bondN);
|
||||
console.log("dsa last bond", utils.formatEther(lpAmount), bondId);
|
||||
};
|
||||
|
||||
afterEach(logAll);
|
||||
|
||||
const dsaDepositUAD3CRVf = async (amount: BigNumberish) => {
|
||||
await uAD3CRVfContract.transfer(dsa.address, one.mul(amount));
|
||||
};
|
||||
|
||||
const dsaDepositUAD = async (amount: BigNumberish) => {
|
||||
await uAD3CRVfContract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 0, one.mul(amount));
|
||||
await uADContract.transfer(dsa.address, one.mul(amount));
|
||||
};
|
||||
|
||||
const dsaDepositCRV3 = async (amount: BigNumberish) => {
|
||||
await uAD3CRVfContract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 1, one.mul(amount));
|
||||
await CRV3Contract.transfer(dsa.address, one.mul(amount));
|
||||
};
|
||||
|
||||
const dsaDepositDAI = async (amount: BigNumberish) => {
|
||||
await uAD3CRVfContract.remove_liquidity_one_coin(
|
||||
one.mul(amount).mul(120).div(100),
|
||||
1,
|
||||
one.mul(amount).mul(110).div(100)
|
||||
);
|
||||
await POOL3Contract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 0, one.mul(amount));
|
||||
await DAIContract.transfer(dsa.address, one.mul(amount));
|
||||
};
|
||||
const dsaDepositUSDC = async (amount: BigNumberish) => {
|
||||
await uAD3CRVfContract.remove_liquidity_one_coin(
|
||||
one.mul(amount).mul(120).div(100),
|
||||
1,
|
||||
one.mul(amount).mul(110).div(100)
|
||||
);
|
||||
await POOL3Contract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 1, onep.mul(amount));
|
||||
await USDCContract.transfer(dsa.address, onep.mul(amount));
|
||||
};
|
||||
const dsaDepositUSDT = async (amount: BigNumberish) => {
|
||||
await uAD3CRVfContract.remove_liquidity_one_coin(
|
||||
one.mul(amount).mul(120).div(100),
|
||||
1,
|
||||
one.mul(amount).mul(110).div(100)
|
||||
);
|
||||
await POOL3Contract.remove_liquidity_one_coin(one.mul(amount).mul(110).div(100), 2, onep.mul(amount));
|
||||
await USDTContract.transfer(dsa.address, onep.mul(amount));
|
||||
};
|
||||
|
||||
describe("Deposit", function () {
|
||||
it("should deposit uAD3CRVf to get Ubiquity Bonding Shares", async function () {
|
||||
await logAll();
|
||||
await dsaDepositUAD3CRVf(100);
|
||||
expect((await bondingShare(dsa.address)).lpAmount).to.be.equal(0);
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "deposit",
|
||||
args: [UAD3CRVF, one.mul(100), 4, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
|
||||
});
|
||||
|
||||
it("should deposit uAD to get Ubiquity Bonding Shares", async function () {
|
||||
await dsaDepositUAD(100);
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "deposit",
|
||||
args: [UAD, one.mul(100), 4, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
|
||||
});
|
||||
|
||||
it("should deposit 3CRV to get Ubiquity Bonding Shares", async function () {
|
||||
await dsaDepositCRV3(100);
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "deposit",
|
||||
args: [CRV3, one.mul(100), 4, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
|
||||
});
|
||||
|
||||
it("should deposit DAI to get Ubiquity Bonding Shares", async function () {
|
||||
await dsaDepositDAI(100);
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "deposit",
|
||||
args: [DAI, one.mul(100), 4, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
|
||||
});
|
||||
|
||||
it("should deposit USDC to get Ubiquity Bonding Shares", async function () {
|
||||
await dsaDepositUSDC(100);
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "deposit",
|
||||
args: [USDC, onep.mul(100), 4, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
|
||||
});
|
||||
|
||||
it("should deposit USDT to get Ubiquity Bonding Shares", async function () {
|
||||
await dsaDepositUSDT(100);
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "deposit",
|
||||
args: [USDT, onep.mul(100), 4, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
expect((await bondingShare(dsa.address)).lpAmount).to.be.gt(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Withdraw", function () {
|
||||
let bondId = -1;
|
||||
|
||||
before(async () => {
|
||||
await depositAndGetOneBond();
|
||||
await depositAndGetOneBond();
|
||||
await depositAndGetOneBond();
|
||||
await depositAndGetOneBond();
|
||||
await depositAndGetOneBond();
|
||||
await depositAndGetOneBond();
|
||||
({ bondId } = await bondingShare(dsa.address));
|
||||
|
||||
await logAll();
|
||||
console.log("Mining 50 000 blocks for more than one week, please wait...");
|
||||
await mineNBlock(50000, 1);
|
||||
});
|
||||
|
||||
it("Should deposit and withdraw DAI", async function () {
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "withdraw",
|
||||
args: [bondId, DAI, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
});
|
||||
|
||||
it("Should deposit and withdraw USDC", async function () {
|
||||
// await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "withdraw",
|
||||
args: [bondId - 1, USDC, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
);
|
||||
// ).to.be.not.reverted;
|
||||
});
|
||||
|
||||
it("Should deposit and withdraw USDT", async function () {
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "withdraw",
|
||||
args: [bondId - 2, USDT, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
});
|
||||
|
||||
it("Should deposit and withdraw UAD", async function () {
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "withdraw",
|
||||
args: [bondId - 3, UAD, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
});
|
||||
|
||||
it("Should deposit and withdraw CRV3", async function () {
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "withdraw",
|
||||
args: [bondId - 4, CRV3, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
});
|
||||
|
||||
it("Should deposit and withdraw UAD3CRVF", async function () {
|
||||
await expect(
|
||||
dsa.cast(
|
||||
...encodeSpells([
|
||||
{
|
||||
connector: ubiquityTest,
|
||||
method: "withdraw",
|
||||
args: [bondId - 5, UAD3CRVF, 0, 0]
|
||||
}
|
||||
]),
|
||||
uadWhaleAddress
|
||||
)
|
||||
).to.be.not.reverted;
|
||||
});
|
||||
});
|
||||
|
||||
describe("DSA wallet setup", function () {
|
||||
it("Should have contracts deployed.", async function () {
|
||||
expect(POOL3Contract.address).to.be.properAddress;
|
||||
expect(CRV3Contract.address).to.be.properAddress;
|
||||
expect(uADContract.address).to.be.properAddress;
|
||||
expect(uAD3CRVfContract.address).to.be.properAddress;
|
||||
expect(DAIContract.address).to.be.properAddress;
|
||||
expect(USDCContract.address).to.be.properAddress;
|
||||
expect(USDTContract.address).to.be.properAddress;
|
||||
expect(BONDContract.address).to.be.properAddress;
|
||||
expect(instaIndex.address).to.be.properAddress;
|
||||
expect(instaConnectorsV2.address).to.be.properAddress;
|
||||
expect(connector.address).to.be.properAddress;
|
||||
expect(dsa.address).to.be.properAddress;
|
||||
});
|
||||
it("Should deposit uAD3CRVf into DSA wallet", async function () {
|
||||
await dsaDepositUAD3CRVf(100);
|
||||
expect(await uAD3CRVfContract.balanceOf(dsa.address)).to.be.gte(one.mul(100));
|
||||
});
|
||||
it("Should deposit uAD into DSA wallet", async function () {
|
||||
await dsaDepositUAD(100);
|
||||
expect(await uADContract.balanceOf(dsa.address)).to.be.gte(one.mul(100));
|
||||
});
|
||||
it("Should deposit 3CRV into DSA wallet", async function () {
|
||||
await dsaDepositCRV3(100);
|
||||
expect(await CRV3Contract.balanceOf(dsa.address)).to.be.gte(one.mul(100));
|
||||
});
|
||||
it("Should deposit DAI into DSA wallet", async function () {
|
||||
await dsaDepositDAI(100);
|
||||
expect(await DAIContract.balanceOf(dsa.address)).to.be.gte(one.mul(100));
|
||||
});
|
||||
it("Should deposit USDC into DSA wallet", async function () {
|
||||
await dsaDepositUSDC(100);
|
||||
expect(await USDCContract.balanceOf(dsa.address)).to.be.gte(onep.mul(100));
|
||||
});
|
||||
it("Should deposit USDT into DSA wallet", async function () {
|
||||
await dsaDepositUSDT(100);
|
||||
expect(await USDTContract.balanceOf(dsa.address)).to.be.gte(onep.mul(100));
|
||||
});
|
||||
});
|
||||
});
|
55
test/mainnet/ubiquity/utils.ts
Normal file
55
test/mainnet/ubiquity/utils.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
import hre, { ethers, network } from "hardhat";
|
||||
import hardhatConfig from "../../../hardhat.config";
|
||||
|
||||
export async function forkReset(blockNumber: any) {
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_reset",
|
||||
params: [
|
||||
{
|
||||
forking: {
|
||||
// @ts-ignore
|
||||
jsonRpcUrl: hardhatConfig.networks.hardhat.forking.url,
|
||||
blockNumber
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
export async function mineBlock(timestamp: any) {
|
||||
await network.provider.request({
|
||||
method: "evm_mine",
|
||||
params: [timestamp]
|
||||
});
|
||||
}
|
||||
|
||||
export async function sendEth(from: any, to: any, amount: any) {
|
||||
await from.sendTransaction({
|
||||
to: to,
|
||||
value: ethers.BigNumber.from(10).pow(18).mul(amount)
|
||||
});
|
||||
}
|
||||
|
||||
export async function mineNBlock(blockCount: any, secondsBetweenBlock: any) {
|
||||
const blockBefore = await ethers.provider.getBlock("latest");
|
||||
const maxMinedBlockPerBatch = 1000;
|
||||
let blockToMine = blockCount;
|
||||
let blockTime = blockBefore.timestamp;
|
||||
while (blockToMine > maxMinedBlockPerBatch) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
||||
const minings: any = [maxMinedBlockPerBatch].map((_v, i) => {
|
||||
const newTs = blockTime + i + (secondsBetweenBlock || 1);
|
||||
return mineBlock(newTs);
|
||||
});
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await Promise.all(minings);
|
||||
blockToMine -= maxMinedBlockPerBatch;
|
||||
blockTime = blockTime + maxMinedBlockPerBatch - 1 + maxMinedBlockPerBatch * (secondsBetweenBlock || 1);
|
||||
}
|
||||
const minings = [blockToMine].map((_v, i) => {
|
||||
const newTs = blockTime + i + (secondsBetweenBlock || 1);
|
||||
return mineBlock(newTs);
|
||||
});
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await Promise.all(minings);
|
||||
}
|
171
test/polygon/paraswap/paraswap.test.ts
Normal file
171
test/polygon/paraswap/paraswap.test.ts
Normal file
|
@ -0,0 +1,171 @@
|
|||
import hre from "hardhat";
|
||||
import { expect } from "chai";
|
||||
import { abis } from "../../../scripts/constant/abis";
|
||||
import { addresses } from "../../../scripts/tests/polygon/addresses";
|
||||
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
|
||||
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
|
||||
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
|
||||
import {
|
||||
ConnectV2ParaswapV5Polygon__factory
|
||||
} from "../../../typechain";
|
||||
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
|
||||
import BigNumber from "bignumber.js";
|
||||
import axios from "axios";
|
||||
// import { Signer } from "ethers";
|
||||
const { waffle, ethers } = hre;
|
||||
const { provider, deployContract } = waffle;
|
||||
import type { Signer, Contract } from "ethers";
|
||||
describe("Paraswap", function() {
|
||||
const connectorName = "paraswap-test";
|
||||
let dsaWallet0: any;
|
||||
let masterSigner: Signer;
|
||||
let instaConnectorsV2: Contract;
|
||||
let connector: any;
|
||||
const wallets = provider.getWallets();
|
||||
const [wallet0, wallet1] = wallets;
|
||||
before(async () => {
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_reset",
|
||||
params: [
|
||||
{
|
||||
forking: {
|
||||
// @ts-ignore
|
||||
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
masterSigner = await getMasterSigner();
|
||||
instaConnectorsV2 = await ethers.getContractAt(
|
||||
abis.core.connectorsV2,
|
||||
addresses.core.connectorsV2
|
||||
);
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName,
|
||||
contractArtifact: ConnectV2ParaswapV5Polygon__factory,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2,
|
||||
});
|
||||
console.log("Connector address", connector.address);
|
||||
});
|
||||
it("Should have contracts deployed.", async function() {
|
||||
expect(!!instaConnectorsV2.address).to.be.true;
|
||||
expect(!!connector.address).to.be.true;
|
||||
expect(!!masterSigner.getAddress()).to.be.true;
|
||||
});
|
||||
describe("DSA wallet setup", function() {
|
||||
it("Should build DSA v2", async function() {
|
||||
dsaWallet0 = await buildDSAv2(wallet0.address);
|
||||
expect(!!dsaWallet0.address).to.be.true;
|
||||
});
|
||||
it("Deposit ETH into DSA wallet", async function() {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: ethers.utils.parseEther("10"),
|
||||
});
|
||||
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
|
||||
ethers.utils.parseEther("10")
|
||||
);
|
||||
});
|
||||
});
|
||||
describe("Main", function() {
|
||||
it("should swap successfully", async function() {
|
||||
async function getArg() {
|
||||
const slippage = 1;
|
||||
/* matic -> USDT */
|
||||
const sellTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; // matic, decimals 18
|
||||
const sellTokenDecimals = 18;
|
||||
const buyTokenAddress = "0xc2132d05d31c914a87c6611c10748aeb04b58e8f"; // USDT, decimals 6
|
||||
const buyTokenDecimals = 6;
|
||||
const amount = 2;
|
||||
const srcAmount = new BigNumber(amount)
|
||||
.times(new BigNumber(10).pow(sellTokenDecimals))
|
||||
.toFixed(0);
|
||||
const fromAddress = dsaWallet0.address;
|
||||
let url = `https://apiv5.paraswap.io/prices/`;
|
||||
let params = {
|
||||
srcToken: sellTokenAddress,
|
||||
destToken: buyTokenAddress,
|
||||
srcDecimals: sellTokenDecimals,
|
||||
destDecimals: buyTokenDecimals,
|
||||
amount: srcAmount,
|
||||
side: "SELL",
|
||||
network: 137,
|
||||
};
|
||||
|
||||
const priceRoute = (await axios
|
||||
.get(url, { params: params })).data.priceRoute
|
||||
|
||||
|
||||
let buyTokenAmount = priceRoute.destAmount;
|
||||
let minAmount = new BigNumber(priceRoute.destAmount)
|
||||
.times(1 - slippage / 100)
|
||||
.toFixed(0);
|
||||
|
||||
let txConfig = {
|
||||
priceRoute: priceRoute,
|
||||
srcToken: sellTokenAddress,
|
||||
destToken: buyTokenAddress,
|
||||
srcDecimals: sellTokenDecimals,
|
||||
destDecimals: buyTokenDecimals,
|
||||
srcAmount: srcAmount,
|
||||
destAmount: minAmount,
|
||||
userAddress: fromAddress,
|
||||
};
|
||||
let url2 = "https://apiv5.paraswap.io/transactions/137?ignoreChecks=true";
|
||||
const calldata = (await axios
|
||||
.post(url2, txConfig)).data.data
|
||||
|
||||
function caculateUnitAmt(
|
||||
buyAmount: any,
|
||||
sellAmount: any,
|
||||
buyDecimal: any,
|
||||
sellDecimal: any,
|
||||
maxSlippage: any
|
||||
) {
|
||||
let unitAmt: any;
|
||||
unitAmt = new BigNumber(buyAmount)
|
||||
.dividedBy(10 ** buyDecimal)
|
||||
.dividedBy(new BigNumber(sellAmount).dividedBy(10 ** sellDecimal));
|
||||
unitAmt = unitAmt.multipliedBy((100 - maxSlippage) / 100);
|
||||
unitAmt = unitAmt.multipliedBy(1e18).toFixed(0);
|
||||
return unitAmt;
|
||||
}
|
||||
|
||||
let unitAmt = caculateUnitAmt(
|
||||
buyTokenAmount,
|
||||
srcAmount,
|
||||
buyTokenDecimals,
|
||||
sellTokenDecimals,
|
||||
1
|
||||
);
|
||||
|
||||
return [
|
||||
buyTokenAddress,
|
||||
sellTokenAddress,
|
||||
srcAmount,
|
||||
unitAmt,
|
||||
calldata,
|
||||
0,
|
||||
];
|
||||
}
|
||||
let arg = await getArg();
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "swap",
|
||||
args: arg,
|
||||
},
|
||||
];
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
const receipt = await tx.wait();
|
||||
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
|
||||
ethers.utils.parseEther("8")
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
137
test/polygon/quickswap/quickswap.test.ts
Normal file
137
test/polygon/quickswap/quickswap.test.ts
Normal file
|
@ -0,0 +1,137 @@
|
|||
import { expect } from "chai";
|
||||
import hre from "hardhat";
|
||||
const { waffle, ethers } = hre;
|
||||
const { provider } = waffle;
|
||||
|
||||
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
|
||||
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
|
||||
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
|
||||
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
|
||||
import { addLiquidity } from "../../../scripts/tests/addLiquidity";
|
||||
|
||||
import { addresses } from "../../../scripts/tests/polygon/addresses";
|
||||
import { abis } from "../../../scripts/constant/abis";
|
||||
import { ConnectV2QuickswapPolygon__factory, ConnectV2QuickswapPolygon } from "../../../typechain";
|
||||
import type { Signer, Contract } from "ethers";
|
||||
|
||||
const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063";
|
||||
|
||||
describe("Quickswap", function () {
|
||||
const connectorName = "Quickswap-v1";
|
||||
|
||||
let dsaWallet0: Contract;
|
||||
let masterSigner: Signer;
|
||||
let instaConnectorsV2: Contract;
|
||||
let connector: Contract;
|
||||
|
||||
const wallets = provider.getWallets();
|
||||
const [wallet0, wallet1, wallet2, wallet3] = wallets;
|
||||
before(async () => {
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_reset",
|
||||
params: [
|
||||
{
|
||||
forking: {
|
||||
// @ts-ignore
|
||||
jsonRpcUrl: hre.config.networks.hardhat.forking.url
|
||||
// blockNumber: 13005785
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
masterSigner = await getMasterSigner();
|
||||
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName,
|
||||
contractArtifact: ConnectV2QuickswapPolygon__factory,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
});
|
||||
console.log("Connector address", connector.address);
|
||||
});
|
||||
|
||||
it("Should have contracts deployed.", async function () {
|
||||
expect(!!instaConnectorsV2.address).to.be.true;
|
||||
expect(!!connector.address).to.be.true;
|
||||
expect(!!(await masterSigner.getAddress())).to.be.true;
|
||||
});
|
||||
|
||||
describe("DSA wallet setup", function () {
|
||||
it("Should build DSA v2", async function () {
|
||||
dsaWallet0 = await buildDSAv2(wallet0.address);
|
||||
expect(!!dsaWallet0.address).to.be.true;
|
||||
});
|
||||
|
||||
it("Deposit ETH & DAI into DSA wallet", async function () {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: ethers.utils.parseEther("10")
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
|
||||
|
||||
await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("10000"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("Main", function () {
|
||||
it("Should deposit successfully", async function () {
|
||||
const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH
|
||||
const daiUnitAmount = ethers.utils.parseEther("1"); // 1 ETH
|
||||
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
||||
|
||||
const getId = "0";
|
||||
const setId = "0";
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, "500000000000000000", getId, setId]
|
||||
}
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
|
||||
let receipt = await tx.wait();
|
||||
}).timeout(10000000000);
|
||||
|
||||
it("Should withdraw successfully", async function () {
|
||||
const ethAmount = ethers.utils.parseEther("0.001"); // 1 ETH
|
||||
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
||||
|
||||
const getId = "0";
|
||||
const setIds = ["0", "0"];
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "withdraw",
|
||||
args: [ethAddress, DAI_ADDR, ethAmount, 0, 0, getId, setIds]
|
||||
}
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
|
||||
let receipt = await tx.wait();
|
||||
});
|
||||
|
||||
it("Should buy successfully", async function () {
|
||||
const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH
|
||||
const daiUnitAmount = ethers.utils.parseEther("4000"); // 1 ETH
|
||||
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
||||
|
||||
const getId = "0";
|
||||
const setId = "0";
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "buy",
|
||||
args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, getId, setId]
|
||||
}
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
|
||||
let receipt = await tx.wait();
|
||||
});
|
||||
});
|
||||
});
|
515
yarn.lock
515
yarn.lock
|
@ -2,6 +2,27 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@^7.0.0":
|
||||
"integrity" "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA=="
|
||||
"resolved" "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz"
|
||||
"version" "7.16.0"
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.16.0"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.15.7":
|
||||
"integrity" "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w=="
|
||||
"resolved" "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz"
|
||||
"version" "7.15.7"
|
||||
|
||||
"@babel/highlight@^7.16.0":
|
||||
"integrity" "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g=="
|
||||
"resolved" "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz"
|
||||
"version" "7.16.0"
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.15.7"
|
||||
"chalk" "^2.0.0"
|
||||
"js-tokens" "^4.0.0"
|
||||
|
||||
"@babel/runtime@^7.4.4":
|
||||
"integrity" "sha512-121rumjddw9c3NCQ55KGkyE1h/nzWhU/owjhw0l4mQrkzz4x9SGS1X8gFLraHwX7td3Yo4QTL+qj0NcIzN87BA=="
|
||||
"resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.5.tgz"
|
||||
|
@ -1700,6 +1721,11 @@
|
|||
dependencies:
|
||||
"acorn" "^4.0.3"
|
||||
|
||||
"acorn-jsx@^5.0.0":
|
||||
"integrity" "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="
|
||||
"resolved" "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
|
||||
"version" "5.3.2"
|
||||
|
||||
"acorn-walk@^8.1.1":
|
||||
"integrity" "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA=="
|
||||
"resolved" "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz"
|
||||
|
@ -1715,7 +1741,7 @@
|
|||
"resolved" "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz"
|
||||
"version" "5.7.4"
|
||||
|
||||
"acorn@^6.4.1":
|
||||
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", "acorn@^6.0.7", "acorn@^6.4.1":
|
||||
"integrity" "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ=="
|
||||
"resolved" "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz"
|
||||
"version" "6.4.2"
|
||||
|
@ -1760,7 +1786,7 @@
|
|||
"resolved" "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz"
|
||||
"version" "3.5.2"
|
||||
|
||||
"ajv@^6.1.0", "ajv@^6.10.0", "ajv@^6.10.2", "ajv@^6.12.3", "ajv@^6.9.1", "ajv@>=5.0.0":
|
||||
"ajv@^6.1.0", "ajv@^6.10.0", "ajv@^6.10.2", "ajv@^6.12.3", "ajv@^6.6.1", "ajv@^6.9.1", "ajv@>=5.0.0":
|
||||
"integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="
|
||||
"resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
|
||||
"version" "6.12.6"
|
||||
|
@ -1799,6 +1825,11 @@
|
|||
"resolved" "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz"
|
||||
"version" "3.2.3"
|
||||
|
||||
"ansi-escapes@^3.2.0":
|
||||
"integrity" "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ=="
|
||||
"resolved" "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz"
|
||||
"version" "3.2.0"
|
||||
|
||||
"ansi-escapes@^4.2.1", "ansi-escapes@^4.3.0":
|
||||
"integrity" "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="
|
||||
"resolved" "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz"
|
||||
|
@ -1854,6 +1885,11 @@
|
|||
dependencies:
|
||||
"color-convert" "^2.0.1"
|
||||
|
||||
"antlr4@4.7.1":
|
||||
"integrity" "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ=="
|
||||
"resolved" "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz"
|
||||
"version" "4.7.1"
|
||||
|
||||
"antlr4ts@^0.5.0-alpha.4":
|
||||
"integrity" "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ=="
|
||||
"resolved" "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz"
|
||||
|
@ -1996,6 +2032,16 @@
|
|||
"resolved" "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz"
|
||||
"version" "1.0.0"
|
||||
|
||||
"ast-parents@0.0.1":
|
||||
"integrity" "sha1-UI/Q8F0MSHddnszaLhdEIyYejdM="
|
||||
"resolved" "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz"
|
||||
"version" "0.0.1"
|
||||
|
||||
"astral-regex@^1.0.0":
|
||||
"integrity" "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg=="
|
||||
"resolved" "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz"
|
||||
"version" "1.0.0"
|
||||
|
||||
"async-each@^1.0.1":
|
||||
"integrity" "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ=="
|
||||
"resolved" "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz"
|
||||
|
@ -2940,6 +2986,30 @@
|
|||
"function-bind" "^1.1.1"
|
||||
"get-intrinsic" "^1.0.2"
|
||||
|
||||
"caller-callsite@^2.0.0":
|
||||
"integrity" "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ="
|
||||
"resolved" "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
dependencies:
|
||||
"callsites" "^2.0.0"
|
||||
|
||||
"caller-path@^2.0.0":
|
||||
"integrity" "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ="
|
||||
"resolved" "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
dependencies:
|
||||
"caller-callsite" "^2.0.0"
|
||||
|
||||
"callsites@^2.0.0":
|
||||
"integrity" "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA="
|
||||
"resolved" "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"callsites@^3.0.0":
|
||||
"integrity" "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
|
||||
"resolved" "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
|
||||
"version" "3.1.0"
|
||||
|
||||
"camel-case@^3.0.0", "camel-case@3.0.x":
|
||||
"integrity" "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M="
|
||||
"resolved" "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz"
|
||||
|
@ -3030,6 +3100,24 @@
|
|||
"strip-ansi" "^3.0.0"
|
||||
"supports-color" "^2.0.0"
|
||||
|
||||
"chalk@^2.0.0":
|
||||
"integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="
|
||||
"resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
|
||||
"version" "2.4.2"
|
||||
dependencies:
|
||||
"ansi-styles" "^3.2.1"
|
||||
"escape-string-regexp" "^1.0.5"
|
||||
"supports-color" "^5.3.0"
|
||||
|
||||
"chalk@^2.1.0", "chalk@^2.4.2":
|
||||
"integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="
|
||||
"resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
|
||||
"version" "2.4.2"
|
||||
dependencies:
|
||||
"ansi-styles" "^3.2.1"
|
||||
"escape-string-regexp" "^1.0.5"
|
||||
"supports-color" "^5.3.0"
|
||||
|
||||
"chalk@^2.3.2":
|
||||
"integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="
|
||||
"resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
|
||||
|
@ -3048,15 +3136,6 @@
|
|||
"escape-string-regexp" "^1.0.5"
|
||||
"supports-color" "^5.3.0"
|
||||
|
||||
"chalk@^2.4.2":
|
||||
"integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="
|
||||
"resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
|
||||
"version" "2.4.2"
|
||||
dependencies:
|
||||
"ansi-styles" "^3.2.1"
|
||||
"escape-string-regexp" "^1.0.5"
|
||||
"supports-color" "^5.3.0"
|
||||
|
||||
"chalk@^4.1.0":
|
||||
"integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="
|
||||
"resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
|
||||
|
@ -3254,6 +3333,13 @@
|
|||
dependencies:
|
||||
"source-map" "~0.6.0"
|
||||
|
||||
"cli-cursor@^2.1.0":
|
||||
"integrity" "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU="
|
||||
"resolved" "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz"
|
||||
"version" "2.1.0"
|
||||
dependencies:
|
||||
"restore-cursor" "^2.0.0"
|
||||
|
||||
"cli-cursor@^3.1.0":
|
||||
"integrity" "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="
|
||||
"resolved" "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz"
|
||||
|
@ -3266,6 +3352,11 @@
|
|||
"resolved" "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz"
|
||||
"version" "2.6.1"
|
||||
|
||||
"cli-width@^2.0.0":
|
||||
"integrity" "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw=="
|
||||
"resolved" "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz"
|
||||
"version" "2.2.1"
|
||||
|
||||
"cli-width@^3.0.0":
|
||||
"integrity" "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw=="
|
||||
"resolved" "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz"
|
||||
|
@ -3396,6 +3487,11 @@
|
|||
"resolved" "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz"
|
||||
"version" "2.17.1"
|
||||
|
||||
"commander@2.18.0":
|
||||
"integrity" "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ=="
|
||||
"resolved" "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz"
|
||||
"version" "2.18.0"
|
||||
|
||||
"commander@3.0.2":
|
||||
"integrity" "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow=="
|
||||
"resolved" "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz"
|
||||
|
@ -3548,6 +3644,16 @@
|
|||
"object-assign" "^4"
|
||||
"vary" "^1"
|
||||
|
||||
"cosmiconfig@^5.0.7":
|
||||
"integrity" "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA=="
|
||||
"resolved" "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz"
|
||||
"version" "5.2.1"
|
||||
dependencies:
|
||||
"import-fresh" "^2.0.0"
|
||||
"is-directory" "^0.3.1"
|
||||
"js-yaml" "^3.13.1"
|
||||
"parse-json" "^4.0.0"
|
||||
|
||||
"crc-32@^1.2.0":
|
||||
"integrity" "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA=="
|
||||
"resolved" "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz"
|
||||
|
@ -3765,7 +3871,7 @@
|
|||
dependencies:
|
||||
"ms" "^2.1.1"
|
||||
|
||||
"debug@^4.1.1", "debug@^4.3.1", "debug@4":
|
||||
"debug@^4.0.1", "debug@^4.1.1", "debug@^4.3.1", "debug@4":
|
||||
"integrity" "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ=="
|
||||
"resolved" "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz"
|
||||
"version" "4.3.1"
|
||||
|
@ -3984,6 +4090,13 @@
|
|||
dependencies:
|
||||
"path-type" "^4.0.0"
|
||||
|
||||
"doctrine@^3.0.0":
|
||||
"integrity" "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="
|
||||
"resolved" "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
dependencies:
|
||||
"esutils" "^2.0.2"
|
||||
|
||||
"dom-converter@^0.2.0":
|
||||
"integrity" "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA=="
|
||||
"resolved" "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz"
|
||||
|
@ -4103,6 +4216,11 @@
|
|||
"minimalistic-assert" "^1.0.0"
|
||||
"minimalistic-crypto-utils" "^1.0.0"
|
||||
|
||||
"emoji-regex@^10.0.0":
|
||||
"integrity" "sha512-KmJa8l6uHi1HrBI34udwlzZY1jOEuID/ft4d8BSSEdRyap7PwBEt910453PJa5MuGvxkLqlt4Uvhu7tttFHViw=="
|
||||
"resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.0.0.tgz"
|
||||
"version" "10.0.0"
|
||||
|
||||
"emoji-regex@^7.0.1":
|
||||
"integrity" "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
|
||||
"resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz"
|
||||
|
@ -4207,7 +4325,7 @@
|
|||
dependencies:
|
||||
"prr" "~1.0.1"
|
||||
|
||||
"error-ex@^1.2.0":
|
||||
"error-ex@^1.2.0", "error-ex@^1.3.1":
|
||||
"integrity" "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="
|
||||
"resolved" "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz"
|
||||
"version" "1.3.2"
|
||||
|
@ -4357,6 +4475,11 @@
|
|||
"resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
|
||||
"version" "1.0.5"
|
||||
|
||||
"escape-string-regexp@^4.0.0":
|
||||
"integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||
"resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
|
||||
"escodegen@1.8.x":
|
||||
"integrity" "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg="
|
||||
"resolved" "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz"
|
||||
|
@ -4387,6 +4510,69 @@
|
|||
"esrecurse" "^4.1.0"
|
||||
"estraverse" "^4.1.1"
|
||||
|
||||
"eslint-utils@^1.3.1":
|
||||
"integrity" "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q=="
|
||||
"resolved" "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz"
|
||||
"version" "1.4.3"
|
||||
dependencies:
|
||||
"eslint-visitor-keys" "^1.1.0"
|
||||
|
||||
"eslint-visitor-keys@^1.0.0", "eslint-visitor-keys@^1.1.0":
|
||||
"integrity" "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
|
||||
"resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz"
|
||||
"version" "1.3.0"
|
||||
|
||||
"eslint@^5.6.0":
|
||||
"integrity" "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg=="
|
||||
"resolved" "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz"
|
||||
"version" "5.16.0"
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
"ajv" "^6.9.1"
|
||||
"chalk" "^2.1.0"
|
||||
"cross-spawn" "^6.0.5"
|
||||
"debug" "^4.0.1"
|
||||
"doctrine" "^3.0.0"
|
||||
"eslint-scope" "^4.0.3"
|
||||
"eslint-utils" "^1.3.1"
|
||||
"eslint-visitor-keys" "^1.0.0"
|
||||
"espree" "^5.0.1"
|
||||
"esquery" "^1.0.1"
|
||||
"esutils" "^2.0.2"
|
||||
"file-entry-cache" "^5.0.1"
|
||||
"functional-red-black-tree" "^1.0.1"
|
||||
"glob" "^7.1.2"
|
||||
"globals" "^11.7.0"
|
||||
"ignore" "^4.0.6"
|
||||
"import-fresh" "^3.0.0"
|
||||
"imurmurhash" "^0.1.4"
|
||||
"inquirer" "^6.2.2"
|
||||
"js-yaml" "^3.13.0"
|
||||
"json-stable-stringify-without-jsonify" "^1.0.1"
|
||||
"levn" "^0.3.0"
|
||||
"lodash" "^4.17.11"
|
||||
"minimatch" "^3.0.4"
|
||||
"mkdirp" "^0.5.1"
|
||||
"natural-compare" "^1.4.0"
|
||||
"optionator" "^0.8.2"
|
||||
"path-is-inside" "^1.0.2"
|
||||
"progress" "^2.0.0"
|
||||
"regexpp" "^2.0.1"
|
||||
"semver" "^5.5.1"
|
||||
"strip-ansi" "^4.0.0"
|
||||
"strip-json-comments" "^2.0.1"
|
||||
"table" "^5.2.3"
|
||||
"text-table" "^0.2.0"
|
||||
|
||||
"espree@^5.0.1":
|
||||
"integrity" "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A=="
|
||||
"resolved" "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz"
|
||||
"version" "5.0.1"
|
||||
dependencies:
|
||||
"acorn" "^6.0.7"
|
||||
"acorn-jsx" "^5.0.0"
|
||||
"eslint-visitor-keys" "^1.0.0"
|
||||
|
||||
"esprima@^2.7.1":
|
||||
"integrity" "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE="
|
||||
"resolved" "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz"
|
||||
|
@ -4402,6 +4588,13 @@
|
|||
"resolved" "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz"
|
||||
"version" "2.7.3"
|
||||
|
||||
"esquery@^1.0.1":
|
||||
"integrity" "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w=="
|
||||
"resolved" "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz"
|
||||
"version" "1.4.0"
|
||||
dependencies:
|
||||
"estraverse" "^5.1.0"
|
||||
|
||||
"esrecurse@^4.1.0":
|
||||
"integrity" "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="
|
||||
"resolved" "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz"
|
||||
|
@ -4419,6 +4612,11 @@
|
|||
"resolved" "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
|
||||
"version" "4.3.0"
|
||||
|
||||
"estraverse@^5.1.0":
|
||||
"integrity" "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
|
||||
"resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
|
||||
"version" "5.3.0"
|
||||
|
||||
"estraverse@^5.2.0":
|
||||
"integrity" "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
|
||||
"resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz"
|
||||
|
@ -4897,7 +5095,7 @@
|
|||
"uuid" "2.0.1"
|
||||
"xmlhttprequest" "1.8.0"
|
||||
|
||||
"ethers@^5.0.0", "ethers@^5.0.1", "ethers@^5.0.13", "ethers@^5.0.2", "ethers@^5.1.0", "ethers@^5.1.3", "ethers@^5.4.7", "ethers@^5.5.2":
|
||||
"ethers@^5.0.0", "ethers@^5.0.1", "ethers@^5.0.13", "ethers@^5.1.0", "ethers@^5.1.3", "ethers@^5.4.7", "ethers@^5.5.2":
|
||||
"integrity" "sha512-EF5W+6Wwcu6BqVwpgmyR5U2+L4c1FQzlM/02dkZOugN3KF0cG9bzHZP+TDJglmPm2/IzCEJDT7KBxzayk7SAHw=="
|
||||
"resolved" "https://registry.npmjs.org/ethers/-/ethers-5.5.2.tgz"
|
||||
"version" "5.5.2"
|
||||
|
@ -5151,6 +5349,11 @@
|
|||
"resolved" "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||
"version" "3.1.3"
|
||||
|
||||
"fast-diff@^1.1.2":
|
||||
"integrity" "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w=="
|
||||
"resolved" "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz"
|
||||
"version" "1.2.0"
|
||||
|
||||
"fast-glob@^3.0.3":
|
||||
"integrity" "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q=="
|
||||
"resolved" "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz"
|
||||
|
@ -5189,6 +5392,13 @@
|
|||
"resolved" "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz"
|
||||
"version" "3.5.2"
|
||||
|
||||
"figures@^2.0.0":
|
||||
"integrity" "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI="
|
||||
"resolved" "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
dependencies:
|
||||
"escape-string-regexp" "^1.0.5"
|
||||
|
||||
"figures@^3.0.0":
|
||||
"integrity" "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg=="
|
||||
"resolved" "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz"
|
||||
|
@ -5196,6 +5406,13 @@
|
|||
dependencies:
|
||||
"escape-string-regexp" "^1.0.5"
|
||||
|
||||
"file-entry-cache@^5.0.1":
|
||||
"integrity" "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g=="
|
||||
"resolved" "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz"
|
||||
"version" "5.0.1"
|
||||
dependencies:
|
||||
"flat-cache" "^2.0.1"
|
||||
|
||||
"file-uri-to-path@1.0.0":
|
||||
"integrity" "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
|
||||
"resolved" "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz"
|
||||
|
@ -5298,6 +5515,15 @@
|
|||
dependencies:
|
||||
"micromatch" "^4.0.2"
|
||||
|
||||
"flat-cache@^2.0.1":
|
||||
"integrity" "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA=="
|
||||
"resolved" "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
dependencies:
|
||||
"flatted" "^2.0.0"
|
||||
"rimraf" "2.6.3"
|
||||
"write" "1.0.3"
|
||||
|
||||
"flat@^4.1.0":
|
||||
"integrity" "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA=="
|
||||
"resolved" "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz"
|
||||
|
@ -5305,6 +5531,11 @@
|
|||
dependencies:
|
||||
"is-buffer" "~2.0.3"
|
||||
|
||||
"flatted@^2.0.0":
|
||||
"integrity" "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA=="
|
||||
"resolved" "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz"
|
||||
"version" "2.0.2"
|
||||
|
||||
"flow-stoplight@^1.0.0":
|
||||
"version" "1.0.0"
|
||||
|
||||
|
@ -5766,6 +5997,11 @@
|
|||
"min-document" "^2.19.0"
|
||||
"process" "^0.11.10"
|
||||
|
||||
"globals@^11.7.0":
|
||||
"integrity" "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
|
||||
"resolved" "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
|
||||
"version" "11.12.0"
|
||||
|
||||
"globals@^9.18.0":
|
||||
"version" "9.18.0"
|
||||
|
||||
|
@ -6279,6 +6515,11 @@
|
|||
"resolved" "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz"
|
||||
"version" "0.1.5"
|
||||
|
||||
"ignore@^4.0.6":
|
||||
"integrity" "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
|
||||
"resolved" "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz"
|
||||
"version" "4.0.6"
|
||||
|
||||
"ignore@^5.1.1":
|
||||
"integrity" "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ=="
|
||||
"resolved" "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz"
|
||||
|
@ -6299,6 +6540,22 @@
|
|||
"resolved" "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz"
|
||||
"version" "4.0.0-rc.12"
|
||||
|
||||
"import-fresh@^2.0.0":
|
||||
"integrity" "sha1-2BNVwVYS04bGH53dOSLUMEgipUY="
|
||||
"resolved" "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
dependencies:
|
||||
"caller-path" "^2.0.0"
|
||||
"resolve-from" "^3.0.0"
|
||||
|
||||
"import-fresh@^3.0.0":
|
||||
"integrity" "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw=="
|
||||
"resolved" "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
|
||||
"version" "3.3.0"
|
||||
dependencies:
|
||||
"parent-module" "^1.0.0"
|
||||
"resolve-from" "^4.0.0"
|
||||
|
||||
"imul@^1.0.0":
|
||||
"integrity" "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk="
|
||||
"resolved" "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz"
|
||||
|
@ -6342,6 +6599,25 @@
|
|||
"resolved" "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
|
||||
"version" "1.3.8"
|
||||
|
||||
"inquirer@^6.2.2":
|
||||
"integrity" "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ=="
|
||||
"resolved" "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz"
|
||||
"version" "6.5.2"
|
||||
dependencies:
|
||||
"ansi-escapes" "^3.2.0"
|
||||
"chalk" "^2.4.2"
|
||||
"cli-cursor" "^2.1.0"
|
||||
"cli-width" "^2.0.0"
|
||||
"external-editor" "^3.0.3"
|
||||
"figures" "^2.0.0"
|
||||
"lodash" "^4.17.12"
|
||||
"mute-stream" "0.0.7"
|
||||
"run-async" "^2.2.0"
|
||||
"rxjs" "^6.4.0"
|
||||
"string-width" "^2.1.0"
|
||||
"strip-ansi" "^5.1.0"
|
||||
"through" "^2.3.6"
|
||||
|
||||
"inquirer@^8.2.0":
|
||||
"integrity" "sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ=="
|
||||
"resolved" "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz"
|
||||
|
@ -6525,6 +6801,11 @@
|
|||
"is-data-descriptor" "^1.0.0"
|
||||
"kind-of" "^6.0.2"
|
||||
|
||||
"is-directory@^0.3.1":
|
||||
"integrity" "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE="
|
||||
"resolved" "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz"
|
||||
"version" "0.3.1"
|
||||
|
||||
"is-docker@^2.0.0":
|
||||
"integrity" "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="
|
||||
"resolved" "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
|
||||
|
@ -6825,7 +7106,7 @@
|
|||
"resolved" "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz"
|
||||
"version" "0.8.0"
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0":
|
||||
"js-tokens@^3.0.0 || ^4.0.0", "js-tokens@^4.0.0":
|
||||
"integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
"resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
|
@ -6833,7 +7114,7 @@
|
|||
"js-tokens@^3.0.2":
|
||||
"version" "3.0.2"
|
||||
|
||||
"js-yaml@^3.14.0", "js-yaml@3.x":
|
||||
"js-yaml@^3.12.0", "js-yaml@^3.13.0", "js-yaml@^3.13.1", "js-yaml@^3.14.0", "js-yaml@3.x":
|
||||
"integrity" "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="
|
||||
"resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz"
|
||||
"version" "3.14.1"
|
||||
|
@ -6870,7 +7151,7 @@
|
|||
"resolved" "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz"
|
||||
"version" "0.5.7"
|
||||
|
||||
"json-parse-better-errors@^1.0.2":
|
||||
"json-parse-better-errors@^1.0.1", "json-parse-better-errors@^1.0.2":
|
||||
"integrity" "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
|
||||
"resolved" "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
|
@ -6903,6 +7184,11 @@
|
|||
"resolved" "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz"
|
||||
"version" "0.2.3"
|
||||
|
||||
"json-stable-stringify-without-jsonify@^1.0.1":
|
||||
"integrity" "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
|
||||
"resolved" "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
|
||||
"json-stable-stringify@^1.0.1":
|
||||
"version" "1.0.1"
|
||||
dependencies:
|
||||
|
@ -7214,7 +7500,7 @@
|
|||
"level-supports" "~1.0.0"
|
||||
"xtend" "~4.0.0"
|
||||
|
||||
"levn@~0.3.0":
|
||||
"levn@^0.3.0", "levn@~0.3.0":
|
||||
"integrity" "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4="
|
||||
"resolved" "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz"
|
||||
"version" "0.3.0"
|
||||
|
@ -7325,7 +7611,7 @@
|
|||
"resolved" "https://registry.npmjs.org/lodash.sum/-/lodash.sum-4.0.2.tgz"
|
||||
"version" "4.0.2"
|
||||
|
||||
"lodash@^4.17.11", "lodash@^4.17.14", "lodash@^4.17.15", "lodash@^4.17.20", "lodash@^4.17.21", "lodash@^4.17.3":
|
||||
"lodash@^4.17.11", "lodash@^4.17.12", "lodash@^4.17.14", "lodash@^4.17.15", "lodash@^4.17.20", "lodash@^4.17.21", "lodash@^4.17.3":
|
||||
"integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
"resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
|
||||
"version" "4.17.21"
|
||||
|
@ -7929,6 +8215,11 @@
|
|||
"fmix" "^0.1.0"
|
||||
"imul" "^1.0.0"
|
||||
|
||||
"mute-stream@0.0.7":
|
||||
"integrity" "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
|
||||
"resolved" "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz"
|
||||
"version" "0.0.7"
|
||||
|
||||
"mute-stream@0.0.8":
|
||||
"integrity" "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
|
||||
"resolved" "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz"
|
||||
|
@ -7976,6 +8267,11 @@
|
|||
"resolved" "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
|
||||
"natural-compare@^1.4.0":
|
||||
"integrity" "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
|
||||
"resolved" "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
|
||||
"version" "1.4.0"
|
||||
|
||||
"negotiator@0.6.2":
|
||||
"integrity" "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
"resolved" "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz"
|
||||
|
@ -8314,6 +8610,13 @@
|
|||
dependencies:
|
||||
"wrappy" "1"
|
||||
|
||||
"onetime@^2.0.0":
|
||||
"integrity" "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ="
|
||||
"resolved" "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
dependencies:
|
||||
"mimic-fn" "^1.0.0"
|
||||
|
||||
"onetime@^5.1.0":
|
||||
"integrity" "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="
|
||||
"resolved" "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz"
|
||||
|
@ -8329,7 +8632,7 @@
|
|||
"is-docker" "^2.0.0"
|
||||
"is-wsl" "^2.1.1"
|
||||
|
||||
"optionator@^0.8.1":
|
||||
"optionator@^0.8.1", "optionator@^0.8.2":
|
||||
"integrity" "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA=="
|
||||
"resolved" "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz"
|
||||
"version" "0.8.3"
|
||||
|
@ -8499,6 +8802,13 @@
|
|||
dependencies:
|
||||
"no-case" "^2.2.0"
|
||||
|
||||
"parent-module@^1.0.0":
|
||||
"integrity" "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="
|
||||
"resolved" "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
dependencies:
|
||||
"callsites" "^3.0.0"
|
||||
|
||||
"parse-asn1@^5.0.0", "parse-asn1@^5.1.5":
|
||||
"integrity" "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw=="
|
||||
"resolved" "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz"
|
||||
|
@ -8522,6 +8832,14 @@
|
|||
dependencies:
|
||||
"error-ex" "^1.2.0"
|
||||
|
||||
"parse-json@^4.0.0":
|
||||
"integrity" "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA="
|
||||
"resolved" "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
dependencies:
|
||||
"error-ex" "^1.3.1"
|
||||
"json-parse-better-errors" "^1.0.1"
|
||||
|
||||
"parse5-htmlparser2-tree-adapter@^6.0.1":
|
||||
"integrity" "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA=="
|
||||
"resolved" "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz"
|
||||
|
@ -8631,6 +8949,11 @@
|
|||
"resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
|
||||
"path-is-inside@^1.0.2":
|
||||
"integrity" "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
|
||||
"resolved" "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
|
||||
"path-key@^2.0.0", "path-key@^2.0.1":
|
||||
"integrity" "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
|
||||
"resolved" "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz"
|
||||
|
@ -8848,15 +9171,32 @@
|
|||
"resolved" "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"prettier-plugin-solidity@^1.0.0-beta.18":
|
||||
"integrity" "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g=="
|
||||
"resolved" "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz"
|
||||
"version" "1.0.0-beta.19"
|
||||
dependencies:
|
||||
"@solidity-parser/parser" "^0.14.0"
|
||||
"emoji-regex" "^10.0.0"
|
||||
"escape-string-regexp" "^4.0.0"
|
||||
"semver" "^7.3.5"
|
||||
"solidity-comments-extractor" "^0.0.7"
|
||||
"string-width" "^4.2.3"
|
||||
|
||||
"prettier@^1.14.3":
|
||||
"integrity" "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew=="
|
||||
"resolved" "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz"
|
||||
"version" "1.19.1"
|
||||
|
||||
"prettier@^1.18.2":
|
||||
"integrity" "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew=="
|
||||
"resolved" "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz"
|
||||
"version" "1.19.1"
|
||||
|
||||
"prettier@^2.1.2":
|
||||
"integrity" "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ=="
|
||||
"resolved" "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz"
|
||||
"version" "2.3.2"
|
||||
"prettier@^2.1.2", "prettier@^2.3.0", "prettier@^2.4.1":
|
||||
"integrity" "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg=="
|
||||
"resolved" "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz"
|
||||
"version" "2.5.1"
|
||||
|
||||
"pretty-error@^2.0.2":
|
||||
"integrity" "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw=="
|
||||
|
@ -8884,6 +9224,11 @@
|
|||
"resolved" "https://registry.npmjs.org/process/-/process-0.11.10.tgz"
|
||||
"version" "0.11.10"
|
||||
|
||||
"progress@^2.0.0":
|
||||
"integrity" "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
|
||||
"resolved" "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
|
||||
"version" "2.0.3"
|
||||
|
||||
"promise-inflight@^1.0.1":
|
||||
"integrity" "sha1-mEcocL8igTL8vdhoEputEsPAKeM="
|
||||
"resolved" "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz"
|
||||
|
@ -9283,6 +9628,11 @@
|
|||
"define-properties" "^1.1.3"
|
||||
"es-abstract" "^1.17.0-next.1"
|
||||
|
||||
"regexpp@^2.0.1":
|
||||
"integrity" "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw=="
|
||||
"resolved" "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
|
||||
"regexpu-core@^2.0.0":
|
||||
"version" "2.0.0"
|
||||
dependencies:
|
||||
|
@ -9385,6 +9735,16 @@
|
|||
"resolved" "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"resolve-from@^3.0.0":
|
||||
"integrity" "sha1-six699nWiBvItuZTM17rywoYh0g="
|
||||
"resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
|
||||
"resolve-from@^4.0.0":
|
||||
"integrity" "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
|
||||
"resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
|
||||
"resolve-url@^0.2.1":
|
||||
"integrity" "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
|
||||
"resolved" "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz"
|
||||
|
@ -9414,6 +9774,14 @@
|
|||
dependencies:
|
||||
"lowercase-keys" "^1.0.0"
|
||||
|
||||
"restore-cursor@^2.0.0":
|
||||
"integrity" "sha1-n37ih/gv0ybU/RYpI9YhKe7g368="
|
||||
"resolved" "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
dependencies:
|
||||
"onetime" "^2.0.0"
|
||||
"signal-exit" "^3.0.2"
|
||||
|
||||
"restore-cursor@^3.1.0":
|
||||
"integrity" "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA=="
|
||||
"resolved" "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz"
|
||||
|
@ -9451,6 +9819,13 @@
|
|||
dependencies:
|
||||
"glob" "^7.1.3"
|
||||
|
||||
"rimraf@2.6.3":
|
||||
"integrity" "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="
|
||||
"resolved" "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz"
|
||||
"version" "2.6.3"
|
||||
dependencies:
|
||||
"glob" "^7.1.3"
|
||||
|
||||
"ripemd160-min@0.0.6":
|
||||
"integrity" "sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A=="
|
||||
"resolved" "https://registry.npmjs.org/ripemd160-min/-/ripemd160-min-0.0.6.tgz"
|
||||
|
@ -9471,7 +9846,7 @@
|
|||
dependencies:
|
||||
"bn.js" "^4.11.1"
|
||||
|
||||
"run-async@^2.4.0":
|
||||
"run-async@^2.2.0", "run-async@^2.4.0":
|
||||
"integrity" "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ=="
|
||||
"resolved" "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz"
|
||||
"version" "2.4.1"
|
||||
|
@ -9495,6 +9870,13 @@
|
|||
"resolved" "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz"
|
||||
"version" "0.2.0"
|
||||
|
||||
"rxjs@^6.4.0", "rxjs@6":
|
||||
"integrity" "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ=="
|
||||
"resolved" "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz"
|
||||
"version" "6.6.7"
|
||||
dependencies:
|
||||
"tslib" "^1.9.0"
|
||||
|
||||
"rxjs@^7.2.0":
|
||||
"integrity" "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w=="
|
||||
"resolved" "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz"
|
||||
|
@ -9502,13 +9884,6 @@
|
|||
dependencies:
|
||||
"tslib" "~2.1.0"
|
||||
|
||||
"rxjs@6":
|
||||
"integrity" "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ=="
|
||||
"resolved" "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz"
|
||||
"version" "6.6.7"
|
||||
dependencies:
|
||||
"tslib" "^1.9.0"
|
||||
|
||||
"safe-buffer@^5.0.1", "safe-buffer@^5.1.0", "safe-buffer@^5.1.1", "safe-buffer@^5.1.2", "safe-buffer@^5.2.0", "safe-buffer@^5.2.1", "safe-buffer@~5.2.0":
|
||||
"integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
|
||||
|
@ -9625,6 +10000,11 @@
|
|||
"resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
|
||||
"version" "5.7.1"
|
||||
|
||||
"semver@^5.5.1":
|
||||
"integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
"resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
|
||||
"version" "5.7.1"
|
||||
|
||||
"semver@^5.7.0":
|
||||
"integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
"resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
|
||||
|
@ -9831,6 +10211,15 @@
|
|||
"resolved" "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
|
||||
"slice-ansi@^2.1.0":
|
||||
"integrity" "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ=="
|
||||
"resolved" "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz"
|
||||
"version" "2.1.0"
|
||||
dependencies:
|
||||
"ansi-styles" "^3.2.0"
|
||||
"astral-regex" "^1.0.0"
|
||||
"is-fullwidth-code-point" "^2.0.0"
|
||||
|
||||
"snake-case@^2.1.0":
|
||||
"integrity" "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8="
|
||||
"resolved" "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz"
|
||||
|
@ -9923,6 +10312,33 @@
|
|||
"semver" "^5.5.0"
|
||||
"tmp" "0.0.33"
|
||||
|
||||
"solhint@^3.3.6":
|
||||
"integrity" "sha512-HWUxTAv2h7hx3s3hAab3ifnlwb02ZWhwFU/wSudUHqteMS3ll9c+m1FlGn9V8ztE2rf3Z82fQZA005Wv7KpcFA=="
|
||||
"resolved" "https://registry.npmjs.org/solhint/-/solhint-3.3.6.tgz"
|
||||
"version" "3.3.6"
|
||||
dependencies:
|
||||
"@solidity-parser/parser" "^0.13.2"
|
||||
"ajv" "^6.6.1"
|
||||
"antlr4" "4.7.1"
|
||||
"ast-parents" "0.0.1"
|
||||
"chalk" "^2.4.2"
|
||||
"commander" "2.18.0"
|
||||
"cosmiconfig" "^5.0.7"
|
||||
"eslint" "^5.6.0"
|
||||
"fast-diff" "^1.1.2"
|
||||
"glob" "^7.1.3"
|
||||
"ignore" "^4.0.6"
|
||||
"js-yaml" "^3.12.0"
|
||||
"lodash" "^4.17.11"
|
||||
"semver" "^6.3.0"
|
||||
optionalDependencies:
|
||||
"prettier" "^1.14.3"
|
||||
|
||||
"solidity-comments-extractor@^0.0.7":
|
||||
"integrity" "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw=="
|
||||
"resolved" "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz"
|
||||
"version" "0.0.7"
|
||||
|
||||
"solidity-coverage@0.7.17":
|
||||
"integrity" "sha512-Erw2hd2xdACAvDX8jUdYkmgJlIIazGznwDJA5dhRaw4def2SisXN9jUjneeyOZnl/E7j6D3XJYug4Zg9iwodsg=="
|
||||
"resolved" "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.17.tgz"
|
||||
|
@ -10147,7 +10563,7 @@
|
|||
"is-fullwidth-code-point" "^1.0.0"
|
||||
"strip-ansi" "^3.0.0"
|
||||
|
||||
"string-width@^1.0.2 || 2", "string-width@^2.0.0":
|
||||
"string-width@^1.0.2 || 2", "string-width@^2.0.0", "string-width@^2.1.0":
|
||||
"integrity" "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw=="
|
||||
"resolved" "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz"
|
||||
"version" "2.1.1"
|
||||
|
@ -10173,6 +10589,15 @@
|
|||
"is-fullwidth-code-point" "^3.0.0"
|
||||
"strip-ansi" "^6.0.1"
|
||||
|
||||
"string-width@^4.2.3":
|
||||
"integrity" "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="
|
||||
"resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
|
||||
"version" "4.2.3"
|
||||
dependencies:
|
||||
"emoji-regex" "^8.0.0"
|
||||
"is-fullwidth-code-point" "^3.0.0"
|
||||
"strip-ansi" "^6.0.1"
|
||||
|
||||
"string.prototype.trim@~1.2.1":
|
||||
"version" "1.2.3"
|
||||
dependencies:
|
||||
|
@ -10265,7 +10690,7 @@
|
|||
"resolved" "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"strip-json-comments@~2.0.1", "strip-json-comments@2.0.1":
|
||||
"strip-json-comments@^2.0.1", "strip-json-comments@~2.0.1", "strip-json-comments@2.0.1":
|
||||
"integrity" "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
|
||||
"resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
|
@ -10345,6 +10770,16 @@
|
|||
"tar" "^4.0.2"
|
||||
"xhr-request" "^1.0.1"
|
||||
|
||||
"table@^5.2.3":
|
||||
"integrity" "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug=="
|
||||
"resolved" "https://registry.npmjs.org/table/-/table-5.4.6.tgz"
|
||||
"version" "5.4.6"
|
||||
dependencies:
|
||||
"ajv" "^6.10.2"
|
||||
"lodash" "^4.17.14"
|
||||
"slice-ansi" "^2.1.0"
|
||||
"string-width" "^3.0.0"
|
||||
|
||||
"tapable@^0.2.7":
|
||||
"integrity" "sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A=="
|
||||
"resolved" "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz"
|
||||
|
@ -10445,6 +10880,11 @@
|
|||
"resolved" "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz"
|
||||
"version" "0.0.1"
|
||||
|
||||
"text-table@^0.2.0":
|
||||
"integrity" "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
|
||||
"resolved" "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
|
||||
"version" "0.2.0"
|
||||
|
||||
"through@^2.3.6":
|
||||
"integrity" "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||
"resolved" "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
|
||||
|
@ -12034,6 +12474,13 @@
|
|||
"resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
|
||||
"write@1.0.3":
|
||||
"integrity" "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig=="
|
||||
"resolved" "https://registry.npmjs.org/write/-/write-1.0.3.tgz"
|
||||
"version" "1.0.3"
|
||||
dependencies:
|
||||
"mkdirp" "^0.5.1"
|
||||
|
||||
"ws@^3.0.0":
|
||||
"integrity" "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA=="
|
||||
"resolved" "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz"
|
||||
|
|
Loading…
Reference in New Issue
Block a user