From 30eb39378fb32da235e1a294cd7007d74d43271e Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Tue, 24 Aug 2021 14:04:17 -0500 Subject: [PATCH 01/28] implement uniswap v3 staker --- .../connectors/uniswapStaker/events.sol | 34 +++ .../connectors/uniswapStaker/helpers.sol | 230 ++++++++++++++++ .../connectors/uniswapStaker/interface.sol | 183 +++++++++++++ .../mainnet/connectors/uniswapStaker/main.sol | 237 +++++++++++++++++ test/uniswapStake/uniswapStake.test.js | 245 ++++++++++++++++++ 5 files changed, 929 insertions(+) create mode 100644 contracts/mainnet/connectors/uniswapStaker/events.sol create mode 100644 contracts/mainnet/connectors/uniswapStaker/helpers.sol create mode 100644 contracts/mainnet/connectors/uniswapStaker/interface.sol create mode 100644 contracts/mainnet/connectors/uniswapStaker/main.sol create mode 100644 test/uniswapStake/uniswapStake.test.js diff --git a/contracts/mainnet/connectors/uniswapStaker/events.sol b/contracts/mainnet/connectors/uniswapStaker/events.sol new file mode 100644 index 00000000..8618e151 --- /dev/null +++ b/contracts/mainnet/connectors/uniswapStaker/events.sol @@ -0,0 +1,34 @@ +pragma solidity ^0.7.0; + +contract Events { + event LogDeposit( + uint256 indexed tokenId, + uint256 liquidity, + uint256 amountA, + uint256 amountB + ); + + event LogWithdraw( + uint256 indexed tokenId, + uint256 liquidity, + uint256 amountA, + uint256 amountB + ); + + event LogStake(uint256 tokenId, address refundee); + + event LogUnstake(uint256 tokenId, bytes32 incentiveId); + + event LogRewardClaimed( + address rewardToken, + address receiver, + uint256 amount + ); + + event LogIncentiveCreated( + uint256 tokenId, + uint256 startTime, + uint256 endTime, + uint256 reward + ); +} diff --git a/contracts/mainnet/connectors/uniswapStaker/helpers.sol b/contracts/mainnet/connectors/uniswapStaker/helpers.sol new file mode 100644 index 00000000..e7b8e7af --- /dev/null +++ b/contracts/mainnet/connectors/uniswapStaker/helpers.sol @@ -0,0 +1,230 @@ +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 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 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 + ) + ); + } + } + + 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}) + ); + } + } + + /** + * @dev Check if token address is etherAddr and convert it to weth + */ + function _checkETH( + address _token0, + address _token1, + uint256 _amount0, + uint256 _amount1 + ) internal { + bool isEth0 = _token0 == wethAddr; + bool isEth1 = _token1 == wethAddr; + convertEthToWeth(isEth0, TokenInterface(_token0), _amount0); + convertEthToWeth(isEth1, 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 + ) + { + _checkETH(_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); + } + + 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); + } +} diff --git a/contracts/mainnet/connectors/uniswapStaker/interface.sol b/contracts/mainnet/connectors/uniswapStaker/interface.sol new file mode 100644 index 00000000..5c537e43 --- /dev/null +++ b/contracts/mainnet/connectors/uniswapStaker/interface.sol @@ -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); +} diff --git a/contracts/mainnet/connectors/uniswapStaker/main.sol b/contracts/mainnet/connectors/uniswapStaker/main.sol new file mode 100644 index 00000000..da0db209 --- /dev/null +++ b/contracts/mainnet/connectors/uniswapStaker/main.sol @@ -0,0 +1,237 @@ +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 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 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) + { + 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 = "LogStake(uint256, address)"; + _eventParam = abi.encode(_tokenId, _refundee); + } + + /** + * @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, _key); + } + + /** + * @dev Claim rewards + * @notice Claim rewards + * @param _rewardToken _rewardToken address + * @param _to address to receive + * @param _amountRequested requested amount + */ + function claimRewards( + address _rewardToken, + address _to, + uint256 _amountRequested + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 rewards = _claimRewards( + IERC20Minimal(_rewardToken), + _to, + _amountRequested + ); + + _eventName = "LogRewardClaimed(address,address,uint256)"; + _eventParam = abi.encode(_rewardToken, _to, rewards); + } + + /** + * @dev Create incentive + * @notice Create incentive + * @param _rewardToken _rewardToken address + * @param _length incentive length + * @param _refundee refundee address + * @param _tokenId NFT LP token id + * @param _reward reward amount + */ + function createIncentive( + address _rewardToken, + uint256 _length, + address _refundee, + uint256 _tokenId, + uint256 _reward + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + address poolAddr = getPoolAddress(_tokenId); + + IUniswapV3Pool pool = IUniswapV3Pool(poolAddr); + uint256 _startTime = block.timestamp; + uint256 _endTime = _startTime + _length; + IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker + .IncentiveKey( + IERC20Minimal(_rewardToken), + pool, + _startTime, + _endTime, + _refundee + ); + staker.createIncentive(_key, _reward); + + _eventName = "LogIncentiveCreated(uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(_tokenId, _startTime, _endTime, _reward); + } +} + +contract ConnectV2UniswapV3Staker is UniswapResolver { + string public constant name = "UniswapStaker-v1"; +} diff --git a/test/uniswapStake/uniswapStake.test.js b/test/uniswapStake/uniswapStake.test.js new file mode 100644 index 00000000..0ca88ae0 --- /dev/null +++ b/test/uniswapStake/uniswapStake.test.js @@ -0,0 +1,245 @@ +const { expect } = require("chai"); +const hre = require("hardhat"); +const { waffle, ethers } = hre; +const { provider, deployContract } = waffle + +const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") +const buildDSAv2 = require("../../scripts/buildDSAv2") +const encodeSpells = require("../../scripts/encodeSpells.js") +const getMasterSigner = require("../../scripts/getMasterSigner") +const addLiquidity = require("../../scripts/addLiquidity"); + +const addresses = require("../../scripts/constant/addresses"); +const abis = require("../../scripts/constant/abis"); +const { abi: nftManagerAbi } = require("@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json") + +const connectV2UniswapStakerArtifacts = require("../../artifacts/contracts/mainnet/connectors/uniswapStaker/main.sol/ConnectV2UniswapV3Staker.json"); +const connectV2UniswapV3Artifacts = require("../../artifacts/contracts/mainnet/connectors/uniswapV3/main.sol/ConnectV2UniswapV3.json"); + +const FeeAmount = { + LOW: 500, + MEDIUM: 3000, + HIGH: 10000, +} + +const TICK_SPACINGS = { + 500: 10, + 3000: 60, + 10000: 200 +} + +const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" +const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + +let tokenIds = [] +const abiCoder = ethers.utils.defaultAbiCoder + +describe("UniswapV3", function () { + const connectorStaker = "UniswapStaker-v1" + const connectorUniswap = "UniswapV3-v1" + + let dsaWallet0 + let masterSigner; + let instaConnectorsV2; + let connector; + let startTime, endTime; + + const wallets = provider.getWallets() + const [wallet0, wallet1, wallet2, wallet3] = wallets + before(async () => { + masterSigner = await getMasterSigner(wallet3) + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + nftManager = await ethers.getContractAt(nftManagerAbi, "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"); + connector = await deployAndEnableConnector({ + connectorName: connectorStaker, + contractArtifact: connectV2UniswapStakerArtifacts, + signer: masterSigner, + connectors: instaConnectorsV2 + }) + console.log("Connector address", connector.address) + + uniswapConnector = await deployAndEnableConnector({ + connectorName: connectorUniswap, + contractArtifact: connectV2UniswapV3Artifacts, + signer: masterSigner, + connectors: instaConnectorsV2 + }); + }) + + it("Should have contracts deployed.", async function () { + expect(!!instaConnectorsV2.address).to.be.true; + expect(!!connector.address).to.be.true; + expect(!!masterSigner.address).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("dai", dsaWallet0.address, ethers.utils.parseEther("100000")); + await addLiquidity("usdt", dsaWallet0.address, ethers.utils.parseEther("100000")); + }); + }); + + describe("Main", function () { + const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiAmount = ethers.utils.parseEther("400") // 1 ETH + + it("Should mint successfully", async function () { + const getIds = ["0", "0"] + const setId = "0" + + const spells = [ + { + connector: connectorUniswap, + method: "mint", + args: [ + DAI_ADDR, + ethAddress, + FeeAmount.MEDIUM, + getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), + getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), + daiAmount, + ethAmount, + "500000000000000000", + getIds, + setId + ], + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + + let castEvent = new Promise((resolve, reject) => { + dsaWallet0.on('LogCast', (origin, sender, value, targetNames, targets, eventNames, eventParams, event) => { + const params = abiCoder.decode(["uint256", "uint256", "uint256", "uint256", "int24", "int24"], eventParams[0]); + tokenIds.push(params[0]); + event.removeListener(); + + resolve({ + eventNames, + }); + }); + + setTimeout(() => { + reject(new Error('timeout')); + }, 60000) + }); + + let event = await castEvent + }); + + it("Should create incentive successfully", async function () { + const spells = [ + { + connector: connectorStaker, + method: "createIncentive", + args: [ + ethAddress, + "1000", + dsaWallet0.address, + tokenIds[0], + ethers.utils.parseEther("0.01") + ], + }] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + + let castEvent = new Promise((resolve, reject) => { + dsaWallet0.on('LogCast', (origin, sender, value, targetNames, targets, eventNames, eventParams, event) => { + const params = abiCoder.decode(["uint256", "uint256", "uint256", "uint256"], eventParams[0]); + event.removeListener(); + + resolve({ start: params[1], end: params[2] }); + }); + + setTimeout(() => { + reject(new Error('timeout')); + }, 60000) + }); + + let event = await castEvent + startTime = event.start; + endTime = event.end; + }); + + it("Should stake successfully", async function () { + const spells = [ + { + connector: connectorStaker, + method: "stake", + args: [ + ethAddress, + startTime, + endTime, + dsaWallet0.address, + tokenIds[0] + ], + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + + it("Should claim rewards successfully", async function () { + const spells = [ + { + connector: connectorStaker, + method: "claimRewards", + args: [ + ethAddress, + dsaWallet0.address, + "1000", + ], + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + + it("Should unstake successfully", async function () { + const spells = [ + { + connector: connectorStaker, + method: "unstake", + args: [ + ethAddress, + startTime, + endTime, + dsaWallet0.address, + tokenIds[0] + ], + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + }) +}) + +const getMinTick = (tickSpacing) => Math.ceil(-887272 / tickSpacing) * tickSpacing +const getMaxTick = (tickSpacing) => Math.floor(887272 / tickSpacing) * tickSpacing From 509d2cf3bda90d6ee8a1a4769b5373d7a363ed6b Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Tue, 24 Aug 2021 14:56:55 -0500 Subject: [PATCH 02/28] refactor: fix deposit/withdraw function --- .../connectors/uniswapStaker/events.sol | 16 +-- .../connectors/uniswapStaker/helpers.sol | 107 ------------------ .../mainnet/connectors/uniswapStaker/main.sol | 99 +++++++--------- test/uniswapStake/uniswapStake.test.js | 7 ++ 4 files changed, 49 insertions(+), 180 deletions(-) diff --git a/contracts/mainnet/connectors/uniswapStaker/events.sol b/contracts/mainnet/connectors/uniswapStaker/events.sol index 8618e151..b5b2e8b0 100644 --- a/contracts/mainnet/connectors/uniswapStaker/events.sol +++ b/contracts/mainnet/connectors/uniswapStaker/events.sol @@ -1,19 +1,11 @@ pragma solidity ^0.7.0; contract Events { - event LogDeposit( - uint256 indexed tokenId, - uint256 liquidity, - uint256 amountA, - uint256 amountB - ); + event LogDeposit(uint256 tokenId); - event LogWithdraw( - uint256 indexed tokenId, - uint256 liquidity, - uint256 amountA, - uint256 amountB - ); + event LogWithdraw(uint256 indexed tokenId, address to); + + event LogDepositTransfer(uint256 indexed tokenId, address to); event LogStake(uint256 tokenId, address refundee); diff --git a/contracts/mainnet/connectors/uniswapStaker/helpers.sol b/contracts/mainnet/connectors/uniswapStaker/helpers.sol index e7b8e7af..71926302 100644 --- a/contracts/mainnet/connectors/uniswapStaker/helpers.sol +++ b/contracts/mainnet/connectors/uniswapStaker/helpers.sol @@ -99,113 +99,6 @@ abstract contract Helpers is DSMath, Basic { } } - /** - * @dev Check if token address is etherAddr and convert it to weth - */ - function _checkETH( - address _token0, - address _token1, - uint256 _amount0, - uint256 _amount1 - ) internal { - bool isEth0 = _token0 == wethAddr; - bool isEth1 = _token1 == wethAddr; - convertEthToWeth(isEth0, TokenInterface(_token0), _amount0); - convertEthToWeth(isEth1, 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 - ) - { - _checkETH(_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); - } - function _stake( uint256 _tokenId, IUniswapV3Staker.IncentiveKey memory _incentiveId diff --git a/contracts/mainnet/connectors/uniswapStaker/main.sol b/contracts/mainnet/connectors/uniswapStaker/main.sol index da0db209..72872a5e 100644 --- a/contracts/mainnet/connectors/uniswapStaker/main.sol +++ b/contracts/mainnet/connectors/uniswapStaker/main.sol @@ -13,78 +13,61 @@ import {Events} from "./events.sol"; abstract contract UniswapResolver is Helpers, Events { /** - * @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 + * @dev Deposit NFT token + * @notice Transfer deposited NFT token + * @param _tokenId NFT LP Token ID */ - function deposit( - uint256 tokenId, - uint256 amountA, - uint256 amountB, - uint256 slippage, - uint256[] calldata getIds, - uint256 setId - ) + function deposit(uint256 _tokenId) 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); + if (_tokenId == 0) _tokenId = _getLastNftId(address(this)); + nftManager.safeTransferFrom( + address(this), + address(staker), + _tokenId, + "" + ); - _eventName = "LogDeposit(uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(tokenId, _liquidity, _amtA, _amtB); + _eventName = "LogDeposit(uint256)"; + _eventParam = abi.encode(_tokenId); } /** - * @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 + * @dev Deposit Transfer + * @notice Transfer deposited NFT token + * @param _tokenId NFT LP Token ID + * @param _to address to transfer */ - function withdraw( - uint256 tokenId, - uint256 liquidity, - uint256 amountAMin, - uint256 amountBMin, - uint256 getId, - uint256[] calldata setIds - ) + function transferDeposit(uint256 _tokenId, address _to) external payable returns (string memory _eventName, bytes memory _eventParam) { - if (tokenId == 0) tokenId = _getLastNftId(address(this)); - uint128 _liquidity = uint128(getUint(getId, liquidity)); + if (_tokenId == 0) _tokenId = _getLastNftId(address(this)); + staker.transferDeposit(_tokenId, _to); - (uint256 _amtA, uint256 _amtB) = _decreaseLiquidity( - tokenId, - _liquidity, - amountAMin, - amountBMin - ); + _eventName = "LogDepositTransfer(uint256,address)"; + _eventParam = abi.encode(_tokenId, _to); + } - setUint(setIds[0], _amtA); - setUint(setIds[1], _amtB); + /** + * @dev Withdraw NFT LP token + * @notice Withdraw NFT LP token from staking pool + * @param _tokenId NFT LP Token ID + * @param _to address to transfer + */ + function withdraw(uint256 _tokenId, address _to) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + if (_tokenId == 0) _tokenId = _getLastNftId(address(this)); + staker.withdrawToken(_tokenId, _to, ""); - _eventName = "LogWithdraw(uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(tokenId, _liquidity, _amtA, _amtB); + _eventName = "LogWithdraw(uint256,address)"; + _eventParam = abi.encode(_tokenId, _to); } /** @@ -107,12 +90,6 @@ abstract contract UniswapResolver is Helpers, Events { payable returns (string memory _eventName, bytes memory _eventParam) { - nftManager.safeTransferFrom( - address(this), - address(staker), - _tokenId, - "" - ); address poolAddr = getPoolAddress(_tokenId); IUniswapV3Pool pool = IUniswapV3Pool(poolAddr); diff --git a/test/uniswapStake/uniswapStake.test.js b/test/uniswapStake/uniswapStake.test.js index 0ca88ae0..923b673a 100644 --- a/test/uniswapStake/uniswapStake.test.js +++ b/test/uniswapStake/uniswapStake.test.js @@ -186,6 +186,13 @@ describe("UniswapV3", function () { it("Should stake successfully", async function () { const spells = [ + { + connector: connectorStaker, + method: "deposit", + args: [ + tokenIds[0] + ], + }, { connector: connectorStaker, method: "stake", From f4b4cbfc5eca24b31842222577fc1f2951afe194 Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Wed, 25 Aug 2021 10:09:52 -0500 Subject: [PATCH 03/28] feat/implement ERC721 deposit/withdraw --- .../connectors/basic-ERC721/events.sol | 14 +++++ .../mainnet/connectors/basic-ERC721/main.sol | 58 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 contracts/mainnet/connectors/basic-ERC721/events.sol create mode 100644 contracts/mainnet/connectors/basic-ERC721/main.sol diff --git a/contracts/mainnet/connectors/basic-ERC721/events.sol b/contracts/mainnet/connectors/basic-ERC721/events.sol new file mode 100644 index 00000000..ebe059e5 --- /dev/null +++ b/contracts/mainnet/connectors/basic-ERC721/events.sol @@ -0,0 +1,14 @@ +pragma solidity ^0.7.0; + +contract Events { + event LogDepositERC721( + address indexed erc721, + address from, + uint256 tokenId + ); + event LogWithdrawERC721( + address indexed erc721, + uint256 tokenId, + address indexed to + ); +} diff --git a/contracts/mainnet/connectors/basic-ERC721/main.sol b/contracts/mainnet/connectors/basic-ERC721/main.sol new file mode 100644 index 00000000..98878ada --- /dev/null +++ b/contracts/mainnet/connectors/basic-ERC721/main.sol @@ -0,0 +1,58 @@ +pragma solidity ^0.7.0; + +/** + * @title Basic. + * @dev Deposit & Withdraw from DSA. + */ +import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; + +import {DSMath} from "../../common/math.sol"; +import {Basic} from "../../common/basic.sol"; +import {Events} from "./events.sol"; + +abstract contract BasicResolver is Events, DSMath, Basic { + /** + * @dev Deposit Assets To Smart Account. + * @notice Deposit a ERC721 token to DSA + * @param token The address of the token to deposit. + * @param tokenId The id of token to deposit. + */ + function depositERC721(address token, uint256 tokenId) + public + payable + returns (string memory _eventName, bytes memory _eventParam) + { + IERC721 tokenContract = IERC721(token); + tokenContract.safeTransferFrom(msg.sender, address(this), tokenId); + + _eventName = "LogDepositERC721(address,address,uint256)"; + _eventParam = abi.encode(token, msg.sender, tokenId); + } + + /** + * @dev Withdraw Assets To Smart Account. + * @notice Withdraw a ERC721 token from DSA + * @param token The address of the token to deposit. + * @param tokenId The id of token to deposit. + * @param to The address to receive the token upon withdrawal + */ + function withdrawERC721( + address token, + uint256 tokenId, + address payable to + ) + public + payable + returns (string memory _eventName, bytes memory _eventParam) + { + IERC721 tokenContract = IERC721(token); + tokenContract.safeTransferFrom(address(this), to, tokenId); + + _eventName = "LogWithdrawERC721(address,uint256,address)"; + _eventParam = abi.encode(token, tokenId, to); + } +} + +contract ConnectV2Basic is BasicResolver { + string public constant name = "BASIC-ERC721-A"; +} From cc6da0c75822b22293487b0f5620725b9e9445f0 Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Wed, 25 Aug 2021 11:18:31 -0500 Subject: [PATCH 04/28] refactor/implement getId/setId --- .../connectors/basic-ERC721/events.sol | 8 +++-- .../mainnet/connectors/basic-ERC721/main.sol | 32 +++++++++++++------ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/contracts/mainnet/connectors/basic-ERC721/events.sol b/contracts/mainnet/connectors/basic-ERC721/events.sol index ebe059e5..7b367145 100644 --- a/contracts/mainnet/connectors/basic-ERC721/events.sol +++ b/contracts/mainnet/connectors/basic-ERC721/events.sol @@ -4,11 +4,15 @@ contract Events { event LogDepositERC721( address indexed erc721, address from, - uint256 tokenId + uint256 tokenId, + uint256 getId, + uint256 setId ); event LogWithdrawERC721( address indexed erc721, uint256 tokenId, - address indexed to + address indexed to, + uint256 getId, + uint256 setId ); } diff --git a/contracts/mainnet/connectors/basic-ERC721/main.sol b/contracts/mainnet/connectors/basic-ERC721/main.sol index 98878ada..9e6f86b2 100644 --- a/contracts/mainnet/connectors/basic-ERC721/main.sol +++ b/contracts/mainnet/connectors/basic-ERC721/main.sol @@ -17,16 +17,25 @@ abstract contract BasicResolver is Events, DSMath, Basic { * @param token The address of the token to deposit. * @param tokenId The id of token to deposit. */ - function depositERC721(address token, uint256 tokenId) + function depositERC721( + address token, + uint256 tokenId, + uint256 getId, + uint256 setId + ) public payable returns (string memory _eventName, bytes memory _eventParam) { - IERC721 tokenContract = IERC721(token); - tokenContract.safeTransferFrom(msg.sender, address(this), tokenId); + uint256 _tokenId = getUint(getId, tokenId); - _eventName = "LogDepositERC721(address,address,uint256)"; - _eventParam = abi.encode(token, msg.sender, tokenId); + IERC721 tokenContract = IERC721(token); + tokenContract.safeTransferFrom(msg.sender, address(this), _tokenId); + + setUint(setId, _tokenId); + + _eventName = "LogDepositERC721(address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(token, msg.sender, _tokenId, getId, setId); } /** @@ -39,17 +48,22 @@ abstract contract BasicResolver is Events, DSMath, Basic { function withdrawERC721( address token, uint256 tokenId, - address payable to + address payable to, + uint256 getId, + uint256 setId ) public payable returns (string memory _eventName, bytes memory _eventParam) { + uint256 _tokenId = getUint(getId, tokenId); IERC721 tokenContract = IERC721(token); - tokenContract.safeTransferFrom(address(this), to, tokenId); + tokenContract.safeTransferFrom(address(this), to, _tokenId); - _eventName = "LogWithdrawERC721(address,uint256,address)"; - _eventParam = abi.encode(token, tokenId, to); + setUint(setId, _tokenId); + + _eventName = "LogWithdrawERC721(address,uint256,address,uint256,uint256)"; + _eventParam = abi.encode(token, _tokenId, to, getId, setId); } } From 7f8e13af0cf4e19133b119c80112caf40986187b Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Wed, 25 Aug 2021 12:48:08 -0500 Subject: [PATCH 05/28] refactor: fix small issue --- contracts/mainnet/connectors/basic-ERC721/main.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/mainnet/connectors/basic-ERC721/main.sol b/contracts/mainnet/connectors/basic-ERC721/main.sol index 9e6f86b2..e7680b51 100644 --- a/contracts/mainnet/connectors/basic-ERC721/main.sol +++ b/contracts/mainnet/connectors/basic-ERC721/main.sol @@ -16,6 +16,8 @@ abstract contract BasicResolver is Events, DSMath, Basic { * @notice Deposit a ERC721 token to DSA * @param token The address of the token to deposit. * @param tokenId The id of token to deposit. + * @param getId ID to retrieve tokenId. + * @param setId ID stores the tokenId. */ function depositERC721( address token, @@ -44,6 +46,8 @@ abstract contract BasicResolver is Events, DSMath, Basic { * @param token The address of the token to deposit. * @param tokenId The id of token to deposit. * @param to The address to receive the token upon withdrawal + * @param getId ID to retrieve tokenId. + * @param setId ID stores the tokenId. */ function withdrawERC721( address token, From 59870142d10817ac2b11656b98f77b6b3070b566 Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Wed, 25 Aug 2021 12:54:44 -0500 Subject: [PATCH 06/28] refactor: fix small issues --- contracts/mainnet/connectors/uniswapStaker/main.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contracts/mainnet/connectors/uniswapStaker/main.sol b/contracts/mainnet/connectors/uniswapStaker/main.sol index 72872a5e..b33e0734 100644 --- a/contracts/mainnet/connectors/uniswapStaker/main.sol +++ b/contracts/mainnet/connectors/uniswapStaker/main.sol @@ -90,6 +90,7 @@ abstract contract UniswapResolver is Helpers, Events { payable returns (string memory _eventName, bytes memory _eventParam) { + if (_tokenId == 0) _tokenId = _getLastNftId(address(this)); address poolAddr = getPoolAddress(_tokenId); IUniswapV3Pool pool = IUniswapV3Pool(poolAddr); @@ -127,6 +128,7 @@ abstract contract UniswapResolver is Helpers, Events { payable returns (string memory _eventName, bytes memory _eventParam) { + if (_tokenId == 0) _tokenId = _getLastNftId(address(this)); address poolAddr = getPoolAddress(_tokenId); IUniswapV3Pool pool = IUniswapV3Pool(poolAddr); @@ -189,6 +191,7 @@ abstract contract UniswapResolver is Helpers, Events { payable returns (string memory _eventName, bytes memory _eventParam) { + if (_tokenId == 0) _tokenId = _getLastNftId(address(this)); address poolAddr = getPoolAddress(_tokenId); IUniswapV3Pool pool = IUniswapV3Pool(poolAddr); @@ -210,5 +213,5 @@ abstract contract UniswapResolver is Helpers, Events { } contract ConnectV2UniswapV3Staker is UniswapResolver { - string public constant name = "UniswapStaker-v1"; + string public constant name = "Uniswap-V3-Staker-v1"; } From c26e01a72b755ad3fee52624122281ca1c2faa9b Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Wed, 25 Aug 2021 16:26:43 -0500 Subject: [PATCH 07/28] refactor: improve test case --- test/uniswapStake/uniswapStake.test.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/uniswapStake/uniswapStake.test.js b/test/uniswapStake/uniswapStake.test.js index 923b673a..be684b6a 100644 --- a/test/uniswapStake/uniswapStake.test.js +++ b/test/uniswapStake/uniswapStake.test.js @@ -147,6 +147,9 @@ describe("UniswapV3", function () { }); let event = await castEvent + + let balance = await nftManager.connect(wallet0).balanceOf(dsaWallet0.address) + console.log("Balane", balance) }); it("Should create incentive successfully", async function () { @@ -208,6 +211,9 @@ describe("UniswapV3", function () { const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) let receipt = await tx.wait() + + let balance = await nftManager.connect(wallet0).balanceOf(dsaWallet0.address) + console.log("Balane", balance) }); it("Should claim rewards successfully", async function () { @@ -239,11 +245,22 @@ describe("UniswapV3", function () { dsaWallet0.address, tokenIds[0] ], + }, + { + connector: connectorStaker, + method: "withdraw", + args: [ + tokenIds[0], + dsaWallet0.address, + ], } ] const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) let receipt = await tx.wait() + + let balance = await nftManager.connect(wallet0).balanceOf(dsaWallet0.address) + console.log("Balane", balance) }); }) }) From cff2edda79ecacf41764e1e023de77abbb5d8af9 Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Sat, 28 Aug 2021 14:35:36 -0500 Subject: [PATCH 08/28] refactor: fix minor issue --- contracts/mainnet/connectors/uniswapStaker/main.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mainnet/connectors/uniswapStaker/main.sol b/contracts/mainnet/connectors/uniswapStaker/main.sol index b33e0734..18ca0916 100644 --- a/contracts/mainnet/connectors/uniswapStaker/main.sol +++ b/contracts/mainnet/connectors/uniswapStaker/main.sol @@ -104,7 +104,7 @@ abstract contract UniswapResolver is Helpers, Events { ); _stake(_tokenId, _key); - _eventName = "LogStake(uint256, address)"; + _eventName = "LogStake(uint256,address)"; _eventParam = abi.encode(_tokenId, _refundee); } From cce38fec6d8bd054ea11f1415d57f6d4316b4338 Mon Sep 17 00:00:00 2001 From: Thrilok kumar <thrilok2000@gmail.com> Date: Sun, 29 Aug 2021 23:03:05 +0530 Subject: [PATCH 09/28] Added new connectors Connector Name: "B-COMPOUND-A" Connector Address: 0xa3EeFDc2de9DFA59968bEcff3E15b53E6162460f Connector Name: "B-MAKERDAO-A" Connector Address: 0xB0A1f10FeEfECf25064CE7cdF0a65042F7dE7bF0 Connector Name: "B-LIQUITY-A" Connector Address: 0x19574E5Dfb40bbD63A4F3bdcF27ed662b329b2ff Connector Name: "UNISWAP-V3-A" Connector Address: 0x25B0c76dE86C3457b9B8b9ee3775F5a7b8D4c475 --- docs/connectors.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/connectors.json b/docs/connectors.json index 28c96123..75db30dc 100644 --- a/docs/connectors.json +++ b/docs/connectors.json @@ -25,7 +25,11 @@ "REFINANCE-A": "0x6f22931423e8ffC8d51f6E5aF73118fC64b27856", "INST-A": "0x52C2C4a0db049255fF345EB9D3Fb1f555b7a924A", "REFLEXER-A": "0xaC6dc28a6251F49Bbe5755E630107Dccde9ae2C8", - "LIQUITY-A": "0x3643bA40B8e2bd8F77233BDB6abe38c218f31bFe" + "LIQUITY-A": "0x3643bA40B8e2bd8F77233BDB6abe38c218f31bFe", + "UNISWAP-V3-A": "0x25B0c76dE86C3457b9B8b9ee3775F5a7b8D4c475", + "B-COMPOUND-A": "0xa3EeFDc2de9DFA59968bEcff3E15b53E6162460f", + "B-MAKERDAO-A": "0xB0A1f10FeEfECf25064CE7cdF0a65042F7dE7bF0", + "B-LIQUITY-A": "0x19574E5Dfb40bbD63A4F3bdcF27ed662b329b2ff" }, "137" : { "1INCH-A": "0xC0d9210496afE9763F5d8cEb8deFfBa817232A9e", From 73ed99993b6cd3f86dd4b05ed10db0688336628a Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Mon, 30 Aug 2021 03:23:54 -0500 Subject: [PATCH 10/28] reactor: fix minor issue --- contracts/mainnet/connectors/basic-ERC721/main.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/mainnet/connectors/basic-ERC721/main.sol b/contracts/mainnet/connectors/basic-ERC721/main.sol index e7680b51..849aebba 100644 --- a/contracts/mainnet/connectors/basic-ERC721/main.sol +++ b/contracts/mainnet/connectors/basic-ERC721/main.sol @@ -14,8 +14,8 @@ abstract contract BasicResolver is Events, DSMath, Basic { /** * @dev Deposit Assets To Smart Account. * @notice Deposit a ERC721 token to DSA - * @param token The address of the token to deposit. - * @param tokenId The id of token to deposit. + * @param token Address of token. + * @param tokenId ID of token. * @param getId ID to retrieve tokenId. * @param setId ID stores the tokenId. */ @@ -43,8 +43,8 @@ abstract contract BasicResolver is Events, DSMath, Basic { /** * @dev Withdraw Assets To Smart Account. * @notice Withdraw a ERC721 token from DSA - * @param token The address of the token to deposit. - * @param tokenId The id of token to deposit. + * @param token Address of the token. + * @param tokenId ID of token. * @param to The address to receive the token upon withdrawal * @param getId ID to retrieve tokenId. * @param setId ID stores the tokenId. @@ -71,6 +71,6 @@ abstract contract BasicResolver is Events, DSMath, Basic { } } -contract ConnectV2Basic is BasicResolver { +contract ConnectV2BasicERC721 is BasicResolver { string public constant name = "BASIC-ERC721-A"; } From 6f7f14c235bb4b27e7eb51d0da8bc34bbe0f94b9 Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Mon, 30 Aug 2021 03:25:28 -0500 Subject: [PATCH 11/28] refactor: fix version string --- contracts/mainnet/connectors/basic-ERC721/main.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mainnet/connectors/basic-ERC721/main.sol b/contracts/mainnet/connectors/basic-ERC721/main.sol index 849aebba..a6962b47 100644 --- a/contracts/mainnet/connectors/basic-ERC721/main.sol +++ b/contracts/mainnet/connectors/basic-ERC721/main.sol @@ -72,5 +72,5 @@ abstract contract BasicResolver is Events, DSMath, Basic { } contract ConnectV2BasicERC721 is BasicResolver { - string public constant name = "BASIC-ERC721-A"; + string public constant name = "BASIC-ERC721-v1.0"; } From 7905b01a85d43d08bec88139135328e1553f513b Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Mon, 30 Aug 2021 10:33:08 -0500 Subject: [PATCH 12/28] feat: support ERC1155 deposit/withdraw --- .../connectors/basic-ERC1155/events.sol | 20 ++++ .../mainnet/connectors/basic-ERC1155/main.sol | 93 +++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 contracts/mainnet/connectors/basic-ERC1155/events.sol create mode 100644 contracts/mainnet/connectors/basic-ERC1155/main.sol diff --git a/contracts/mainnet/connectors/basic-ERC1155/events.sol b/contracts/mainnet/connectors/basic-ERC1155/events.sol new file mode 100644 index 00000000..2ef9f79a --- /dev/null +++ b/contracts/mainnet/connectors/basic-ERC1155/events.sol @@ -0,0 +1,20 @@ +pragma solidity ^0.7.0; + +contract Events { + event LogDepositERC1155( + address indexed erc1155, + address from, + uint256 tokenId, + uint256 amount, + uint256 getId, + uint256 setId + ); + event LogWithdrawERC1155( + address indexed erc1155, + uint256 tokenId, + address indexed to, + uint256 amount, + uint256 getId, + uint256 setId + ); +} diff --git a/contracts/mainnet/connectors/basic-ERC1155/main.sol b/contracts/mainnet/connectors/basic-ERC1155/main.sol new file mode 100644 index 00000000..c71b7805 --- /dev/null +++ b/contracts/mainnet/connectors/basic-ERC1155/main.sol @@ -0,0 +1,93 @@ +pragma solidity ^0.7.0; + +/** + * @title Basic. + * @dev Deposit & Withdraw from DSA. + */ +import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; + +import {DSMath} from "../../common/math.sol"; +import {Basic} from "../../common/basic.sol"; +import {Events} from "./events.sol"; + +abstract contract BasicResolver is Events, DSMath, Basic { + /** + * @dev Deposit Assets To Smart Account. + * @notice Deposit a ERC721 token to DSA + * @param token Address of token. + * @param tokenId ID of token. + * @param amount Amount to deposit. + * @param getId ID to retrieve amount. + * @param setId ID stores the amount. + */ + function depositERC1155( + address token, + uint256 tokenId, + uint256 amount, + uint256 getId, + uint256 setId + ) + public + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amount = getUint(getId, tokenId); + + IERC1155 tokenContract = IERC1155(token); + tokenContract.safeTransferFrom( + msg.sender, + address(this), + tokenId, + _amount, + "" + ); + + setUint(setId, _amount); + + _eventName = "LogDepositERC1155(address,address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode( + token, + msg.sender, + tokenId, + _amount, + getId, + setId + ); + } + + /** + * @dev Withdraw Assets To Smart Account. + * @notice Withdraw a ERC721 token from DSA + * @param token Address of the token. + * @param tokenId ID of token. + * @param to The address to receive the token upon withdrawal + * @param amount Amount to withdraw. + * @param getId ID to retrieve amount. + * @param setId ID stores the amount. + */ + function withdrawERC721( + address token, + uint256 tokenId, + address payable to, + uint256 amount, + uint256 getId, + uint256 setId + ) + public + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amount = getUint(getId, amount); + IERC1155 tokenContract = IERC1155(token); + tokenContract.safeTransferFrom(address(this), to, tokenId, _amount, ""); + + setUint(setId, _amount); + + _eventName = "LogWithdrawERC1155(address,uint256,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(token, tokenId, to, _amount, getId, setId); + } +} + +contract ConnectV2BasicERC1155 is BasicResolver { + string public constant name = "BASIC-ERC1155-v1.0"; +} From 7ad2a53364049f139223816633dc34dbe6ae465e Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Mon, 30 Aug 2021 10:34:52 -0500 Subject: [PATCH 13/28] refactor: fix minor issue --- contracts/mainnet/connectors/basic-ERC1155/main.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mainnet/connectors/basic-ERC1155/main.sol b/contracts/mainnet/connectors/basic-ERC1155/main.sol index c71b7805..b6ab4af8 100644 --- a/contracts/mainnet/connectors/basic-ERC1155/main.sol +++ b/contracts/mainnet/connectors/basic-ERC1155/main.sol @@ -65,7 +65,7 @@ abstract contract BasicResolver is Events, DSMath, Basic { * @param getId ID to retrieve amount. * @param setId ID stores the amount. */ - function withdrawERC721( + function withdrawERC1155( address token, uint256 tokenId, address payable to, From 453848c7f516c90f5a12fb0b8e66c3b7f9557d7a Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Tue, 31 Aug 2021 09:41:31 -0500 Subject: [PATCH 14/28] feat: ERC721 test case --- test/basic-ERC721/nftTransfer.test.js | 107 ++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 test/basic-ERC721/nftTransfer.test.js diff --git a/test/basic-ERC721/nftTransfer.test.js b/test/basic-ERC721/nftTransfer.test.js new file mode 100644 index 00000000..9735d51e --- /dev/null +++ b/test/basic-ERC721/nftTransfer.test.js @@ -0,0 +1,107 @@ +const { expect } = require("chai"); +const hre = require("hardhat"); +const { web3, deployments, waffle, ethers } = hre; +const { provider, deployContract } = waffle + +const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") +const buildDSAv2 = require("../../scripts/buildDSAv2") +const encodeSpells = require("../../scripts/encodeSpells.js") +const getMasterSigner = require("../../scripts/getMasterSigner") + +const addresses = require("../../scripts/constant/addresses"); +const abis = require("../../scripts/constant/abis"); +const constants = require("../../scripts/constant/constant"); +const tokens = require("../../scripts/constant/tokens"); + +const connectV2BasicERC721Artifacts = require("../../artifacts/contracts/mainnet/connectors/basic-ERC721/main.sol/ConnectV2BasicERC721.json") +const erc721Artifacts = require("../../artifacts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.json") + +const TOKEN_CONTRACT_ADDR = "0x4d695c615a7aacf2d7b9c481b66045bb2457dfde"; +const TOKEN_OWNER_ADDR = "0x8c6b10d42ff08e56133fca0dac75e1931b1fcc23"; +const TOKEN_ID = "38"; + +describe("BASIC-ERC721", function () { + const connectorName = "BASIC-ERC721-A" + + let dsaWallet0 + let masterSigner; + let instaConnectorsV2; + let connector; + let nftContract; + let tokenOwner; + + + const wallets = provider.getWallets() + const [wallet0, wallet1, wallet2, wallet3] = wallets + before(async () => { + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [TOKEN_OWNER_ADDR], + }); + + await network.provider.send("hardhat_setBalance", [ + TOKEN_OWNER_ADDR, + "0x1000000000000000", + ]); + + // get tokenOwner + tokenOwner = await ethers.getSigner( + TOKEN_OWNER_ADDR + ); + nftContract = await ethers.getContractAt(erc721Artifacts.abi, TOKEN_CONTRACT_ADDR) + masterSigner = await getMasterSigner(wallet3) + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: connectV2BasicERC721Artifacts, + 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.address).to.be.true; + }); + + describe("DSA wallet setup", function () { + it("Should build DSA v2", async function () { + dsaWallet0 = await buildDSAv2(tokenOwner.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 deposit successfully", async () => { + console.log("DSA wallet address", dsaWallet0.address) + await nftContract.connect(tokenOwner).setApprovalForAll(dsaWallet0.address, true); + const spells = [ + { + connector: connectorName, + method: "depositERC721", + args: [ + TOKEN_CONTRACT_ADDR, + TOKEN_ID, + "0", + "0" + ] + } + ]; + + const tx = await dsaWallet0 + .connect(tokenOwner) + .cast(...encodeSpells(spells), tokenOwner.address); + const receipt = await tx.wait(); + }); + }) +}) From d39dc1d5091b49b4f14bf2f620a309d64665bff5 Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Tue, 31 Aug 2021 11:17:03 -0500 Subject: [PATCH 15/28] feat: implement ERC721/1155 testcase --- contracts/test/implementation_default.sol | 114 ++++++++++ contracts/test/variables.sol | 6 + .../abi/core/InstaImplementations.json | 206 ++++++++++++++++++ test/basic-ERC1155/ERC1155-transfer.js | 127 +++++++++++ ...nftTransfer.test.js => ERC721-transfer.js} | 19 ++ 5 files changed, 472 insertions(+) create mode 100644 contracts/test/implementation_default.sol create mode 100644 contracts/test/variables.sol create mode 100644 scripts/constant/abi/core/InstaImplementations.json create mode 100644 test/basic-ERC1155/ERC1155-transfer.js rename test/basic-ERC721/{nftTransfer.test.js => ERC721-transfer.js} (79%) diff --git a/contracts/test/implementation_default.sol b/contracts/test/implementation_default.sol new file mode 100644 index 00000000..e897433b --- /dev/null +++ b/contracts/test/implementation_default.sol @@ -0,0 +1,114 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +import { Variables } from "./variables.sol"; + +interface IndexInterface { + function list() external view returns (address); +} + +interface ListInterface { + function addAuth(address user) external; + + function removeAuth(address user) external; +} + +contract Constants is Variables { + uint256 public constant implementationVersion = 1; + // InstaIndex Address. + address public immutable instaIndex; + // The Account Module Version. + uint256 public constant version = 2; + + constructor(address _instaIndex) { + instaIndex = _instaIndex; + } +} + +contract Record is Constants { + constructor(address _instaIndex) Constants(_instaIndex) {} + + event LogEnableUser(address indexed user); + event LogDisableUser(address indexed user); + + /** + * @dev Check for Auth if enabled. + * @param user address/user/owner. + */ + function isAuth(address user) public view returns (bool) { + return _auth[user]; + } + + /** + * @dev Enable New User. + * @param user Owner address + */ + function enable(address user) public { + require( + msg.sender == address(this) || msg.sender == instaIndex, + "not-self-index" + ); + require(user != address(0), "not-valid"); + require(!_auth[user], "already-enabled"); + _auth[user] = true; + ListInterface(IndexInterface(instaIndex).list()).addAuth(user); + emit LogEnableUser(user); + } + + /** + * @dev Disable User. + * @param user Owner address + */ + function disable(address user) public { + require(msg.sender == address(this), "not-self"); + require(user != address(0), "not-valid"); + require(_auth[user], "already-disabled"); + delete _auth[user]; + ListInterface(IndexInterface(instaIndex).list()).removeAuth(user); + emit LogDisableUser(user); + } + + /** + * @dev ERC721 token receiver + */ + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external returns (bytes4) { + return 0x150b7a02; // bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) + } + + /** + * @dev ERC1155 token receiver + */ + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes memory + ) external returns (bytes4) { + return 0xf23a6e61; // bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)")) + } + + /** + * @dev ERC1155 token receiver + */ + function onERC1155BatchReceived( + address, + address, + uint256[] calldata, + uint256[] calldata, + bytes calldata + ) external returns (bytes4) { + return 0xbc197c81; // bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)")) + } +} + +contract InstaDefaultImplementation is Record { + constructor(address _instaIndex) public Record(_instaIndex) {} + + receive() external payable {} +} diff --git a/contracts/test/variables.sol b/contracts/test/variables.sol new file mode 100644 index 00000000..86853496 --- /dev/null +++ b/contracts/test/variables.sol @@ -0,0 +1,6 @@ +pragma solidity ^0.7.0; + +contract Variables { + // Auth Module(Address of Auth => bool). + mapping (address => bool) internal _auth; +} \ No newline at end of file diff --git a/scripts/constant/abi/core/InstaImplementations.json b/scripts/constant/abi/core/InstaImplementations.json new file mode 100644 index 00000000..c1bae964 --- /dev/null +++ b/scripts/constant/abi/core/InstaImplementations.json @@ -0,0 +1,206 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "InstaImplementations", + "sourceName": "contracts/v2/registry/implementations.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_instaIndex", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4[]", + "name": "sigs", + "type": "bytes4[]" + } + ], + "name": "LogAddImplementation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4[]", + "name": "sigs", + "type": "bytes4[]" + } + ], + "name": "LogRemoveImplementation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "LogSetDefaultImplementation", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "_sigs", + "type": "bytes4[]" + } + ], + "name": "addImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_sig", + "type": "bytes4" + } + ], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_impl", + "type": "address" + } + ], + "name": "getImplementationSigs", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_sig", + "type": "bytes4" + } + ], + "name": "getSigImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "instaIndex", + "outputs": [ + { + "internalType": "contract IndexInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "removeImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_defaultImplementation", + "type": "address" + } + ], + "name": "setDefaultImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60a060405234801561001057600080fd5b506040516116383803806116388339818101604052602081101561003357600080fd5b8101908080519060200190929190505050808073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050505060805160601c61158e6100aa6000398061039f528061085b5280610c5d5280610dfb525061158e6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063b39c45931161005b578063b39c4593146101e2578063dc9cc64514610216578063ef7e5c7b1461028d578063f0c01b421461030457610088565b806322175a321461008d5780637c16ffc4146100d157806389396dc814610115578063a41098bf146101ae575b600080fd5b6100cf600480360360208110156100a357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061039d565b005b610113600480360360208110156100e757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610859565b005b6101576004803603602081101561012b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b82565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561019a57808201518184015260208101905061017f565b505050509050019250505060405180910390f35b6101b6610c5b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ea610c7f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102616004803603602081101561022c57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610ca3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102d8600480360360208110156102a357600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610d7e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61039b6004803603604081101561031a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561035757600080fd5b82018360208201111561036957600080fd5b8035906020019184602083028401116401000000008311171561038b57600080fd5b9091929391929390505050610df9565b005b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ee97f7f36040518163ffffffff1660e01b815260040160206040518083038186803b15801561040357600080fd5b505afa158015610417573d6000803e3d6000fd5b505050506040513d602081101561042d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496d706c656d656e746174696f6e733a206e6f742d6d6173746572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610564576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806114cd602b913960400191505060405180910390fd5b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490501415610600576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806114f8602b913960400191505060405180910390fd5b6060600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156106cd57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161067a5790505b5050505050905060005b815181101561077a5760008282815181106106ee57fe5b6020026020010151905060016000827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555080806001019150506106d7565b50600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006107c69190611305565b8173ffffffffffffffffffffffffffffffffffffffff167fb7d759e6cdda23e8a1749bce345fc77355b8a22eeaf92c6e4e7257d959c162c7826040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610842578082015181840152602081019050610827565b505050509050019250505060405180910390a25050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ee97f7f36040518163ffffffff1660e01b815260040160206040518083038186803b1580156108bf57600080fd5b505afa1580156108d3573d6000803e3d6000fd5b505050506040513d60208110156108e957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461099a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496d706c656d656e746174696f6e733a206e6f742d6d6173746572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260398152602001806114656039913960400191505060405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ac5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806115236036913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f3b337225b8d68d037e0c721876335a3832bd08162c943fe5f88e8d428597ca8f60405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610c4f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019060040190602082600301049283019260010382029150808411610bfc5790505b50505050509050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d545780610d76565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff165b915050919050565b600060016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ee97f7f36040518163ffffffff1660e01b815260040160206040518083038186803b158015610e5f57600080fd5b505afa158015610e73573d6000803e3d6000fd5b505050506040513d6020811015610e8957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496d706c656d656e746174696f6e733a206e6f742d6d6173746572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806114cd602b913960400191505060405180910390fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490501461105b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f81526020018061149e602f913960400191505060405180910390fd5b60005b8282905081101561123357600083838381811061107757fe5b905060200201357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169050600073ffffffffffffffffffffffffffffffffffffffff1660016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611195576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806114426023913960400191505060405180910390fd5b8460016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050808060010191505061105e565b508181600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020919061128292919061132d565b508273ffffffffffffffffffffffffffffffffffffffff167ff9c512a86be00aaec236065d0a439f064133f367de889c782448c3578a3f30c5838360405180806020018281038252848482818152602001925060200280828437600081840152601f19601f820116905080830192505050935050505060405180910390a2505050565b50805460008255600701600890049060005260206000209081019061132a91906113f9565b50565b828054828255906000526020600020906007016008900481019282156113e85791602002820160005b838211156113b65783357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191683826101000a81548163ffffffff021916908360e01c02179055509260200192600401602081600301049283019260010302611356565b80156113e65782816101000a81549063ffffffff02191690556004016020816003010492830192600103026113b6565b505b5090506113f59190611416565b5090565b5b808211156114125760008160009055506001016113fa565b5090565b5b8082111561143d57600081816101000a81549063ffffffff021916905550600101611417565b509056fe496d706c656d656e746174696f6e733a205f73696720616c7265616479206164646564496d706c656d656e746174696f6e733a205f64656661756c74496d706c656d656e746174696f6e2061646472657373206e6f742076616c6964496d706c656d656e746174696f6e733a205f696d706c656d656e746174696f6e20616c72656164792061646465642e496d706c656d656e746174696f6e733a205f696d706c656d656e746174696f6e206e6f742076616c69642e496d706c656d656e746174696f6e733a205f696d706c656d656e746174696f6e206e6f7420666f756e642e496d706c656d656e746174696f6e733a205f64656661756c74496d706c656d656e746174696f6e2063616e6e6f742062652073616d65a2646970667358221220d42dcb568934728d15f318f76a6028fe848a484b097ea24581f45425fcde152864736f6c63430007000033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063b39c45931161005b578063b39c4593146101e2578063dc9cc64514610216578063ef7e5c7b1461028d578063f0c01b421461030457610088565b806322175a321461008d5780637c16ffc4146100d157806389396dc814610115578063a41098bf146101ae575b600080fd5b6100cf600480360360208110156100a357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061039d565b005b610113600480360360208110156100e757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610859565b005b6101576004803603602081101561012b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b82565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561019a57808201518184015260208101905061017f565b505050509050019250505060405180910390f35b6101b6610c5b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ea610c7f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102616004803603602081101561022c57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610ca3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102d8600480360360208110156102a357600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610d7e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61039b6004803603604081101561031a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561035757600080fd5b82018360208201111561036957600080fd5b8035906020019184602083028401116401000000008311171561038b57600080fd5b9091929391929390505050610df9565b005b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ee97f7f36040518163ffffffff1660e01b815260040160206040518083038186803b15801561040357600080fd5b505afa158015610417573d6000803e3d6000fd5b505050506040513d602081101561042d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496d706c656d656e746174696f6e733a206e6f742d6d6173746572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610564576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806114cd602b913960400191505060405180910390fd5b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490501415610600576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806114f8602b913960400191505060405180910390fd5b6060600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156106cd57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161067a5790505b5050505050905060005b815181101561077a5760008282815181106106ee57fe5b6020026020010151905060016000827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555080806001019150506106d7565b50600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006107c69190611305565b8173ffffffffffffffffffffffffffffffffffffffff167fb7d759e6cdda23e8a1749bce345fc77355b8a22eeaf92c6e4e7257d959c162c7826040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610842578082015181840152602081019050610827565b505050509050019250505060405180910390a25050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ee97f7f36040518163ffffffff1660e01b815260040160206040518083038186803b1580156108bf57600080fd5b505afa1580156108d3573d6000803e3d6000fd5b505050506040513d60208110156108e957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461099a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496d706c656d656e746174696f6e733a206e6f742d6d6173746572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260398152602001806114656039913960400191505060405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ac5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806115236036913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f3b337225b8d68d037e0c721876335a3832bd08162c943fe5f88e8d428597ca8f60405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610c4f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019060040190602082600301049283019260010382029150808411610bfc5790505b50505050509050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d545780610d76565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff165b915050919050565b600060016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ee97f7f36040518163ffffffff1660e01b815260040160206040518083038186803b158015610e5f57600080fd5b505afa158015610e73573d6000803e3d6000fd5b505050506040513d6020811015610e8957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496d706c656d656e746174696f6e733a206e6f742d6d6173746572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806114cd602b913960400191505060405180910390fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490501461105b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f81526020018061149e602f913960400191505060405180910390fd5b60005b8282905081101561123357600083838381811061107757fe5b905060200201357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169050600073ffffffffffffffffffffffffffffffffffffffff1660016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611195576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806114426023913960400191505060405180910390fd5b8460016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050808060010191505061105e565b508181600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020919061128292919061132d565b508273ffffffffffffffffffffffffffffffffffffffff167ff9c512a86be00aaec236065d0a439f064133f367de889c782448c3578a3f30c5838360405180806020018281038252848482818152602001925060200280828437600081840152601f19601f820116905080830192505050935050505060405180910390a2505050565b50805460008255600701600890049060005260206000209081019061132a91906113f9565b50565b828054828255906000526020600020906007016008900481019282156113e85791602002820160005b838211156113b65783357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191683826101000a81548163ffffffff021916908360e01c02179055509260200192600401602081600301049283019260010302611356565b80156113e65782816101000a81549063ffffffff02191690556004016020816003010492830192600103026113b6565b505b5090506113f59190611416565b5090565b5b808211156114125760008160009055506001016113fa565b5090565b5b8082111561143d57600081816101000a81549063ffffffff021916905550600101611417565b509056fe496d706c656d656e746174696f6e733a205f73696720616c7265616479206164646564496d706c656d656e746174696f6e733a205f64656661756c74496d706c656d656e746174696f6e2061646472657373206e6f742076616c6964496d706c656d656e746174696f6e733a205f696d706c656d656e746174696f6e20616c72656164792061646465642e496d706c656d656e746174696f6e733a205f696d706c656d656e746174696f6e206e6f742076616c69642e496d706c656d656e746174696f6e733a205f696d706c656d656e746174696f6e206e6f7420666f756e642e496d706c656d656e746174696f6e733a205f64656661756c74496d706c656d656e746174696f6e2063616e6e6f742062652073616d65a2646970667358221220d42dcb568934728d15f318f76a6028fe848a484b097ea24581f45425fcde152864736f6c63430007000033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/test/basic-ERC1155/ERC1155-transfer.js b/test/basic-ERC1155/ERC1155-transfer.js new file mode 100644 index 00000000..cd2f2b12 --- /dev/null +++ b/test/basic-ERC1155/ERC1155-transfer.js @@ -0,0 +1,127 @@ +const { expect } = require("chai"); +const hre = require("hardhat"); +const { web3, deployments, waffle, ethers } = hre; +const { provider, deployContract } = waffle +const {abi: implementationsABI} = require("../../scripts/constant/abi/core/InstaImplementations.json") + +const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") +const buildDSAv2 = require("../../scripts/buildDSAv2") +const encodeSpells = require("../../scripts/encodeSpells.js") +const getMasterSigner = require("../../scripts/getMasterSigner") + +const addresses = require("../../scripts/constant/addresses"); +const abis = require("../../scripts/constant/abis"); +const constants = require("../../scripts/constant/constant"); +const tokens = require("../../scripts/constant/tokens"); + +const connectV2BasicERC1155Artifacts = require("../../artifacts/contracts/mainnet/connectors/basic-ERC1155/main.sol/ConnectV2BasicERC1155.json") +const erc1155Artifacts = require("../../artifacts/@openzeppelin/contracts/token/ERC1155/IERC1155.sol/IERC1155.json") + +const TOKEN_CONTRACT_ADDR = "0x1ca3262009b21F944e6b92a2a88D039D06F1acFa"; +const TOKEN_OWNER_ADDR = "0x1ca3262009b21F944e6b92a2a88D039D06F1acFa"; +const TOKEN_ID = "1"; + +const implementationsMappingAddr = "0xCBA828153d3a85b30B5b912e1f2daCac5816aE9D" + +describe("BASIC-ERC1155", function () { + const connectorName = "BASIC-ERC1155-A" + + let dsaWallet0 + let masterSigner; + let instaConnectorsV2; + let connector; + let nftContract; + let tokenOwner; + let instaImplementationsMapping; + + + const wallets = provider.getWallets() + const [wallet0, wallet1, wallet2, wallet3] = wallets + before(async () => { + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [TOKEN_OWNER_ADDR], + }); + + await network.provider.send("hardhat_setBalance", [ + TOKEN_OWNER_ADDR, + "0x1000000000000000", + ]); + + // get tokenOwner + tokenOwner = await ethers.getSigner( + TOKEN_OWNER_ADDR + ); + nftContract = await ethers.getContractAt(erc1155Artifacts.abi, TOKEN_CONTRACT_ADDR) + masterSigner = await getMasterSigner(wallet3) + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + + instaImplementationsMapping = await ethers.getContractAt(implementationsABI, implementationsMappingAddr); + InstaAccountV2DefaultImpl = await ethers.getContractFactory("InstaDefaultImplementation") + instaAccountV2DefaultImpl = await InstaAccountV2DefaultImpl.deploy(addresses.core.instaIndex); + await instaAccountV2DefaultImpl.deployed() + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: connectV2BasicERC1155Artifacts, + 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.address).to.be.true; + }); + + describe("Implementations", function () { + + it("Should add default implementation to mapping.", async function () { + const tx = await instaImplementationsMapping.connect(masterSigner).setDefaultImplementation(instaAccountV2DefaultImpl.address); + await tx.wait() + expect(await instaImplementationsMapping.defaultImplementation()).to.be.equal(instaAccountV2DefaultImpl.address); + }); + + }); + + describe("DSA wallet setup", function () { + it("Should build DSA v2", async function () { + dsaWallet0 = await buildDSAv2(tokenOwner.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 deposit successfully", async () => { + console.log("DSA wallet address", dsaWallet0.address) + await nftContract.connect(tokenOwner).setApprovalForAll(dsaWallet0.address, true); + const spells = [ + { + connector: connectorName, + method: "depositERC1155", + args: [ + TOKEN_CONTRACT_ADDR, + TOKEN_ID, + 1, + "0", + "0" + ] + } + ]; + + const tx = await dsaWallet0 + .connect(tokenOwner) + .cast(...encodeSpells(spells), tokenOwner.address); + const receipt = await tx.wait(); + }); + }) +}) diff --git a/test/basic-ERC721/nftTransfer.test.js b/test/basic-ERC721/ERC721-transfer.js similarity index 79% rename from test/basic-ERC721/nftTransfer.test.js rename to test/basic-ERC721/ERC721-transfer.js index 9735d51e..01a5de0b 100644 --- a/test/basic-ERC721/nftTransfer.test.js +++ b/test/basic-ERC721/ERC721-transfer.js @@ -2,6 +2,7 @@ const { expect } = require("chai"); const hre = require("hardhat"); const { web3, deployments, waffle, ethers } = hre; const { provider, deployContract } = waffle +const {abi: implementationsABI} = require("../../scripts/constant/abi/core/InstaImplementations.json") const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") const buildDSAv2 = require("../../scripts/buildDSAv2") @@ -20,6 +21,8 @@ const TOKEN_CONTRACT_ADDR = "0x4d695c615a7aacf2d7b9c481b66045bb2457dfde"; const TOKEN_OWNER_ADDR = "0x8c6b10d42ff08e56133fca0dac75e1931b1fcc23"; const TOKEN_ID = "38"; +const implementationsMappingAddr = "0xCBA828153d3a85b30B5b912e1f2daCac5816aE9D" + describe("BASIC-ERC721", function () { const connectorName = "BASIC-ERC721-A" @@ -29,6 +32,7 @@ describe("BASIC-ERC721", function () { let connector; let nftContract; let tokenOwner; + let instaImplementationsMapping; const wallets = provider.getWallets() @@ -51,6 +55,11 @@ describe("BASIC-ERC721", function () { nftContract = await ethers.getContractAt(erc721Artifacts.abi, TOKEN_CONTRACT_ADDR) masterSigner = await getMasterSigner(wallet3) instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + + instaImplementationsMapping = await ethers.getContractAt(implementationsABI, implementationsMappingAddr); + InstaAccountV2DefaultImpl = await ethers.getContractFactory("InstaDefaultImplementation") + instaAccountV2DefaultImpl = await InstaAccountV2DefaultImpl.deploy(addresses.core.instaIndex); + await instaAccountV2DefaultImpl.deployed() connector = await deployAndEnableConnector({ connectorName, contractArtifact: connectV2BasicERC721Artifacts, @@ -66,6 +75,16 @@ describe("BASIC-ERC721", function () { expect(!!masterSigner.address).to.be.true; }); + describe("Implementations", function () { + + it("Should add default implementation to mapping.", async function () { + const tx = await instaImplementationsMapping.connect(masterSigner).setDefaultImplementation(instaAccountV2DefaultImpl.address); + await tx.wait() + expect(await instaImplementationsMapping.defaultImplementation()).to.be.equal(instaAccountV2DefaultImpl.address); + }); + + }); + describe("DSA wallet setup", function () { it("Should build DSA v2", async function () { dsaWallet0 = await buildDSAv2(tokenOwner.address) From 7d45c6ad8fc2ae256bfcde30b9e1eb6f0d1f7e99 Mon Sep 17 00:00:00 2001 From: Ishan Jain <contact@ishanjain.me> Date: Thu, 2 Sep 2021 13:00:48 +0530 Subject: [PATCH 16/28] Updated pr status check gh action config --- .github/workflows/status.yml | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/.github/workflows/status.yml b/.github/workflows/status.yml index 9dd6986c..0470aa1e 100644 --- a/.github/workflows/status.yml +++ b/.github/workflows/status.yml @@ -9,18 +9,24 @@ jobs: matrix: node-version: [16.x] steps: - - uses: actions/checkout@v1 - with: - # Checkout the head ref instead of the PR branch that github creates. - ref: ${{ github.head_ref }} - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - name: Install and build - run: | - npm install - - name: Run status checks - run: node ./status-checks - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Use Cache + uses: actions/cache@v2 + with: + path: | + node_modules + */*/node_modules + key: ${{ runner.os }}-${{ matrix.node_version }}-${{ hashFiles('**/package-lock.json') }} + - name: Install and build + run: | + npm install + - name: Run status checks + run: node ./status-checks + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 1252c0f4279601459e4878faf27bc55856de1d96 Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Thu, 2 Sep 2021 03:09:09 -0500 Subject: [PATCH 17/28] refactor: minor fixes and implement ETH-INST pool test --- .../connectors/uniswapStaker/events.sol | 2 +- .../mainnet/connectors/uniswapStaker/main.sol | 16 ++-- scripts/addLiquidity.js | 9 ++ test/uniswapStake/uniswapStake.test.js | 94 +++++++++++++++++-- 4 files changed, 104 insertions(+), 17 deletions(-) diff --git a/contracts/mainnet/connectors/uniswapStaker/events.sol b/contracts/mainnet/connectors/uniswapStaker/events.sol index b5b2e8b0..0406b33c 100644 --- a/contracts/mainnet/connectors/uniswapStaker/events.sol +++ b/contracts/mainnet/connectors/uniswapStaker/events.sol @@ -18,7 +18,7 @@ contract Events { ); event LogIncentiveCreated( - uint256 tokenId, + address poolAddr, uint256 startTime, uint256 endTime, uint256 reward diff --git a/contracts/mainnet/connectors/uniswapStaker/main.sol b/contracts/mainnet/connectors/uniswapStaker/main.sol index 18ca0916..e65f44d9 100644 --- a/contracts/mainnet/connectors/uniswapStaker/main.sol +++ b/contracts/mainnet/connectors/uniswapStaker/main.sol @@ -177,24 +177,21 @@ abstract contract UniswapResolver is Helpers, Events { * @param _rewardToken _rewardToken address * @param _length incentive length * @param _refundee refundee address - * @param _tokenId NFT LP token id + * @param _poolAddr Uniswap V3 Pool address * @param _reward reward amount */ function createIncentive( address _rewardToken, uint256 _length, address _refundee, - uint256 _tokenId, + address _poolAddr, uint256 _reward ) external payable returns (string memory _eventName, bytes memory _eventParam) { - if (_tokenId == 0) _tokenId = _getLastNftId(address(this)); - address poolAddr = getPoolAddress(_tokenId); - - IUniswapV3Pool pool = IUniswapV3Pool(poolAddr); + IUniswapV3Pool pool = IUniswapV3Pool(_poolAddr); uint256 _startTime = block.timestamp; uint256 _endTime = _startTime + _length; IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker @@ -205,10 +202,13 @@ abstract contract UniswapResolver is Helpers, Events { _endTime, _refundee ); + if (_rewardToken != ethAddr) { + IERC20Minimal(_rewardToken).approve(address(staker), _reward); + } staker.createIncentive(_key, _reward); - _eventName = "LogIncentiveCreated(uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(_tokenId, _startTime, _endTime, _reward); + _eventName = "LogIncentiveCreated(address,uint256,uint256,uint256)"; + _eventParam = abi.encode(_poolAddr, _startTime, _endTime, _reward); } } diff --git a/scripts/addLiquidity.js b/scripts/addLiquidity.js index 0fb51156..c461a775 100644 --- a/scripts/addLiquidity.js +++ b/scripts/addLiquidity.js @@ -50,6 +50,15 @@ const tokenMapping = { await mineTx(contract.mint(address, amt)); }, }, + inst: { + impersonateSigner: "0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88", + address: "0x6f40d4a6237c257fff2db00fa0510deeecd303eb", + abi: ["function transfer(address to, uint value)"], + process: async function(owner, address, amt) { + const contract = new ethers.Contract(this.address, this.abi, owner); + await mineTx(contract.transfer(address, amt)); + }, + } }; module.exports = async (tokenName, address, amt) => { diff --git a/test/uniswapStake/uniswapStake.test.js b/test/uniswapStake/uniswapStake.test.js index be684b6a..67b523a0 100644 --- a/test/uniswapStake/uniswapStake.test.js +++ b/test/uniswapStake/uniswapStake.test.js @@ -30,6 +30,7 @@ const TICK_SPACINGS = { const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" +const INST_ADDR = "0x6f40d4a6237c257fff2db00fa0510deeecd303eb" let tokenIds = [] const abiCoder = ethers.utils.defaultAbiCoder @@ -88,7 +89,7 @@ describe("UniswapV3", function () { await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("100000")); }); - it("Deposit ETH & USDT into DSA wallet", async function () { + it("Deposit ETH & USDT & INST into DSA wallet", async function () { await wallet0.sendTransaction({ to: dsaWallet0.address, value: ethers.utils.parseEther("10") @@ -97,12 +98,14 @@ describe("UniswapV3", function () { await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("100000")); await addLiquidity("usdt", dsaWallet0.address, ethers.utils.parseEther("100000")); + await addLiquidity("inst", dsaWallet0.address, ethers.utils.parseEther("10000")); }); }); describe("Main", function () { const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH const daiAmount = ethers.utils.parseEther("400") // 1 ETH + const instAmount = ethers.utils.parseEther("50") it("Should mint successfully", async function () { const getIds = ["0", "0"] @@ -124,6 +127,22 @@ describe("UniswapV3", function () { getIds, setId ], + }, + { + connector: connectorUniswap, + method: "mint", + args: [ + INST_ADDR, + ethAddress, + FeeAmount.MEDIUM, + getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), + getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), + instAmount, + ethAmount, + "500000000000000000", + getIds, + setId + ], } ] @@ -133,7 +152,9 @@ describe("UniswapV3", function () { let castEvent = new Promise((resolve, reject) => { dsaWallet0.on('LogCast', (origin, sender, value, targetNames, targets, eventNames, eventParams, event) => { const params = abiCoder.decode(["uint256", "uint256", "uint256", "uint256", "int24", "int24"], eventParams[0]); + const params1 = abiCoder.decode(["uint256", "uint256", "uint256", "uint256", "int24", "int24"], eventParams[1]); tokenIds.push(params[0]); + tokenIds.push(params1[0]); event.removeListener(); resolve({ @@ -153,6 +174,7 @@ describe("UniswapV3", function () { }); it("Should create incentive successfully", async function () { + console.log("TokenIds", tokenIds[1]); const spells = [ { connector: connectorStaker, @@ -161,20 +183,32 @@ describe("UniswapV3", function () { ethAddress, "1000", dsaWallet0.address, - tokenIds[0], + "0xc2e9f25be6257c210d7adf0d4cd6e3e881ba25f8", + ethers.utils.parseEther("0.01") + ], + }, + { + connector: connectorStaker, + method: "createIncentive", + args: [ + INST_ADDR, + "50", + dsaWallet0.address, + "0xcba27c8e7115b4eb50aa14999bc0866674a96ecb", ethers.utils.parseEther("0.01") ], }] - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) let receipt = await tx.wait() let castEvent = new Promise((resolve, reject) => { dsaWallet0.on('LogCast', (origin, sender, value, targetNames, targets, eventNames, eventParams, event) => { const params = abiCoder.decode(["uint256", "uint256", "uint256", "uint256"], eventParams[0]); + const params1 = abiCoder.decode(["uint256", "uint256", "uint256", "uint256"], eventParams[1]); event.removeListener(); - resolve({ start: params[1], end: params[2] }); + resolve({ start: [params[1], params1[1]], end: [params[2], params1[2]] }); }); setTimeout(() => { @@ -201,11 +235,29 @@ describe("UniswapV3", function () { method: "stake", args: [ ethAddress, - startTime, - endTime, + startTime[0], + endTime[0], dsaWallet0.address, tokenIds[0] ], + }, + { + connector: connectorStaker, + method: "deposit", + args: [ + tokenIds[1] + ], + }, + { + connector: connectorStaker, + method: "stake", + args: [ + INST_ADDR, + startTime[1], + endTime[1], + dsaWallet0.address, + tokenIds[1] + ], } ] @@ -222,7 +274,14 @@ describe("UniswapV3", function () { connector: connectorStaker, method: "claimRewards", args: [ - ethAddress, + DAI_ADDR, + dsaWallet0.address, + "1000", + ], + connector: connectorStaker, + method: "claimRewards", + args: [ + INST_ADDR, dsaWallet0.address, "1000", ], @@ -239,7 +298,7 @@ describe("UniswapV3", function () { connector: connectorStaker, method: "unstake", args: [ - ethAddress, + DAI_ADDR, startTime, endTime, dsaWallet0.address, @@ -253,6 +312,25 @@ describe("UniswapV3", function () { tokenIds[0], dsaWallet0.address, ], + }, + { + connector: connectorStaker, + method: "unstake", + args: [ + INST_ADDR, + startTime, + endTime, + dsaWallet0.address, + tokenIds[1] + ], + }, + { + connector: connectorStaker, + method: "withdraw", + args: [ + tokenIds[1], + dsaWallet0.address, + ], } ] From 0da788cdb2f3d8ab8c4af2ab66fbe58b3a542673 Mon Sep 17 00:00:00 2001 From: Ishan Jain <contact@ishanjain.me> Date: Thu, 2 Sep 2021 22:56:29 +0530 Subject: [PATCH 18/28] auto check pr gh action: Add output of status checks as a comment in the thread --- .github/workflows/status.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/status.yml b/.github/workflows/status.yml index 0470aa1e..fc6ede0a 100644 --- a/.github/workflows/status.yml +++ b/.github/workflows/status.yml @@ -27,6 +27,22 @@ jobs: run: | npm install - name: Run status checks - run: node ./status-checks + id: status_check + run: | + output=$(node ./status-checks) + # Escape newlines so _all_ the output is included in the set-output + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=status_check_output::$output" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Auto Comment Status Check Result + # Use with caution + uses: bubkoo/auto-comment@v1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + pullRequestSynchronize: "${{ steps.status_check.outputs.output }}" + pullRequestAssigned: "${{ steps.status_check.outputs.output }}" + pullRequestOpened: "${{ steps.status_check.outputs.output }}" + pullRequestReopened: "${{ steps.status_check.outputs.output }}" From cf504594be9a99e628dd1ba6a7ae8cae46830e9f Mon Sep 17 00:00:00 2001 From: Ishan Jain <contact@ishanjain.me> Date: Thu, 2 Sep 2021 23:31:58 +0530 Subject: [PATCH 19/28] Updated pull request check gh action --- .github/workflows/status.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/status.yml b/.github/workflows/status.yml index fc6ede0a..2e72f099 100644 --- a/.github/workflows/status.yml +++ b/.github/workflows/status.yml @@ -42,7 +42,7 @@ jobs: uses: bubkoo/auto-comment@v1 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - pullRequestSynchronize: "${{ steps.status_check.outputs.output }}" - pullRequestAssigned: "${{ steps.status_check.outputs.output }}" - pullRequestOpened: "${{ steps.status_check.outputs.output }}" - pullRequestReopened: "${{ steps.status_check.outputs.output }}" + pullRequestSynchronize: "${{ steps.status_check.outputs.status_check_output }}" + pullRequestAssigned: "${{ steps.status_check.outputs.status_check_output }}" + pullRequestOpened: "${{ steps.status_check.outputs.status_check_output }}" + pullRequestReopened: "${{ steps.status_check.outputs.status_check_output }}" From 6c5460fac2745e722438330124f9c8010a2adb3c Mon Sep 17 00:00:00 2001 From: Aleksandr S <ardhead@gmail.com> Date: Sun, 5 Sep 2021 11:32:18 +0300 Subject: [PATCH 20/28] cl args to set check path --- README.md | 6 ++++++ package.json | 1 + status-checks/check.js | 13 ++++++++----- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e9a60cd8..39b78357 100644 --- a/README.md +++ b/README.md @@ -54,3 +54,9 @@ Few things to consider while writing the connector: If you can't find something you're looking for or have any questions, ask them at our developers community on [Discord](https://discord.gg/83vvrnY) or simply send an [Email](mailto:info@instadapp.io). +## Check run + +use +`npm run check` +to check `connectors` directory. Use `connector=$` argument to check specific connector: +`npm run check connector=contracts/mainnet/common` diff --git a/package.json b/package.json index 589d093e..22fdaec2 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "test": "hardhat test", "coverage": "./node_modules/.bin/solidity-coverage", + "check": "node status-checks/huskyCheck.js", "check-husky": "node status-checks/huskyCheck.js", "build-contracts": "sol-merger \"./contracts/connectors/mock.sol\" ./contracts/build" }, diff --git a/status-checks/check.js b/status-checks/check.js index a76d81ae..c0848d77 100644 --- a/status-checks/check.js +++ b/status-checks/check.js @@ -3,13 +3,11 @@ const path = require('path') const forbiddenStrings = ['selfdestruct'] -const getConnectorsList = async () => { +const getConnectorsList = async (connectorsRootsDirs) => { try { const connectors = [] - const connectorsRootsDirs = ['mainnet', 'polygon'] for (let index = 0; index < connectorsRootsDirs.length; index++) { - const root = `contracts/${connectorsRootsDirs[index]}/connectors` - const dirs = [root] + const dirs = [connectorsRootsDirs[index]] while (dirs.length) { const currentDir = dirs.pop() const subs = fs.readdirSync(currentDir, { withFileTypes: true }) @@ -326,9 +324,14 @@ const checkHeadComments = async (connector) => { async function checkMain () { try { + const connectorsRootsDirsDefault = ['mainnet', 'polygon'].map(v=> `contracts/${v}/connectors`) + const customPathArg = process.argv.find(a => a.startsWith('connector=')) + const connectorsRootsDirs = customPathArg + ? [customPathArg.slice(10)] + : connectorsRootsDirsDefault const errors = [] const warnings = [] - const connectors = await getConnectorsList() + const connectors = await getConnectorsList(connectorsRootsDirs) for (let index = 0; index < connectors.length; index++) { const { forbiddenErrors, code } = await checkForbidden(connectors[index].path) connectors[index].code = code From 7b2dd953b1575ff885773e2a79883edc1c4f0b01 Mon Sep 17 00:00:00 2001 From: Aleksandr S <ardhead@gmail.com> Date: Sun, 5 Sep 2021 19:53:23 +0300 Subject: [PATCH 21/28] readme update --- README.md | 7 ------- status-checks/readme.md | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 status-checks/readme.md diff --git a/README.md b/README.md index 39b78357..be1b4893 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,3 @@ Few things to consider while writing the connector: ### Support If you can't find something you're looking for or have any questions, ask them at our developers community on [Discord](https://discord.gg/83vvrnY) or simply send an [Email](mailto:info@instadapp.io). - -## Check run - -use -`npm run check` -to check `connectors` directory. Use `connector=$` argument to check specific connector: -`npm run check connector=contracts/mainnet/common` diff --git a/status-checks/readme.md b/status-checks/readme.md new file mode 100644 index 00000000..ed376c25 --- /dev/null +++ b/status-checks/readme.md @@ -0,0 +1,7 @@ + +# Check run + +use +`npm run check` +to check `connectors` directory. Use `connector=$` argument to check specific connector: +`npm run check connector=contracts/mainnet/common` From b64791d984d68958613d6c65b2e016702a0ad0b7 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar <thrilok2000@gmail.com> Date: Tue, 7 Sep 2021 16:44:59 +0530 Subject: [PATCH 22/28] Minor comment fixes --- contracts/mainnet/connectors/basic-ERC1155/main.sol | 8 ++++---- contracts/mainnet/connectors/basic-ERC721/main.sol | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/mainnet/connectors/basic-ERC1155/main.sol b/contracts/mainnet/connectors/basic-ERC1155/main.sol index b6ab4af8..0aef5cd7 100644 --- a/contracts/mainnet/connectors/basic-ERC1155/main.sol +++ b/contracts/mainnet/connectors/basic-ERC1155/main.sol @@ -2,7 +2,7 @@ pragma solidity ^0.7.0; /** * @title Basic. - * @dev Deposit & Withdraw from DSA. + * @dev Deposit & Withdraw from ERC1155 DSA. */ import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; @@ -13,7 +13,7 @@ import {Events} from "./events.sol"; abstract contract BasicResolver is Events, DSMath, Basic { /** * @dev Deposit Assets To Smart Account. - * @notice Deposit a ERC721 token to DSA + * @notice Deposit a ERC1155 token to DSA * @param token Address of token. * @param tokenId ID of token. * @param amount Amount to deposit. @@ -31,7 +31,7 @@ abstract contract BasicResolver is Events, DSMath, Basic { payable returns (string memory _eventName, bytes memory _eventParam) { - uint256 _amount = getUint(getId, tokenId); + uint256 _amount = getUint(getId, amount); IERC1155 tokenContract = IERC1155(token); tokenContract.safeTransferFrom( @@ -57,7 +57,7 @@ abstract contract BasicResolver is Events, DSMath, Basic { /** * @dev Withdraw Assets To Smart Account. - * @notice Withdraw a ERC721 token from DSA + * @notice Withdraw a ERC1155 token from DSA * @param token Address of the token. * @param tokenId ID of token. * @param to The address to receive the token upon withdrawal diff --git a/contracts/mainnet/connectors/basic-ERC721/main.sol b/contracts/mainnet/connectors/basic-ERC721/main.sol index a6962b47..410c6342 100644 --- a/contracts/mainnet/connectors/basic-ERC721/main.sol +++ b/contracts/mainnet/connectors/basic-ERC721/main.sol @@ -2,7 +2,7 @@ pragma solidity ^0.7.0; /** * @title Basic. - * @dev Deposit & Withdraw from DSA. + * @dev Deposit & Withdraw ERC721 from DSA. */ import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; From 3c800b82accee88a1888107b8c60c96107270651 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar <thrilok2000@gmail.com> Date: Tue, 7 Sep 2021 23:48:07 +0530 Subject: [PATCH 23/28] restructured uniswap folders --- contracts/mainnet/connectors/uniswap/{ => v2}/events.sol | 0 contracts/mainnet/connectors/uniswap/{ => v2}/helpers.sol | 0 contracts/mainnet/connectors/uniswap/{ => v2}/interface.sol | 0 contracts/mainnet/connectors/uniswap/{ => v2}/main.sol | 0 contracts/mainnet/connectors/{uniswapV3 => uniswap/v3}/events.sol | 0 .../mainnet/connectors/{uniswapV3 => uniswap/v3}/helpers.sol | 0 .../mainnet/connectors/{uniswapV3 => uniswap/v3}/interface.sol | 0 contracts/mainnet/connectors/{uniswapV3 => uniswap/v3}/main.sol | 0 .../connectors/{uniswapStaker => uniswap/v3_staker}/events.sol | 0 .../connectors/{uniswapStaker => uniswap/v3_staker}/helpers.sol | 0 .../connectors/{uniswapStaker => uniswap/v3_staker}/interface.sol | 0 .../connectors/{uniswapStaker => uniswap/v3_staker}/main.sol | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename contracts/mainnet/connectors/uniswap/{ => v2}/events.sol (100%) rename contracts/mainnet/connectors/uniswap/{ => v2}/helpers.sol (100%) rename contracts/mainnet/connectors/uniswap/{ => v2}/interface.sol (100%) rename contracts/mainnet/connectors/uniswap/{ => v2}/main.sol (100%) rename contracts/mainnet/connectors/{uniswapV3 => uniswap/v3}/events.sol (100%) rename contracts/mainnet/connectors/{uniswapV3 => uniswap/v3}/helpers.sol (100%) rename contracts/mainnet/connectors/{uniswapV3 => uniswap/v3}/interface.sol (100%) rename contracts/mainnet/connectors/{uniswapV3 => uniswap/v3}/main.sol (100%) rename contracts/mainnet/connectors/{uniswapStaker => uniswap/v3_staker}/events.sol (100%) rename contracts/mainnet/connectors/{uniswapStaker => uniswap/v3_staker}/helpers.sol (100%) rename contracts/mainnet/connectors/{uniswapStaker => uniswap/v3_staker}/interface.sol (100%) rename contracts/mainnet/connectors/{uniswapStaker => uniswap/v3_staker}/main.sol (100%) diff --git a/contracts/mainnet/connectors/uniswap/events.sol b/contracts/mainnet/connectors/uniswap/v2/events.sol similarity index 100% rename from contracts/mainnet/connectors/uniswap/events.sol rename to contracts/mainnet/connectors/uniswap/v2/events.sol diff --git a/contracts/mainnet/connectors/uniswap/helpers.sol b/contracts/mainnet/connectors/uniswap/v2/helpers.sol similarity index 100% rename from contracts/mainnet/connectors/uniswap/helpers.sol rename to contracts/mainnet/connectors/uniswap/v2/helpers.sol diff --git a/contracts/mainnet/connectors/uniswap/interface.sol b/contracts/mainnet/connectors/uniswap/v2/interface.sol similarity index 100% rename from contracts/mainnet/connectors/uniswap/interface.sol rename to contracts/mainnet/connectors/uniswap/v2/interface.sol diff --git a/contracts/mainnet/connectors/uniswap/main.sol b/contracts/mainnet/connectors/uniswap/v2/main.sol similarity index 100% rename from contracts/mainnet/connectors/uniswap/main.sol rename to contracts/mainnet/connectors/uniswap/v2/main.sol diff --git a/contracts/mainnet/connectors/uniswapV3/events.sol b/contracts/mainnet/connectors/uniswap/v3/events.sol similarity index 100% rename from contracts/mainnet/connectors/uniswapV3/events.sol rename to contracts/mainnet/connectors/uniswap/v3/events.sol diff --git a/contracts/mainnet/connectors/uniswapV3/helpers.sol b/contracts/mainnet/connectors/uniswap/v3/helpers.sol similarity index 100% rename from contracts/mainnet/connectors/uniswapV3/helpers.sol rename to contracts/mainnet/connectors/uniswap/v3/helpers.sol diff --git a/contracts/mainnet/connectors/uniswapV3/interface.sol b/contracts/mainnet/connectors/uniswap/v3/interface.sol similarity index 100% rename from contracts/mainnet/connectors/uniswapV3/interface.sol rename to contracts/mainnet/connectors/uniswap/v3/interface.sol diff --git a/contracts/mainnet/connectors/uniswapV3/main.sol b/contracts/mainnet/connectors/uniswap/v3/main.sol similarity index 100% rename from contracts/mainnet/connectors/uniswapV3/main.sol rename to contracts/mainnet/connectors/uniswap/v3/main.sol diff --git a/contracts/mainnet/connectors/uniswapStaker/events.sol b/contracts/mainnet/connectors/uniswap/v3_staker/events.sol similarity index 100% rename from contracts/mainnet/connectors/uniswapStaker/events.sol rename to contracts/mainnet/connectors/uniswap/v3_staker/events.sol diff --git a/contracts/mainnet/connectors/uniswapStaker/helpers.sol b/contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol similarity index 100% rename from contracts/mainnet/connectors/uniswapStaker/helpers.sol rename to contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol diff --git a/contracts/mainnet/connectors/uniswapStaker/interface.sol b/contracts/mainnet/connectors/uniswap/v3_staker/interface.sol similarity index 100% rename from contracts/mainnet/connectors/uniswapStaker/interface.sol rename to contracts/mainnet/connectors/uniswap/v3_staker/interface.sol diff --git a/contracts/mainnet/connectors/uniswapStaker/main.sol b/contracts/mainnet/connectors/uniswap/v3_staker/main.sol similarity index 100% rename from contracts/mainnet/connectors/uniswapStaker/main.sol rename to contracts/mainnet/connectors/uniswap/v3_staker/main.sol From 73969113c5a67d4bac2260354df5b7dfcc08bd48 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar <thrilok2000@gmail.com> Date: Tue, 7 Sep 2021 23:50:58 +0530 Subject: [PATCH 24/28] minor fixes --- contracts/mainnet/connectors/uniswap/v2/helpers.sol | 6 +++--- contracts/mainnet/connectors/uniswap/v2/main.sol | 2 +- contracts/mainnet/connectors/uniswap/v3/helpers.sol | 6 +++--- contracts/mainnet/connectors/uniswap/v3/main.sol | 2 +- contracts/mainnet/connectors/uniswap/v3_staker/events.sol | 1 + contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol | 6 +++--- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap/v2/helpers.sol b/contracts/mainnet/connectors/uniswap/v2/helpers.sol index f435a78b..f0a8a6da 100644 --- a/contracts/mainnet/connectors/uniswap/v2/helpers.sol +++ b/contracts/mainnet/connectors/uniswap/v2/helpers.sol @@ -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"; import { IUniswapV2Router02, IUniswapV2Factory } from "./interface.sol"; abstract contract Helpers is DSMath, Basic { diff --git a/contracts/mainnet/connectors/uniswap/v2/main.sol b/contracts/mainnet/connectors/uniswap/v2/main.sol index a8ee9959..e0daa6a9 100644 --- a/contracts/mainnet/connectors/uniswap/v2/main.sol +++ b/contracts/mainnet/connectors/uniswap/v2/main.sol @@ -5,7 +5,7 @@ pragma solidity ^0.7.0; * @dev Decentralized Exchange. */ -import { TokenInterface } from "../../common/interfaces.sol"; +import { TokenInterface } from "../../../common/interfaces.sol"; import { Helpers } from "./helpers.sol"; import { Events } from "./events.sol"; diff --git a/contracts/mainnet/connectors/uniswap/v3/helpers.sol b/contracts/mainnet/connectors/uniswap/v3/helpers.sol index 8585f84f..2fc42f8b 100644 --- a/contracts/mainnet/connectors/uniswap/v3/helpers.sol +++ b/contracts/mainnet/connectors/uniswap/v3/helpers.sol @@ -1,9 +1,9 @@ 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 {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"; diff --git a/contracts/mainnet/connectors/uniswap/v3/main.sol b/contracts/mainnet/connectors/uniswap/v3/main.sol index 7fd058a6..c40f871f 100644 --- a/contracts/mainnet/connectors/uniswap/v3/main.sol +++ b/contracts/mainnet/connectors/uniswap/v3/main.sol @@ -6,7 +6,7 @@ pragma abicoder v2; * @dev Decentralized Exchange. */ -import {TokenInterface} from "../../common/interfaces.sol"; +import {TokenInterface} from "../../../common/interfaces.sol"; import {Helpers} from "./helpers.sol"; import {Events} from "./events.sol"; diff --git a/contracts/mainnet/connectors/uniswap/v3_staker/events.sol b/contracts/mainnet/connectors/uniswap/v3_staker/events.sol index 0406b33c..1582d7d2 100644 --- a/contracts/mainnet/connectors/uniswap/v3_staker/events.sol +++ b/contracts/mainnet/connectors/uniswap/v3_staker/events.sol @@ -19,6 +19,7 @@ contract Events { event LogIncentiveCreated( address poolAddr, + address refundee, uint256 startTime, uint256 endTime, uint256 reward diff --git a/contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol b/contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol index 71926302..f6ff4e16 100644 --- a/contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol +++ b/contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol @@ -1,9 +1,9 @@ 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 {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"; From e62e0cfea84be9d908d274faba8041dbab5bd1b9 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar <thrilok2000@gmail.com> Date: Wed, 8 Sep 2021 00:00:48 +0530 Subject: [PATCH 25/28] Minor changes --- .../connectors/uniswap/v3_staker/events.sol | 10 +++--- .../connectors/uniswap/v3_staker/helpers.sol | 36 ------------------- .../connectors/uniswap/v3_staker/main.sol | 35 +++++++++--------- 3 files changed, 21 insertions(+), 60 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap/v3_staker/events.sol b/contracts/mainnet/connectors/uniswap/v3_staker/events.sol index 1582d7d2..fa8bbebf 100644 --- a/contracts/mainnet/connectors/uniswap/v3_staker/events.sol +++ b/contracts/mainnet/connectors/uniswap/v3_staker/events.sol @@ -3,21 +3,21 @@ pragma solidity ^0.7.0; contract Events { event LogDeposit(uint256 tokenId); - event LogWithdraw(uint256 indexed tokenId, address to); + event LogWithdraw(uint256 indexed tokenId); event LogDepositTransfer(uint256 indexed tokenId, address to); - event LogStake(uint256 tokenId, address refundee); + event LogStake(uint256 indexed tokenId, bytes32 incentiveId); - event LogUnstake(uint256 tokenId, bytes32 incentiveId); + event LogUnstake(uint256 indexed tokenId, bytes32 incentiveId); event LogRewardClaimed( - address rewardToken, - address receiver, + address indexed rewardToken, uint256 amount ); event LogIncentiveCreated( + bytes32 incentiveId, address poolAddr, address refundee, uint256 startTime, diff --git a/contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol b/contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol index f6ff4e16..258d0961 100644 --- a/contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol +++ b/contracts/mainnet/connectors/uniswap/v3_staker/helpers.sol @@ -32,42 +32,6 @@ abstract contract Helpers is DSMath, Basic { 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 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 - ) - ); - } - } - function getPoolAddress(uint256 _tokenId) internal view diff --git a/contracts/mainnet/connectors/uniswap/v3_staker/main.sol b/contracts/mainnet/connectors/uniswap/v3_staker/main.sol index e65f44d9..2da11c59 100644 --- a/contracts/mainnet/connectors/uniswap/v3_staker/main.sol +++ b/contracts/mainnet/connectors/uniswap/v3_staker/main.sol @@ -6,7 +6,7 @@ pragma abicoder v2; * @dev Decentralized Exchange. */ -import {TokenInterface} from "../../common/interfaces.sol"; +import {TokenInterface} from "../../../common/interfaces.sol"; import "./interface.sol"; import {Helpers} from "./helpers.sol"; import {Events} from "./events.sol"; @@ -56,18 +56,17 @@ abstract contract UniswapResolver is Helpers, Events { * @dev Withdraw NFT LP token * @notice Withdraw NFT LP token from staking pool * @param _tokenId NFT LP Token ID - * @param _to address to transfer */ - function withdraw(uint256 _tokenId, address _to) + function withdraw(uint256 _tokenId) external payable returns (string memory _eventName, bytes memory _eventParam) { if (_tokenId == 0) _tokenId = _getLastNftId(address(this)); - staker.withdrawToken(_tokenId, _to, ""); + staker.withdrawToken(_tokenId, address(this), ""); - _eventName = "LogWithdraw(uint256,address)"; - _eventParam = abi.encode(_tokenId, _to); + _eventName = "LogWithdraw(uint256)"; + _eventParam = abi.encode(_tokenId); } /** @@ -104,8 +103,8 @@ abstract contract UniswapResolver is Helpers, Events { ); _stake(_tokenId, _key); - _eventName = "LogStake(uint256,address)"; - _eventParam = abi.encode(_tokenId, _refundee); + _eventName = "LogStake(uint256,bytes32)"; + _eventParam = abi.encode(_tokenId, keccak256(abi.encode(_key))); } /** @@ -142,20 +141,18 @@ abstract contract UniswapResolver is Helpers, Events { ); _unstake(_key, _tokenId); _eventName = "LogUnstake(uint256,bytes32)"; - _eventParam = abi.encode(_tokenId, _key); + _eventParam = abi.encode(_tokenId, keccak256(abi.encode(_key))); } /** * @dev Claim rewards * @notice Claim rewards * @param _rewardToken _rewardToken address - * @param _to address to receive - * @param _amountRequested requested amount + * @param _amount requested amount */ function claimRewards( address _rewardToken, - address _to, - uint256 _amountRequested + uint256 _amount ) external payable @@ -163,12 +160,12 @@ abstract contract UniswapResolver is Helpers, Events { { uint256 rewards = _claimRewards( IERC20Minimal(_rewardToken), - _to, - _amountRequested + address(this), + _amount ); - _eventName = "LogRewardClaimed(address,address,uint256)"; - _eventParam = abi.encode(_rewardToken, _to, rewards); + _eventName = "LogRewardClaimed(address,uint256)"; + _eventParam = abi.encode(_rewardToken, rewards); } /** @@ -207,8 +204,8 @@ abstract contract UniswapResolver is Helpers, Events { } staker.createIncentive(_key, _reward); - _eventName = "LogIncentiveCreated(address,uint256,uint256,uint256)"; - _eventParam = abi.encode(_poolAddr, _startTime, _endTime, _reward); + _eventName = "LogIncentiveCreated(bytes32,address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(keccak256(abi.encode(_key)), _poolAddr, _refundee, _startTime, _endTime, _reward); } } From df7becce200ee6b1d4fefe7044e0422b00acf638 Mon Sep 17 00:00:00 2001 From: Ishan Jain <contact@ishanjain.me> Date: Wed, 8 Sep 2021 00:31:20 +0530 Subject: [PATCH 26/28] Pretty print status check output in comments, Remove the colors --- .github/workflows/status.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/status.yml b/.github/workflows/status.yml index 2e72f099..3382de78 100644 --- a/.github/workflows/status.yml +++ b/.github/workflows/status.yml @@ -29,7 +29,8 @@ jobs: - name: Run status checks id: status_check run: | - output=$(node ./status-checks) + # Run status checks, Remove ANSI colors from the text + output=$(node ./status-checks | sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g') # Escape newlines so _all_ the output is included in the set-output output="${output//'%'/'%25'}" output="${output//$'\n'/'%0A'}" @@ -42,7 +43,7 @@ jobs: uses: bubkoo/auto-comment@v1 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - pullRequestSynchronize: "${{ steps.status_check.outputs.status_check_output }}" - pullRequestAssigned: "${{ steps.status_check.outputs.status_check_output }}" - pullRequestOpened: "${{ steps.status_check.outputs.status_check_output }}" - pullRequestReopened: "${{ steps.status_check.outputs.status_check_output }}" + pullRequestSynchronize: "```${{ steps.status_check.outputs.status_check_output }}```" + pullRequestAssigned: "```${{ steps.status_check.outputs.status_check_output }}```" + pullRequestOpened: "```${{ steps.status_check.outputs.status_check_output }}```" + pullRequestReopened: "```${{ steps.status_check.outputs.status_check_output }}```" From a2717f0853ca6e422800188f9bdcb22799e092dc Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Tue, 7 Sep 2021 14:35:46 -0500 Subject: [PATCH 27/28] refactor: minor fixes --- hardhat.config.js | 2 +- test/uniswapStake/uniswapStake.test.js | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/hardhat.config.js b/hardhat.config.js index 3320c333..44456a48 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -57,7 +57,7 @@ module.exports = { hardhat: { forking: { url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`, - blockNumber: 13005785, + blockNumber: 13180514, }, blockGasLimit: 12000000, gasPrice: parseInt(utils.parseUnits("300", "gwei")) diff --git a/test/uniswapStake/uniswapStake.test.js b/test/uniswapStake/uniswapStake.test.js index 67b523a0..b11a5927 100644 --- a/test/uniswapStake/uniswapStake.test.js +++ b/test/uniswapStake/uniswapStake.test.js @@ -170,11 +170,10 @@ describe("UniswapV3", function () { let event = await castEvent let balance = await nftManager.connect(wallet0).balanceOf(dsaWallet0.address) - console.log("Balane", balance) + console.log("Balance", balance) }); it("Should create incentive successfully", async function () { - console.log("TokenIds", tokenIds[1]); const spells = [ { connector: connectorStaker, @@ -265,7 +264,7 @@ describe("UniswapV3", function () { let receipt = await tx.wait() let balance = await nftManager.connect(wallet0).balanceOf(dsaWallet0.address) - console.log("Balane", balance) + console.log("Balance", balance) }); it("Should claim rewards successfully", async function () { @@ -274,7 +273,7 @@ describe("UniswapV3", function () { connector: connectorStaker, method: "claimRewards", args: [ - DAI_ADDR, + ethAddress, dsaWallet0.address, "1000", ], @@ -298,9 +297,9 @@ describe("UniswapV3", function () { connector: connectorStaker, method: "unstake", args: [ - DAI_ADDR, - startTime, - endTime, + ethAddress, + startTime[0], + endTime[0], dsaWallet0.address, tokenIds[0] ], @@ -318,8 +317,8 @@ describe("UniswapV3", function () { method: "unstake", args: [ INST_ADDR, - startTime, - endTime, + startTime[1], + endTime[1], dsaWallet0.address, tokenIds[1] ], @@ -338,7 +337,7 @@ describe("UniswapV3", function () { let receipt = await tx.wait() let balance = await nftManager.connect(wallet0).balanceOf(dsaWallet0.address) - console.log("Balane", balance) + console.log("Balance", balance) }); }) }) From cf53215d13a40193ba11e91a254c6cdb2822fba6 Mon Sep 17 00:00:00 2001 From: cryptoDev222 <genius.developer.63@gmail.com> Date: Tue, 7 Sep 2021 15:20:19 -0500 Subject: [PATCH 28/28] refactor: minor fixes --- test/uniswapStake/uniswapStake.test.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/test/uniswapStake/uniswapStake.test.js b/test/uniswapStake/uniswapStake.test.js index b11a5927..043bd07f 100644 --- a/test/uniswapStake/uniswapStake.test.js +++ b/test/uniswapStake/uniswapStake.test.js @@ -13,8 +13,8 @@ const addresses = require("../../scripts/constant/addresses"); const abis = require("../../scripts/constant/abis"); const { abi: nftManagerAbi } = require("@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json") -const connectV2UniswapStakerArtifacts = require("../../artifacts/contracts/mainnet/connectors/uniswapStaker/main.sol/ConnectV2UniswapV3Staker.json"); -const connectV2UniswapV3Artifacts = require("../../artifacts/contracts/mainnet/connectors/uniswapV3/main.sol/ConnectV2UniswapV3.json"); +const connectV2UniswapStakerArtifacts = require("../../artifacts/contracts/mainnet/connectors/uniswap/v3_staker/main.sol/ConnectV2UniswapV3Staker.json"); +const connectV2UniswapV3Artifacts = require("../../artifacts/contracts/mainnet/connectors/uniswap/v3/main.sol/ConnectV2UniswapV3.json"); const FeeAmount = { LOW: 500, @@ -203,11 +203,11 @@ describe("UniswapV3", function () { let castEvent = new Promise((resolve, reject) => { dsaWallet0.on('LogCast', (origin, sender, value, targetNames, targets, eventNames, eventParams, event) => { - const params = abiCoder.decode(["uint256", "uint256", "uint256", "uint256"], eventParams[0]); - const params1 = abiCoder.decode(["uint256", "uint256", "uint256", "uint256"], eventParams[1]); + const params = abiCoder.decode(["bytes32","address","address","uint256","uint256","uint256"], eventParams[0]); + const params1 = abiCoder.decode(["bytes32","address","address","uint256","uint256","uint256"], eventParams[1]); event.removeListener(); - resolve({ start: [params[1], params1[1]], end: [params[2], params1[2]] }); + resolve({ start: [params[3], params1[3]], end: [params[4], params1[4]] }); }); setTimeout(() => { @@ -274,14 +274,12 @@ describe("UniswapV3", function () { method: "claimRewards", args: [ ethAddress, - dsaWallet0.address, "1000", ], connector: connectorStaker, method: "claimRewards", args: [ INST_ADDR, - dsaWallet0.address, "1000", ], } @@ -309,7 +307,6 @@ describe("UniswapV3", function () { method: "withdraw", args: [ tokenIds[0], - dsaWallet0.address, ], }, { @@ -327,8 +324,7 @@ describe("UniswapV3", function () { connector: connectorStaker, method: "withdraw", args: [ - tokenIds[1], - dsaWallet0.address, + tokenIds[1] ], } ]