diff --git a/contracts/mock/aave-v2-migrator/main.sol b/contracts/mock/aave-v2-migrator/main.sol new file mode 100644 index 0000000..7d65358 --- /dev/null +++ b/contracts/mock/aave-v2-migrator/main.sol @@ -0,0 +1,113 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +import { Variables } from "./variables.sol"; + +/** + * @title InstaAccountV2 Implementation-M2. + * @dev DeFi Smart Account Wallet for polygon migration. + */ + +interface ConnectorsInterface { + function isConnectors(string[] calldata connectorNames) external view returns (bool, address[] memory); +} + +contract Constants is Variables { + // InstaIndex Address. + address internal constant instaIndex = 0xA9B99766E6C676Cf1975c0D3166F96C0848fF5ad; + // Migration contract Address. + address internal constant migrationContract = 0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9; + // Connnectors Address. + address public constant connectorsM1 = 0x0a0a82D2F86b9E46AE60E22FCE4e8b916F858Ddc; +} + +contract InstaImplementationM2 is Constants { + + function decodeEvent(bytes memory response) internal pure returns (string memory _eventCode, bytes memory _eventParams) { + if (response.length > 0) { + (_eventCode, _eventParams) = abi.decode(response, (string, bytes)); + } + } + + event LogCastMigrate( + address indexed origin, + address indexed sender, + uint256 value, + string[] targetsNames, + address[] targets, + string[] eventNames, + bytes[] eventParams + ); + + receive() external payable {} + + /** + * @dev Delegate the calls to Connector. + * @param _target Connector address + * @param _data CallData of function. + */ + function spell(address _target, bytes memory _data) internal returns (bytes memory response) { + require(_target != address(0), "target-invalid"); + assembly { + let succeeded := delegatecall(gas(), _target, add(_data, 0x20), mload(_data), 0, 0) + let size := returndatasize() + + response := mload(0x40) + mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + mstore(response, size) + returndatacopy(add(response, 0x20), 0, size) + + switch iszero(succeeded) + case 1 { + // throw if delegatecall failed + returndatacopy(0x00, 0x00, size) + revert(0x00, size) + } + } + } + + /** + * @dev This is the main function, Where all the different functions are called + * from Smart Account. + * @param _targetNames Array of Connector address. + * @param _datas Array of Calldata. + */ + function castMigrate( + string[] calldata _targetNames, + bytes[] calldata _datas, + address _origin + ) + external + payable + returns (bytes32) // Dummy return to fix instaIndex buildWithCast function + { + uint256 _length = _targetNames.length; + require(msg.sender == migrationContract, "2: permission-denied"); + require(_length != 0, "2: length-invalid"); + require(_length == _datas.length , "2: array-length-invalid"); + + string[] memory eventNames = new string[](_length); + bytes[] memory eventParams = new bytes[](_length); + + // TODO: restrict migration contract to run something specific? or give is all access as it doesn't have power to run anything else + (bool isOk, address[] memory _targets) = ConnectorsInterface(connectorsM1).isConnectors(_targetNames); + + require(isOk, "2: not-connector"); + + for (uint i = 0; i < _length; i++) { + bytes memory response = spell(_targets[i], _datas[i]); + (eventNames[i], eventParams[i]) = decodeEvent(response); + } + + emit LogCastMigrate( + _origin, + msg.sender, + msg.value, + _targetNames, + _targets, + eventNames, + eventParams + ); + } + +} \ No newline at end of file diff --git a/contracts/mock/aave-v2-migrator/variables.sol b/contracts/mock/aave-v2-migrator/variables.sol new file mode 100644 index 0000000..8685349 --- /dev/null +++ b/contracts/mock/aave-v2-migrator/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/contracts/receivers/aave-v2-receiver/events.sol b/contracts/receivers/aave-v2-receiver/events.sol index 4d6372e..c4a3231 100644 --- a/contracts/receivers/aave-v2-receiver/events.sol +++ b/contracts/receivers/aave-v2-receiver/events.sol @@ -27,4 +27,12 @@ contract Events { ); event LogMigrate(uint _id); + + event LogFlashLoan( + address indexed sender, + address[] tokens, + uint[] amounts, + uint[] feeAmts, + uint route + ); } \ No newline at end of file diff --git a/contracts/receivers/aave-v2-receiver/interfaces.sol b/contracts/receivers/aave-v2-receiver/interfaces.sol index 5ff7f9a..3203652 100644 --- a/contracts/receivers/aave-v2-receiver/interfaces.sol +++ b/contracts/receivers/aave-v2-receiver/interfaces.sol @@ -25,6 +25,15 @@ struct AaveData { address[] borrowTokens; } +struct CastData { + address dsa; + uint route; + address[] tokens; + uint[] amounts; + string[] dsaTargets; + bytes[] dsaData; +} + interface IndexInterface { function master() external view returns (address); } @@ -99,5 +108,9 @@ interface AaveInterface { } interface InstaListInterface { - function accountID(address) external view returns (uint); + function accountID(address) external view returns (uint64); +} + +interface DSAInterface { + function castMigrate(string[] calldata _targets, bytes[] calldata _datas, address _origin) external payable returns (bytes32); } \ No newline at end of file diff --git a/contracts/receivers/aave-v2-receiver/main.sol b/contracts/receivers/aave-v2-receiver/main.sol index caff527..30c0c4f 100644 --- a/contracts/receivers/aave-v2-receiver/main.sol +++ b/contracts/receivers/aave-v2-receiver/main.sol @@ -4,7 +4,7 @@ pragma experimental ABIEncoderV2; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { TokenInterface } from "../../common/interfaces.sol"; -import { AccountInterface, AaveData, AaveInterface, IndexInterface } from "./interfaces.sol"; +import { AccountInterface, AaveData, AaveInterface, IndexInterface, CastData, DSAInterface } from "./interfaces.sol"; import { Events } from "./events.sol"; import { Helpers } from "./helpers.sol"; @@ -126,7 +126,58 @@ contract AaveV2Migrator is MigrateResolver { } } -contract InstaAaveV2MigratorReceiverImplementation is AaveV2Migrator { +contract InstaFlash is AaveV2Migrator { + + using SafeERC20 for IERC20; + + /** + * FOR SECURITY PURPOSE + * only Smart DEFI Account can access the liquidity pool contract + */ + modifier isDSA { + uint64 id = instaList.accountID(msg.sender); + require(id != 0, "not-dsa-id"); + _; + } + + function initiateFlashLoan( + address[] calldata _tokens, + uint256[] calldata _amounts, + uint /*_route */, // no use of route but just to follow current flashloan pattern + bytes calldata data + ) external isDSA { + uint _length = _tokens.length; + require(_length == _amounts.length, "not-equal-length"); + uint[] memory iniBal = new uint[](_length); + IERC20[] memory _tokenContracts = new IERC20[](_length); + for (uint i = 0; i < _length; i++) { + _tokenContracts[i] = IERC20(_tokens[i]); + iniBal[i] = _tokenContracts[i].balanceOf(address(this)); + _tokenContracts[i].safeTransfer(msg.sender, _amounts[i]); + } + CastData memory cd; + (cd.dsa, cd.route, cd.tokens, cd.amounts, cd.dsaTargets, cd.dsaData) = abi.decode( + data, + (address, uint256, address[], uint256[], string[], bytes[]) + ); + DSAInterface(msg.sender).castMigrate(cd.dsaTargets, cd.dsaData, 0xB7fA44c2E964B6EB24893f7082Ecc08c8d0c0F87); + for (uint i = 0; i < _length; i++) { + uint _finBal = _tokenContracts[i].balanceOf(address(this)); + require(_finBal >= iniBal[i], "flashloan-not-returned"); + } + uint[] memory _feeAmts = new uint[](_length); + emit LogFlashLoan( + msg.sender, + _tokens, + _amounts, + _feeAmts, + 0 + ); + } + +} + +contract InstaAaveV2MigratorReceiverImplementation is InstaFlash { function migrate(uint _id) external { bytes memory _data = positions[_id]; diff --git a/contracts/receivers/flashloan-connector/events.sol b/contracts/receivers/flashloan-connector/events.sol new file mode 100644 index 0000000..9fc1cd4 --- /dev/null +++ b/contracts/receivers/flashloan-connector/events.sol @@ -0,0 +1,10 @@ +pragma solidity >=0.7.0; +pragma experimental ABIEncoderV2; + +contract Events { + event LogFlashBorrow(address token, uint256 tokenAmt); + event LogFlashPayback(address token, uint256 tokenAmt); + + event LogFlashMultiBorrow(address[] token, uint256[] tokenAmts); + event LogFlashMultiPayback(address[] token, uint256[] tokenAmts); +} \ No newline at end of file diff --git a/contracts/receivers/flashloan-connector/interfaces.sol b/contracts/receivers/flashloan-connector/interfaces.sol new file mode 100644 index 0000000..c191135 --- /dev/null +++ b/contracts/receivers/flashloan-connector/interfaces.sol @@ -0,0 +1,6 @@ +pragma solidity >=0.7.0; +pragma experimental ABIEncoderV2; + +interface InstaFlashV2Interface { + function initiateFlashLoan(address[] calldata tokens, uint256[] calldata amts, uint route, bytes calldata data) external; +} \ No newline at end of file diff --git a/contracts/receivers/flashloan-connector/main.sol b/contracts/receivers/flashloan-connector/main.sol new file mode 100644 index 0000000..571909d --- /dev/null +++ b/contracts/receivers/flashloan-connector/main.sol @@ -0,0 +1,118 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { TokenInterface } from "../../common/interfaces.sol"; +import { DSMath } from "../../common/math.sol"; +import { Stores } from "../../common/stores-polygon.sol"; +import { Variables } from "./variables.sol"; +import { Events } from "./events.sol"; + +contract LiquidityResolver is DSMath, Stores, Variables, Events { + using SafeERC20 for IERC20; + + /** + * @dev Borrow Flashloan and Cast spells. + * @param token Token Address. + * @param amt Token Amount. + * @param data targets & data for cast. + */ + function flashBorrowAndCast( + address token, + uint amt, + uint route, + bytes memory data + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + address[] memory tokens = new address[](1); + uint[] memory amts = new uint[](1); + tokens[0] = token; + amts[0] = amt; + + instaPool.initiateFlashLoan(tokens, amts, route, data); + + _eventName = "LogFlashBorrow(address,uint256)"; + _eventParam = abi.encode(token, amt); + } + + /** + * @dev Return token to InstaPool. + * @param token Token Address. + * @param amt Token Amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function flashPayback( + address token, + uint amt, + uint getId, + uint setId + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + uint _amt = getUint(getId, amt); + + IERC20 tokenContract = IERC20(token); + + tokenContract.safeTransfer(address(instaPool), _amt); + + setUint(setId, _amt); + + _eventName = "LogFlashPayback(address,uint256)"; + _eventParam = abi.encode(token, _amt); + } + + /** + * @dev Borrow Flashloan and Cast spells. + * @param tokens Array of token Addresses. + * @param amts Array of token Amounts. + * @param route Route to borrow. + * @param data targets & data for cast. + */ + function flashMultiBorrowAndCast( + address[] calldata tokens, + uint[] calldata amts, + uint route, + bytes calldata data + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + instaPool.initiateFlashLoan(tokens, amts, route, data); + + _eventName = "LogFlashMultiBorrow(address[],uint256[])"; + _eventParam = abi.encode(tokens, amts); + } + + /** + * @dev Return Multiple token liquidity to InstaPool. + * @param tokens Array of token addresses. + * @param amts Array of token amounts. + * @param getId get token amounts at this IDs from `InstaMemory` Contract. + * @param setId set token amounts at this IDs in `InstaMemory` Contract. + */ + function flashMultiPayback( + address[] calldata tokens, + uint[] calldata amts, + uint[] calldata getId, + uint[] calldata setId + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + uint _length = tokens.length; + + uint[] memory _amts = new uint[](_length); + + for (uint i = 0; i < _length; i++) { + uint _amt = getUint(getId[i], amts[i]); + + _amts[i] = _amt; + + IERC20 tokenContract = IERC20(tokens[i]); + + tokenContract.safeTransfer(address(instaPool), _amt); + + setUint(setId[i], _amt); + } + + _eventName = "LogFlashMultiPayback(address[],uint256[])"; + _eventParam = abi.encode(tokens, _amts); + } +} + +contract ConnectInstaPool is LiquidityResolver { + string public name = "Instapool-v1"; +} \ No newline at end of file diff --git a/contracts/receivers/flashloan-connector/variables.sol b/contracts/receivers/flashloan-connector/variables.sol new file mode 100644 index 0000000..956f260 --- /dev/null +++ b/contracts/receivers/flashloan-connector/variables.sol @@ -0,0 +1,12 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +import { InstaFlashV2Interface } from "./interfaces.sol"; + +contract Variables { + + /** + * @dev Instapool / Receiver contract proxy + */ + InstaFlashV2Interface public constant instaPool = InstaFlashV2Interface(0x4A090897f47993C2504144419751D6A91D79AbF4); +} \ No newline at end of file diff --git a/test/receiver_flashloan.test.js b/test/receiver_flashloan.test.js new file mode 100644 index 0000000..08d55e8 --- /dev/null +++ b/test/receiver_flashloan.test.js @@ -0,0 +1,234 @@ +const hre = require("hardhat"); +const { expect } = require("chai"); +const { ethers, network, waffle } = hre; +const { provider, deployContract } = waffle + +const Receiver = require("../artifacts/contracts/receivers/aave-v2-receiver/main.sol/InstaAaveV2MigratorReceiverImplementation.json") +const Implementation = require("../artifacts/contracts/mock/aave-v2-migrator/main.sol/InstaImplementationM2.json") + +describe("Receiver", function() { + let accounts, account, receiver, master, implementation + + const usdc = '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174' + const usdt = '0xc2132D05D31c914a87C6611C10748AEb04B58e8F' + const dai = '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063' + const wbtc = '0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6' + const weth = '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619' + const wmatic = '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270' + + const instaImplementations = '0x39d3d5e7c11D61E072511485878dd84711c19d4A' + + const maxValue = '115792089237316195423570985008687907853269984665640564039457584007913129639935' + + const erc20Abi = [ + "function balanceOf(address) view returns (uint)", + "function transfer(address to, uint amount)", + "function approve(address spender, uint amount)" + ] + + const instaImplementationABI = [ + "function addImplementation(address _implementation, bytes4[] calldata _sigs)", + "function getImplementation(bytes4 _sig) view returns (address)", + "function removeImplementation(address _implementation)" + ] + + const implementations_m2Sigs = ["0x5a19a5eb"] + + before(async function() { + accounts = await ethers.getSigners() + account = accounts[0] + + masterAddress = "0x31de2088f38ed7F8a4231dE03973814edA1f8773" + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [ masterAddress ] + }) + + master = ethers.provider.getSigner(masterAddress) + + receiver = await deployContract(account, Receiver, []) + implementation = await deployContract(account, Implementation, []) + + console.log("Receiver deployed: ", receiver.address) + console.log("ImplementationM2 deployed: ", implementation.address) + + await master.sendTransaction({ + to: receiver.address, + value: ethers.utils.parseEther("45400000") + }) + + const usdcHolderAddr = '0x986a2fCa9eDa0e06fBf7839B89BfC006eE2a23Dd' // 1,000,000 + await account.sendTransaction({ to: usdcHolderAddr, value: ethers.utils.parseEther('1') }) + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [ usdcHolderAddr ] + }) + const usdcHolder = ethers.provider.getSigner(usdcHolderAddr) + const usdcContract = new ethers.Contract(usdc, erc20Abi, usdcHolder) + await usdcContract.transfer(receiver.address, ethers.utils.parseUnits('1000000', 6)) + + const daiHolderAddr = '0x7A61A0Ed364E599Ae4748D1EbE74bf236Dd27B09' // 300,000 + await accounts[0].sendTransaction({ to: daiHolderAddr, value: ethers.utils.parseEther('1') }) + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [ daiHolderAddr ] + }) + const daiHolder = ethers.provider.getSigner(daiHolderAddr) + const daiContract = new ethers.Contract(dai, erc20Abi, daiHolder) + await daiContract.transfer(receiver.address, ethers.utils.parseUnits('10000', 18)) + }) + + // it("should change the implementation", async function() { + // const funder = await deployContract(master, Funder, []) + // await master.sendTransaction({ + // to: funder.address, + // value: ethers.utils.parseEther("10") + // }) + + // await funder.kill() + + // const proxyAbi = [ + // "function upgradeTo(address newImplementation)" + // ] + + // const masterProxyAddr = '0x697860CeE594c577F18f71cAf3d8B68D913c7366' + // const masterProxySigner = ethers.provider.getSigner(masterProxyAddr) + + // const receiverProxy = '0x4A090897f47993C2504144419751D6A91D79AbF4' + // const receiverProxyContract = new ethers.Contract(receiverProxy, proxyAbi, masterProxySigner) + + // await receiverProxyContract.upgradeTo(receiver.address) + // }) + + it("should match matic receiver", async function() { + const maticReceiver = await receiver.maticReceiver() + + expect(maticReceiver).to.be.equal('0x0000000000000000000000000000000000001001') + }) + + it("should set implementationsM2", async function() { + + const instaImplementationsContract = new ethers.Contract(instaImplementations, instaImplementationABI, master) + await instaImplementationsContract.connect(master).removeImplementation('0xEAac5739eB532110431b14D01017506DBA8f7b07') + await instaImplementationsContract.connect(master).addImplementation(implementation.address, implementations_m2Sigs) + }) + + it("Should not flashloan non-dsa address", async function() { + const eoaAddr = '0xA35f3FEFEcb5160327d1B6A210b60D1e1d7968e3' + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [ eoaAddr ] + }) + + const eoaSigner = ethers.provider.getSigner(eoaAddr) + + await expect(receiver.connect(eoaSigner).initiateFlashLoan( + [usdc], + [ethers.utils.parseUnits('1000', 6)], + 0, + '0x' + )).to.be.revertedWith('not-dsa-id') + }) + + it("single token flashloan", async function() { + const dsaAddr = '0x150Acc42e6751776c9E784EfF830cB4f35aE98f3' + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [ dsaAddr ] + }) + + const dsaSigner = ethers.provider.getSigner(dsaAddr) + + const aave = new ethers.utils.Interface([ + 'function deposit(address,uint256,uint256,uint256)', + 'function withdraw(address,uint256,uint256,uint256)' + ]) + + const basic = new ethers.utils.Interface([ + 'function withdraw(address,uint256,address,uint256,uint256)' + ]) + + const abiCoder = ethers.utils.defaultAbiCoder + + const abiData = abiCoder.encode( + ['address', 'uint256', 'address[]', 'uint256[]', 'string[]', 'bytes[]'], + [ + dsaAddr, + 0, + [usdc], + [ethers.utils.parseUnits('1000', 6)], + ['AAVE-V2-A', 'AAVE-V2-A', 'BASIC-A'], + [ + aave.encodeFunctionData('deposit', [usdc, ethers.utils.parseUnits('1000', 6), 0, 0]), + aave.encodeFunctionData('withdraw', [usdc, ethers.utils.parseUnits('1000', 6), 0, 0]), + basic.encodeFunctionData('withdraw', [usdc, ethers.utils.parseUnits('1000', 6), receiver.address, 0, 0]) + ] + ] + ) + + // console.log('abiData', abiData) + + const tx = await receiver.connect(dsaSigner).initiateFlashLoan( + [usdc], + [ethers.utils.parseUnits('1000', 6)], + 0, + abiData + ) + + await tx.wait() + }) + + it("multi token flashloan", async function() { + const dsaAddr = '0x150Acc42e6751776c9E784EfF830cB4f35aE98f3' + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [ dsaAddr ] + }) + + const dsaSigner = ethers.provider.getSigner(dsaAddr) + + const aave = new ethers.utils.Interface([ + 'function deposit(address,uint256,uint256,uint256)', + 'function withdraw(address,uint256,uint256,uint256)' + ]) + + const basic = new ethers.utils.Interface([ + 'function withdraw(address,uint256,address,uint256,uint256)' + ]) + + const abiCoder = ethers.utils.defaultAbiCoder + + const abiData = abiCoder.encode( + ['address', 'uint256', 'address[]', 'uint256[]', 'string[]', 'bytes[]'], + [ + dsaAddr, + 0, + [usdc, dai], + [ethers.utils.parseUnits('1000', 6), ethers.utils.parseEther('5000')], + ['AAVE-V2-A', 'AAVE-V2-A', 'AAVE-V2-A', 'AAVE-V2-A', 'BASIC-A', 'BASIC-A'], + [ + aave.encodeFunctionData('deposit', [usdc, ethers.utils.parseUnits('1000', 6), 0, 0]), + aave.encodeFunctionData('deposit', [dai, ethers.utils.parseEther('5000'), 0, 0]), + aave.encodeFunctionData('withdraw', [usdc, ethers.utils.parseUnits('1000', 6), 0, 0]), + aave.encodeFunctionData('withdraw', [dai, ethers.utils.parseEther('5000'), 0, 0]), + basic.encodeFunctionData('withdraw', [usdc, ethers.utils.parseUnits('1000', 6), receiver.address, 0, 0]), + basic.encodeFunctionData('withdraw', [dai, ethers.utils.parseEther('5000'), receiver.address, 0, 0]) + ] + ] + ) + + // console.log('abiData', abiData) + + const tx = await receiver.connect(dsaSigner).initiateFlashLoan( + [usdc, dai], + [ethers.utils.parseUnits('1000', 6), ethers.utils.parseEther('5000')], + 0, + abiData + ) + + await tx.wait() + }) +}) \ No newline at end of file diff --git a/test/receiver_l2.test.js b/test/receiver_l2.test.js index 0e7fa1d..f2d05d3 100644 --- a/test/receiver_l2.test.js +++ b/test/receiver_l2.test.js @@ -5,7 +5,8 @@ const { provider, deployContract } = waffle const Migrator = require("../artifacts/contracts/receivers/aave-v2-receiver/main.sol/InstaAaveV2MigratorReceiverImplementation.json") const TokenMappingContract = require("../artifacts/contracts/receivers/mapping/main.sol/InstaPolygonTokenMapping.json") -const Implementations_m2Contract = require("../artifacts/contracts/implementation/aave-v2-migrator/main.sol/InstaImplementationM1.json") +const Implementations_m2Contract = require("../artifacts/contracts/implementation/aave-v2-migrator/main.sol/InstaImplementationM2.json") +const Funder = require("../artifacts/contracts/mock/funder.sol/Funder.json"); const tokenMaps = { // polygon address : main net address @@ -21,7 +22,7 @@ const tokenMaps = { // describe("Migrator", function() { - let accounts, masterAddress, master, migrator, ethereum, instapool, tokenMapping, implementations_m2Contract + let accounts, masterAddress, master, migrator, ethereum, instapool, tokenMapping, receiverSigner const erc20Abi = [ "function balanceOf(address) view returns (uint)", @@ -47,6 +48,8 @@ describe("Migrator", function() { const instaConnectorsV2 = '0x0a0a82D2F86b9E46AE60E22FCE4e8b916F858Ddc' const instaImplementations = '0x39d3d5e7c11D61E072511485878dd84711c19d4A' + + const receiverMsgSender = '0x0000000000000000000000000000000000001001' const maxValue = '115792089237316195423570985008687907853269984665640564039457584007913129639935' @@ -60,19 +63,26 @@ describe("Migrator", function() { params: [ masterAddress ] }) + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [ receiverMsgSender ] + }) + accounts = await ethers.getSigners(); master = ethers.provider.getSigner(masterAddress) + receiverSigner = ethers.provider.getSigner(receiverMsgSender) + migrator = await deployContract(master, Migrator, []) // instapool = await deployContract(master, InstaPool, []) tokenMapping = await deployContract(master, TokenMappingContract, [Object.values(tokenMaps), Object.keys(tokenMaps)]) console.log("Migrator deployed: ", migrator.address) - implementations_m2Contract = await deployContract(master, Implementations_m2Contract, [instaConnectorsV2, migrator.address]) + // implementations_m2Contract = await deployContract(master, Implementations_m2Contract, []) console.log("Migrator deployed: ", migrator.address) console.log("tokenMapping deployed: ", tokenMapping.address) - console.log("implementations_m2Contract deployed: ", implementations_m2Contract.address) + // console.log("implementations_m2Contract deployed: ", implementations_m2Contract.address) await master.sendTransaction({ to: migrator.address, @@ -81,11 +91,11 @@ describe("Migrator", function() { ethereum = network.provider }) - it("should set implementationsV2", async function() { + // it("should set implementationsV2", async function() { - const instaImplementationsContract = new ethers.Contract(instaImplementations, instaImplementationABI, master) - await instaImplementationsContract.connect(master).addImplementation(implementations_m2Contract.address, implementations_m2Sigs) - }) + // const instaImplementationsContract = new ethers.Contract(instaImplementations, instaImplementationABI, master) + // await instaImplementationsContract.connect(master).addImplementation(implementations_m2Contract.address, implementations_m2Sigs) + // }) it("should set tokens", async function() { const tx = await migrator.connect(master).addTokenSupport([...Object.keys(tokenMaps).slice(1, 3), "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"]) @@ -95,8 +105,17 @@ describe("Migrator", function() { expect(isMatic).to.be.true; }) + it("fund receiver data setter", async function() { + const funder = await deployContract(master, Funder, []) + await master.sendTransaction({ + to: funder.address, + value: ethers.utils.parseEther("1") + }); + await funder.kill() + }) + it("should set data", async function() { - const tx = await migrator.onStateReceive("345", migrateData) + const tx = await migrator.connect(receiverSigner).onStateReceive("345", migrateData) const receipt = await tx.wait() const _migrateData = await migrator.positions("345") @@ -226,7 +245,7 @@ describe("Migrator", function() { it("test migrate 2", async function() { const positionData = '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000150acc42e6751776c9e784eff830cb4f35ae98f300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000056900d33ca7fc0000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000004a817c80000000000000000000000000000000000000000000000000000000004a817c800000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000003000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000006b175474e89094c44da98b954eedeac495271d0f' - let tx = await migrator.onStateReceive("346", positionData) + let tx = await migrator.connect(receiverSigner).onStateReceive("346", positionData) await tx.wait() tx = await migrator.migrate("346") @@ -242,7 +261,7 @@ describe("Migrator", function() { it("test migrate 3", async function() { const positionData = '0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000032d99500f7621c6dc5391395d419236383dbff9700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000361a08405e8fd8000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000df847580000000000000000000000000000000000000000000000000000000009502f90000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7' - let tx = await migrator.onStateReceive("347", positionData) + let tx = await migrator.connect(receiverSigner).onStateReceive("347", positionData) await tx.wait() tx = await migrator.migrate("347") @@ -258,7 +277,7 @@ describe("Migrator", function() { it("test migrate 4", async function() { const positionData = '0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000029601161ad5da8c54435f4065af3a0ee30cb24dd00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000d86821017a3f60000000000000000000000000000000000000000000000000000000000000b274d080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000574fbde60000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' - let tx = await migrator.onStateReceive("348", positionData) + let tx = await migrator.connect(receiverSigner).onStateReceive("348", positionData) await tx.wait() tx = await migrator.migrate("348")