From 1338e6f5c92674c926e63ea3b71e15db52e8f250 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Sat, 7 May 2022 01:54:51 +0400 Subject: [PATCH 01/20] update transfer fee --- contracts/aggregator/mainnet/flashloan/main.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/aggregator/mainnet/flashloan/main.sol b/contracts/aggregator/mainnet/flashloan/main.sol index 4c66f5d3..d0a713e3 100644 --- a/contracts/aggregator/mainnet/flashloan/main.sol +++ b/contracts/aggregator/mainnet/flashloan/main.sol @@ -673,7 +673,7 @@ contract FlashAggregator is Setups { * @notice Function to transfer fee to the treasury. Will be called manually. * @param _tokens token addresses for transferring fee to treasury. */ - function transferFeeToTreasury(address[] memory _tokens) public { + function transferFee(address[] memory _tokens, address _to) public onlyOwner { for (uint256 i = 0; i < _tokens.length; i++) { IERC20 token_ = IERC20(_tokens[i]); uint256 decimals_ = TokenInterface(_tokens[i]).decimals(); @@ -686,7 +686,7 @@ contract FlashAggregator is Setups { ? (token_.balanceOf(address(this)) - amtToSub_) : 0; if (amtToTransfer_ > 0) - token_.safeTransfer(treasuryAddr, amtToTransfer_); + token_.safeTransfer(_to, amtToTransfer_); } } } From 0f4be4088c2f8d597ab3b1ab2de940c4e569c838 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Sat, 7 May 2022 03:02:23 +0400 Subject: [PATCH 02/20] added event --- contracts/aggregator/mainnet/flashloan/main.sol | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/contracts/aggregator/mainnet/flashloan/main.sol b/contracts/aggregator/mainnet/flashloan/main.sol index d0a713e3..7b751da1 100644 --- a/contracts/aggregator/mainnet/flashloan/main.sol +++ b/contracts/aggregator/mainnet/flashloan/main.sol @@ -82,6 +82,12 @@ contract FlashAggregator is Setups { uint256[] amounts ); + event LogCollectRevenue( + address to, + address[] tokens, + uint256[] amounts + ); + /** * @dev Callback function for aave flashloan. * @notice Callback function for aave flashloan. @@ -674,6 +680,7 @@ contract FlashAggregator is Setups { * @param _tokens token addresses for transferring fee to treasury. */ function transferFee(address[] memory _tokens, address _to) public onlyOwner { + uint256[] memory _amts = new uint256[](_tokens.length); for (uint256 i = 0; i < _tokens.length; i++) { IERC20 token_ = IERC20(_tokens[i]); uint256 decimals_ = TokenInterface(_tokens[i]).decimals(); @@ -682,12 +689,13 @@ contract FlashAggregator is Setups { : decimals_ > 7 ? 100 : 10; - uint256 amtToTransfer_ = token_.balanceOf(address(this)) > amtToSub_ + _amts[i] = token_.balanceOf(address(this)) > amtToSub_ ? (token_.balanceOf(address(this)) - amtToSub_) : 0; - if (amtToTransfer_ > 0) - token_.safeTransfer(_to, amtToTransfer_); + if (_amts[i] > 0) + token_.safeTransfer(_to, _amts[i]); } + emit LogCollectRevenue(_to, _tokens, _amts); } } From e0996b5c2e0b91ae45564e62473b4b9a33d6fbcd Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Mon, 9 May 2022 20:44:00 +0400 Subject: [PATCH 03/20] Implementations created --- contracts/ProxyAave/main.sol | 101 +++++ contracts/ProxyBalancer/main.sol | 243 +++++++++++ contracts/ProxyMaker/main.sol | 205 +++++++++ .../aggregator/mainnet/flashloan/helpers.sol | 25 ++ .../aggregator/mainnet/flashloan/main.sol | 408 +----------------- .../mainnet/flashloan/variables.sol | 6 + test/mainnet/newFlashAggr.ts | 126 ++++++ 7 files changed, 729 insertions(+), 385 deletions(-) create mode 100644 contracts/ProxyAave/main.sol create mode 100644 contracts/ProxyBalancer/main.sol create mode 100644 contracts/ProxyMaker/main.sol create mode 100644 test/mainnet/newFlashAggr.ts diff --git a/contracts/ProxyAave/main.sol b/contracts/ProxyAave/main.sol new file mode 100644 index 00000000..7e9abab5 --- /dev/null +++ b/contracts/ProxyAave/main.sol @@ -0,0 +1,101 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; +import "../aggregator/mainnet/flashloan/helpers.sol"; + +contract AaveImplementation is Helper { + + /** + * @dev Callback function for aave flashloan. + * @notice Callback function for aave flashloan. + * @param _assets list of asset addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets for flashloan. + * @param _premiums list of premiums/fees for the corresponding addresses for flashloan. + * @param _initiator initiator address for flashloan. + * @param _data extra data passed. + */ + function executeOperation( + address[] memory _assets, + uint256[] memory _amounts, + uint256[] memory _premiums, + address _initiator, + bytes memory _data + ) external verifyDataHash(_data) returns (bool) { + require(_initiator == address(this), "not-same-sender"); + require(msg.sender == address(aaveLending), "not-aave-sender"); + + FlashloanVariables memory instaLoanVariables_; + + (address sender_, bytes memory data_) = abi.decode( + _data, + (address, bytes) + ); + + instaLoanVariables_._tokens = _assets; + instaLoanVariables_._amounts = _amounts; + instaLoanVariables_._instaFees = calculateFees( + _amounts, + calculateFeeBPS(1, sender_) + ); + instaLoanVariables_._iniBals = calculateBalances( + _assets, + address(this) + ); + + safeApprove(instaLoanVariables_, _premiums, address(aaveLending)); + safeTransfer(instaLoanVariables_, sender_); + + if (checkIfDsa(sender_)) { + Address.functionCall( + sender_, + data_, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(sender_).executeOperation( + _assets, + _amounts, + instaLoanVariables_._instaFees, + sender_, + data_ + ); + } + + instaLoanVariables_._finBals = calculateBalances( + _assets, + address(this) + ); + validateFlashloan(instaLoanVariables_); + + return true; + } + + /** + * @dev Middle function for route 1. + * @notice Middle function for route 1. + * @param _tokens list of token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets or amount of ether to borrow as collateral for flashloan. + * @param _data extra data passed. + */ + function routeAave( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + bytes memory data_ = abi.encode(msg.sender, _data); + uint256 length_ = _tokens.length; + uint256[] memory _modes = new uint256[](length_); + for (uint256 i = 0; i < length_; i++) { + _modes[i] = 0; + } + dataHash = bytes32(keccak256(data_)); + aaveLending.flashLoan( + address(this), + _tokens, + _amounts, + _modes, + address(0), + data_, + 3228 + ); + } +} \ No newline at end of file diff --git a/contracts/ProxyBalancer/main.sol b/contracts/ProxyBalancer/main.sol new file mode 100644 index 00000000..0bec320f --- /dev/null +++ b/contracts/ProxyBalancer/main.sol @@ -0,0 +1,243 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; +import "../aggregator/mainnet/flashloan/helpers.sol"; + +contract BalancerImplementation is Helper { + + /** + * @dev Fallback function for balancer flashloan. + * @notice Fallback function for balancer flashloan. + * @param _amounts list of amounts for the corresponding assets or amount of ether to borrow as collateral for flashloan. + * @param _fees list of fees for the corresponding addresses for flashloan. + * @param _data extra data passed(includes route info aswell). + */ + function receiveFlashLoan( + IERC20[] memory, + uint256[] memory _amounts, + uint256[] memory _fees, + bytes memory _data + ) external verifyDataHash(_data) { + require(msg.sender == address(balancerLending), "not-balancer-sender"); + + FlashloanVariables memory instaLoanVariables_; + + ( + uint256 route_, + address[] memory tokens_, + uint256[] memory amounts_, + address sender_, + bytes memory data_ + ) = abi.decode(_data, (uint256, address[], uint256[], address, bytes)); + + instaLoanVariables_._tokens = tokens_; + instaLoanVariables_._amounts = amounts_; + instaLoanVariables_._iniBals = calculateBalances( + tokens_, + address(this) + ); + instaLoanVariables_._instaFees = calculateFees( + amounts_, + calculateFeeBPS(route_, sender_) + ); + + if (route_ == 5) { + if (tokens_[0] == stEthTokenAddr) { + wstEthToken.unwrap(_amounts[0]); + } + safeTransfer(instaLoanVariables_, sender_); + if (checkIfDsa(sender_)) { + Address.functionCall( + sender_, + data_, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(sender_).executeOperation( + tokens_, + amounts_, + instaLoanVariables_._instaFees, + sender_, + data_ + ); + } + if (tokens_[0] == stEthTokenAddr) { + wstEthToken.wrap(amounts_[0]); + } + + instaLoanVariables_._finBals = calculateBalances( + tokens_, + address(this) + ); + if (tokens_[0] == stEthTokenAddr) { + // adding 10 wei to avoid any possible decimal errors in final calculations + instaLoanVariables_._finBals[0] = + instaLoanVariables_._finBals[0] + + 10; + instaLoanVariables_._tokens[0] = address(wstEthToken); + instaLoanVariables_._amounts[0] = _amounts[0]; + } + validateFlashloan(instaLoanVariables_); + safeTransferWithFee( + instaLoanVariables_, + _fees, + address(balancerLending) + ); + } else if (route_ == 6 || route_ == 7) { + require(_fees[0] == 0, "flash-ETH-fee-not-0"); + + address[] memory wEthTokenList = new address[](1); + wEthTokenList[0] = address(wethToken); + + if (route_ == 6) { + compoundSupply(wEthTokenList, _amounts); + compoundBorrow(tokens_, amounts_); + } else { + aaveSupply(wEthTokenList, _amounts); + aaveBorrow(tokens_, amounts_); + } + + safeTransfer(instaLoanVariables_, sender_); + + if (checkIfDsa(sender_)) { + Address.functionCall( + sender_, + data_, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(sender_).executeOperation( + tokens_, + amounts_, + instaLoanVariables_._instaFees, + sender_, + data_ + ); + } + + if (route_ == 6) { + compoundPayback(tokens_, amounts_); + compoundWithdraw(wEthTokenList, _amounts); + } else { + aavePayback(tokens_, amounts_); + aaveWithdraw(wEthTokenList, _amounts); + } + instaLoanVariables_._finBals = calculateBalances( + tokens_, + address(this) + ); + validateFlashloan(instaLoanVariables_); + instaLoanVariables_._tokens = wEthTokenList; + instaLoanVariables_._amounts = _amounts; + safeTransferWithFee( + instaLoanVariables_, + _fees, + address(balancerLending) + ); + } else { + revert("wrong-route"); + } + } + + /** + * @dev Middle function for route 5. + * @notice Middle function for route 5. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + */ + function routeBalancer( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + uint256 length_ = _tokens.length; + IERC20[] memory tokens_ = new IERC20[](length_); + for (uint256 i = 0; i < length_; i++) { + tokens_[i] = IERC20(_tokens[i]); + } + bytes memory data_ = abi.encode( + 5, + _tokens, + _amounts, + msg.sender, + _data + ); + dataHash = bytes32(keccak256(data_)); + if (_tokens[0] == stEthTokenAddr) { + require(length_ == 1, "steth-length-should-be-1"); + tokens_[0] = IERC20(address(wstEthToken)); + _amounts[0] = wstEthToken.getWstETHByStETH(_amounts[0]); + } + balancerLending.flashLoan( + InstaFlashReceiverInterface(address(this)), + tokens_, + _amounts, + data_ + ); + } + + /** + * @dev Middle function for route 6. + * @notice Middle function for route 6. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + */ + function routeBalancerCompound( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + bytes memory data_ = abi.encode( + 6, + _tokens, + _amounts, + msg.sender, + _data + ); + IERC20[] memory wethTokenList_ = new IERC20[](1); + uint256[] memory wethAmountList_ = new uint256[](1); + wethTokenList_[0] = IERC20(wethToken); + wethAmountList_[0] = getWEthBorrowAmount(); + dataHash = bytes32(keccak256(data_)); + balancerLending.flashLoan( + InstaFlashReceiverInterface(address(this)), + wethTokenList_, + wethAmountList_, + data_ + ); + } + + /** + * @dev Middle function for route 7. + * @notice Middle function for route 7. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + */ + function routeBalancerAave( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + bytes memory data_ = abi.encode( + 7, + _tokens, + _amounts, + msg.sender, + _data + ); + IERC20[] memory wethTokenList_ = new IERC20[](1); + uint256[] memory wethAmountList_ = new uint256[](1); + wethTokenList_[0] = wethToken; + wethAmountList_[0] = getWEthBorrowAmount(); + dataHash = bytes32(keccak256(data_)); + balancerLending.flashLoan( + InstaFlashReceiverInterface(address(this)), + wethTokenList_, + wethAmountList_, + data_ + ); + } + +} \ No newline at end of file diff --git a/contracts/ProxyMaker/main.sol b/contracts/ProxyMaker/main.sol new file mode 100644 index 00000000..252e97ad --- /dev/null +++ b/contracts/ProxyMaker/main.sol @@ -0,0 +1,205 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; +import "../aggregator/mainnet/flashloan/helpers.sol"; + +contract MakerImplementation is Helper { + + /** + * @dev Fallback function for makerdao flashloan. + * @notice Fallback function for makerdao flashloan. + * @param _initiator initiator address for flashloan. + * @param _amount DAI amount for flashloan. + * @param _fee fee for the flashloan. + * @param _data extra data passed(includes route info aswell). + */ + function onFlashLoan( + address _initiator, + address, + uint256 _amount, + uint256 _fee, + bytes calldata _data + ) external verifyDataHash(_data) returns (bytes32) { + require(_initiator == address(this), "not-same-sender"); + require(msg.sender == address(makerLending), "not-maker-sender"); + + FlashloanVariables memory instaLoanVariables_; + + ( + uint256 route_, + address[] memory tokens_, + uint256[] memory amounts_, + address sender_, + bytes memory data_ + ) = abi.decode(_data, (uint256, address[], uint256[], address, bytes)); + + instaLoanVariables_._tokens = tokens_; + instaLoanVariables_._amounts = amounts_; + instaLoanVariables_._iniBals = calculateBalances( + tokens_, + address(this) + ); + instaLoanVariables_._instaFees = calculateFees( + amounts_, + calculateFeeBPS(route_, sender_) + ); + + if (route_ == 2) { + safeTransfer(instaLoanVariables_, sender_); + + if (checkIfDsa(sender_)) { + Address.functionCall( + sender_, + data_, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(sender_).executeOperation( + tokens_, + amounts_, + instaLoanVariables_._instaFees, + sender_, + data_ + ); + } + } else if (route_ == 3 || route_ == 4) { + require(_fee == 0, "flash-DAI-fee-not-0"); + + address[] memory _daiTokenList = new address[](1); + uint256[] memory _daiTokenAmountsList = new uint256[](1); + _daiTokenList[0] = daiTokenAddr; + _daiTokenAmountsList[0] = _amount; + + if (route_ == 3) { + compoundSupply(_daiTokenList, _daiTokenAmountsList); + compoundBorrow(tokens_, amounts_); + } else { + aaveSupply(_daiTokenList, _daiTokenAmountsList); + aaveBorrow(tokens_, amounts_); + } + + safeTransfer(instaLoanVariables_, sender_); + + if (checkIfDsa(sender_)) { + Address.functionCall( + sender_, + data_, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(sender_).executeOperation( + tokens_, + amounts_, + instaLoanVariables_._instaFees, + sender_, + data_ + ); + } + + if (route_ == 3) { + compoundPayback(tokens_, amounts_); + compoundWithdraw(_daiTokenList, _daiTokenAmountsList); + } else { + aavePayback(tokens_, amounts_); + aaveWithdraw(_daiTokenList, _daiTokenAmountsList); + } + } else { + revert("wrong-route"); + } + + instaLoanVariables_._finBals = calculateBalances( + tokens_, + address(this) + ); + validateFlashloan(instaLoanVariables_); + + return keccak256("ERC3156FlashBorrower.onFlashLoan"); + } + + /** + * @dev Middle function for route 2. + * @notice Middle function for route 2. + * @param _token token address for flashloan(DAI). + * @param _amount DAI amount for flashloan. + * @param _data extra data passed. + */ + function routeMaker( + address _token, + uint256 _amount, + bytes memory _data + ) internal { + address[] memory tokens_ = new address[](1); + uint256[] memory amounts_ = new uint256[](1); + tokens_[0] = _token; + amounts_[0] = _amount; + bytes memory data_ = abi.encode( + 2, + tokens_, + amounts_, + msg.sender, + _data + ); + dataHash = bytes32(keccak256(data_)); + makerLending.flashLoan( + InstaFlashReceiverInterface(address(this)), + _token, + _amount, + data_ + ); + } + + /** + * @dev Middle function for route 3. + * @notice Middle function for route 3. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + */ + function routeMakerCompound( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + bytes memory data_ = abi.encode( + 3, + _tokens, + _amounts, + msg.sender, + _data + ); + dataHash = bytes32(keccak256(data_)); + makerLending.flashLoan( + InstaFlashReceiverInterface(address(this)), + daiTokenAddr, + daiBorrowAmount, + data_ + ); + } + + /** + * @dev Middle function for route 4. + * @notice Middle function for route 4. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + */ + function routeMakerAave( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + bytes memory data_ = abi.encode( + 4, + _tokens, + _amounts, + msg.sender, + _data + ); + dataHash = bytes32(keccak256(data_)); + makerLending.flashLoan( + InstaFlashReceiverInterface(address(this)), + daiTokenAddr, + daiBorrowAmount, + data_ + ); + } +} \ No newline at end of file diff --git a/contracts/aggregator/mainnet/flashloan/helpers.sol b/contracts/aggregator/mainnet/flashloan/helpers.sol index ddf5369e..3b53b13a 100644 --- a/contracts/aggregator/mainnet/flashloan/helpers.sol +++ b/contracts/aggregator/mainnet/flashloan/helpers.sol @@ -7,6 +7,31 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract Helper is Variables { using SafeERC20 for IERC20; + /** + * @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 Approves the token to the spender address with allowance amount. * @notice Approves the token to the spender address with allowance amount. diff --git a/contracts/aggregator/mainnet/flashloan/main.sol b/contracts/aggregator/mainnet/flashloan/main.sol index 7b751da1..2b7d3119 100644 --- a/contracts/aggregator/mainnet/flashloan/main.sol +++ b/contracts/aggregator/mainnet/flashloan/main.sol @@ -7,6 +7,7 @@ pragma solidity ^0.8.0; */ import "./helpers.sol"; +import "hardhat/console.sol"; import "@openzeppelin/contracts/utils/Address.sol"; contract AdminModule is Helper { @@ -103,54 +104,9 @@ contract FlashAggregator is Setups { uint256[] memory _premiums, address _initiator, bytes memory _data - ) external verifyDataHash(_data) returns (bool) { - require(_initiator == address(this), "not-same-sender"); - require(msg.sender == address(aaveLending), "not-aave-sender"); - - FlashloanVariables memory instaLoanVariables_; - - (address sender_, bytes memory data_) = abi.decode( - _data, - (address, bytes) - ); - - instaLoanVariables_._tokens = _assets; - instaLoanVariables_._amounts = _amounts; - instaLoanVariables_._instaFees = calculateFees( - _amounts, - calculateFeeBPS(1, sender_) - ); - instaLoanVariables_._iniBals = calculateBalances( - _assets, - address(this) - ); - - safeApprove(instaLoanVariables_, _premiums, address(aaveLending)); - safeTransfer(instaLoanVariables_, sender_); - - if (checkIfDsa(sender_)) { - Address.functionCall( - sender_, - data_, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(sender_).executeOperation( - _assets, - _amounts, - instaLoanVariables_._instaFees, - sender_, - data_ - ); - } - - instaLoanVariables_._finBals = calculateBalances( - _assets, - address(this) - ); - validateFlashloan(instaLoanVariables_); - - return true; + ) external returns (bool) { + bytes memory response = spell(AAVE_PROXY, msg.data); + return (abi.decode(response, (bool))); } /** @@ -167,101 +123,9 @@ contract FlashAggregator is Setups { uint256 _amount, uint256 _fee, bytes calldata _data - ) external verifyDataHash(_data) returns (bytes32) { - require(_initiator == address(this), "not-same-sender"); - require(msg.sender == address(makerLending), "not-maker-sender"); - - FlashloanVariables memory instaLoanVariables_; - - ( - uint256 route_, - address[] memory tokens_, - uint256[] memory amounts_, - address sender_, - bytes memory data_ - ) = abi.decode(_data, (uint256, address[], uint256[], address, bytes)); - - instaLoanVariables_._tokens = tokens_; - instaLoanVariables_._amounts = amounts_; - instaLoanVariables_._iniBals = calculateBalances( - tokens_, - address(this) - ); - instaLoanVariables_._instaFees = calculateFees( - amounts_, - calculateFeeBPS(route_, sender_) - ); - - if (route_ == 2) { - safeTransfer(instaLoanVariables_, sender_); - - if (checkIfDsa(sender_)) { - Address.functionCall( - sender_, - data_, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(sender_).executeOperation( - tokens_, - amounts_, - instaLoanVariables_._instaFees, - sender_, - data_ - ); - } - } else if (route_ == 3 || route_ == 4) { - require(_fee == 0, "flash-DAI-fee-not-0"); - - address[] memory _daiTokenList = new address[](1); - uint256[] memory _daiTokenAmountsList = new uint256[](1); - _daiTokenList[0] = daiTokenAddr; - _daiTokenAmountsList[0] = _amount; - - if (route_ == 3) { - compoundSupply(_daiTokenList, _daiTokenAmountsList); - compoundBorrow(tokens_, amounts_); - } else { - aaveSupply(_daiTokenList, _daiTokenAmountsList); - aaveBorrow(tokens_, amounts_); - } - - safeTransfer(instaLoanVariables_, sender_); - - if (checkIfDsa(sender_)) { - Address.functionCall( - sender_, - data_, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(sender_).executeOperation( - tokens_, - amounts_, - instaLoanVariables_._instaFees, - sender_, - data_ - ); - } - - if (route_ == 3) { - compoundPayback(tokens_, amounts_); - compoundWithdraw(_daiTokenList, _daiTokenAmountsList); - } else { - aavePayback(tokens_, amounts_); - aaveWithdraw(_daiTokenList, _daiTokenAmountsList); - } - } else { - revert("wrong-route"); - } - - instaLoanVariables_._finBals = calculateBalances( - tokens_, - address(this) - ); - validateFlashloan(instaLoanVariables_); - - return keccak256("ERC3156FlashBorrower.onFlashLoan"); + ) external returns (bytes32) { + bytes memory response = spell(MAKER_PROXY, msg.data); + return (abi.decode(response, (bytes32))); } /** @@ -276,126 +140,8 @@ contract FlashAggregator is Setups { uint256[] memory _amounts, uint256[] memory _fees, bytes memory _data - ) external verifyDataHash(_data) { - require(msg.sender == address(balancerLending), "not-balancer-sender"); - - FlashloanVariables memory instaLoanVariables_; - - ( - uint256 route_, - address[] memory tokens_, - uint256[] memory amounts_, - address sender_, - bytes memory data_ - ) = abi.decode(_data, (uint256, address[], uint256[], address, bytes)); - - instaLoanVariables_._tokens = tokens_; - instaLoanVariables_._amounts = amounts_; - instaLoanVariables_._iniBals = calculateBalances( - tokens_, - address(this) - ); - instaLoanVariables_._instaFees = calculateFees( - amounts_, - calculateFeeBPS(route_, sender_) - ); - - if (route_ == 5) { - if (tokens_[0] == stEthTokenAddr) { - wstEthToken.unwrap(_amounts[0]); - } - safeTransfer(instaLoanVariables_, sender_); - if (checkIfDsa(sender_)) { - Address.functionCall( - sender_, - data_, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(sender_).executeOperation( - tokens_, - amounts_, - instaLoanVariables_._instaFees, - sender_, - data_ - ); - } - if (tokens_[0] == stEthTokenAddr) { - wstEthToken.wrap(amounts_[0]); - } - - instaLoanVariables_._finBals = calculateBalances( - tokens_, - address(this) - ); - if (tokens_[0] == stEthTokenAddr) { - // adding 10 wei to avoid any possible decimal errors in final calculations - instaLoanVariables_._finBals[0] = - instaLoanVariables_._finBals[0] + - 10; - instaLoanVariables_._tokens[0] = address(wstEthToken); - instaLoanVariables_._amounts[0] = _amounts[0]; - } - validateFlashloan(instaLoanVariables_); - safeTransferWithFee( - instaLoanVariables_, - _fees, - address(balancerLending) - ); - } else if (route_ == 6 || route_ == 7) { - require(_fees[0] == 0, "flash-ETH-fee-not-0"); - - address[] memory wEthTokenList = new address[](1); - wEthTokenList[0] = address(wethToken); - - if (route_ == 6) { - compoundSupply(wEthTokenList, _amounts); - compoundBorrow(tokens_, amounts_); - } else { - aaveSupply(wEthTokenList, _amounts); - aaveBorrow(tokens_, amounts_); - } - - safeTransfer(instaLoanVariables_, sender_); - - if (checkIfDsa(sender_)) { - Address.functionCall( - sender_, - data_, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(sender_).executeOperation( - tokens_, - amounts_, - instaLoanVariables_._instaFees, - sender_, - data_ - ); - } - - if (route_ == 6) { - compoundPayback(tokens_, amounts_); - compoundWithdraw(wEthTokenList, _amounts); - } else { - aavePayback(tokens_, amounts_); - aaveWithdraw(wEthTokenList, _amounts); - } - instaLoanVariables_._finBals = calculateBalances( - tokens_, - address(this) - ); - validateFlashloan(instaLoanVariables_); - instaLoanVariables_._tokens = wEthTokenList; - instaLoanVariables_._amounts = _amounts; - safeTransferWithFee( - instaLoanVariables_, - _fees, - address(balancerLending) - ); - } else { - revert("wrong-route"); - } + ) external { + spell(BALANCER_PROXY, msg.data); } /** @@ -410,22 +156,7 @@ contract FlashAggregator is Setups { uint256[] memory _amounts, bytes memory _data ) internal { - bytes memory data_ = abi.encode(msg.sender, _data); - uint256 length_ = _tokens.length; - uint256[] memory _modes = new uint256[](length_); - for (uint256 i = 0; i < length_; i++) { - _modes[i] = 0; - } - dataHash = bytes32(keccak256(data_)); - aaveLending.flashLoan( - address(this), - _tokens, - _amounts, - _modes, - address(0), - data_, - 3228 - ); + spell(AAVE_PROXY, msg.data); } /** @@ -440,24 +171,7 @@ contract FlashAggregator is Setups { uint256 _amount, bytes memory _data ) internal { - address[] memory tokens_ = new address[](1); - uint256[] memory amounts_ = new uint256[](1); - tokens_[0] = _token; - amounts_[0] = _amount; - bytes memory data_ = abi.encode( - 2, - tokens_, - amounts_, - msg.sender, - _data - ); - dataHash = bytes32(keccak256(data_)); - makerLending.flashLoan( - InstaFlashReceiverInterface(address(this)), - _token, - _amount, - data_ - ); + spell(MAKER_PROXY, msg.data); } /** @@ -472,20 +186,7 @@ contract FlashAggregator is Setups { uint256[] memory _amounts, bytes memory _data ) internal { - bytes memory data_ = abi.encode( - 3, - _tokens, - _amounts, - msg.sender, - _data - ); - dataHash = bytes32(keccak256(data_)); - makerLending.flashLoan( - InstaFlashReceiverInterface(address(this)), - daiTokenAddr, - daiBorrowAmount, - data_ - ); + spell(MAKER_PROXY, msg.data); } /** @@ -500,20 +201,7 @@ contract FlashAggregator is Setups { uint256[] memory _amounts, bytes memory _data ) internal { - bytes memory data_ = abi.encode( - 4, - _tokens, - _amounts, - msg.sender, - _data - ); - dataHash = bytes32(keccak256(data_)); - makerLending.flashLoan( - InstaFlashReceiverInterface(address(this)), - daiTokenAddr, - daiBorrowAmount, - data_ - ); + spell(MAKER_PROXY, msg.data); } /** @@ -528,30 +216,7 @@ contract FlashAggregator is Setups { uint256[] memory _amounts, bytes memory _data ) internal { - uint256 length_ = _tokens.length; - IERC20[] memory tokens_ = new IERC20[](length_); - for (uint256 i = 0; i < length_; i++) { - tokens_[i] = IERC20(_tokens[i]); - } - bytes memory data_ = abi.encode( - 5, - _tokens, - _amounts, - msg.sender, - _data - ); - dataHash = bytes32(keccak256(data_)); - if (_tokens[0] == stEthTokenAddr) { - require(length_ == 1, "steth-length-should-be-1"); - tokens_[0] = IERC20(address(wstEthToken)); - _amounts[0] = wstEthToken.getWstETHByStETH(_amounts[0]); - } - balancerLending.flashLoan( - InstaFlashReceiverInterface(address(this)), - tokens_, - _amounts, - data_ - ); + spell(BALANCER_PROXY, msg.data); } /** @@ -566,24 +231,7 @@ contract FlashAggregator is Setups { uint256[] memory _amounts, bytes memory _data ) internal { - bytes memory data_ = abi.encode( - 6, - _tokens, - _amounts, - msg.sender, - _data - ); - IERC20[] memory wethTokenList_ = new IERC20[](1); - uint256[] memory wethAmountList_ = new uint256[](1); - wethTokenList_[0] = IERC20(wethToken); - wethAmountList_[0] = getWEthBorrowAmount(); - dataHash = bytes32(keccak256(data_)); - balancerLending.flashLoan( - InstaFlashReceiverInterface(address(this)), - wethTokenList_, - wethAmountList_, - data_ - ); + spell(BALANCER_PROXY, msg.data); } /** @@ -598,24 +246,7 @@ contract FlashAggregator is Setups { uint256[] memory _amounts, bytes memory _data ) internal { - bytes memory data_ = abi.encode( - 7, - _tokens, - _amounts, - msg.sender, - _data - ); - IERC20[] memory wethTokenList_ = new IERC20[](1); - uint256[] memory wethAmountList_ = new uint256[](1); - wethTokenList_[0] = wethToken; - wethAmountList_[0] = getWEthBorrowAmount(); - dataHash = bytes32(keccak256(data_)); - balancerLending.flashLoan( - InstaFlashReceiverInterface(address(this)), - wethTokenList_, - wethAmountList_, - data_ - ); + spell(BALANCER_PROXY, msg.data); } /** @@ -702,6 +333,13 @@ contract FlashAggregator is Setups { contract InstaFlashAggregator is FlashAggregator { using SafeERC20 for IERC20; + function initialize(address aave, address maker, address balancer) public { + AAVE_PROXY = aave; + MAKER_PROXY = maker; + BALANCER_PROXY = balancer; + console.log("initialize call successful! AAVE_PROXY = ", AAVE_PROXY); + } + /* Deprecated */ diff --git a/contracts/aggregator/mainnet/flashloan/variables.sol b/contracts/aggregator/mainnet/flashloan/variables.sol index 61497a81..75e7f136 100644 --- a/contracts/aggregator/mainnet/flashloan/variables.sol +++ b/contracts/aggregator/mainnet/flashloan/variables.sol @@ -31,6 +31,12 @@ contract ConstantVariables { ListInterface internal constant instaList = ListInterface(0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb); uint256 public constant InstaFeeBPS = 5; // in BPS; 1 BPS = 0.01% + // address internal constant AAVE_PROXY; + // address internal constant MAKER_PROXY; + // address internal constant BALANCER_PROXY; + address internal AAVE_PROXY; + address internal MAKER_PROXY; + address internal BALANCER_PROXY; } contract Variables is ConstantVariables { diff --git a/test/mainnet/newFlashAggr.ts b/test/mainnet/newFlashAggr.ts new file mode 100644 index 00000000..326bafd2 --- /dev/null +++ b/test/mainnet/newFlashAggr.ts @@ -0,0 +1,126 @@ +const hre = require('hardhat') +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +const { ethers } = hre + + +import { + AaveImplementation, + BalancerImplementation, + MakerImplementation, + AaveImplementation__factory, + BalancerImplementation__factory, + MakerImplementation__factory, + InstaFlashAggregator, + InstaFlashAggregator__factory, + IERC20__factory, + IERC20, + InstaFlashReceiver__factory, + InstaFlashReceiver, + InstaFlashAggregatorProxy, + InstaFlashAggregatorProxy__factory, + } from '../../typechain' + + describe('FlashLoan', function () { + + let proxyA : AaveImplementation, + proxyB : BalancerImplementation, + proxyM : MakerImplementation, + aggregator : InstaFlashAggregator, + ProxyA, + ProxyB, + ProxyM, + Aggregator, + admin = "0xb208CDF8e1c319d0019397dceC8E0bA3Fb9A149F", + proxyAddr = "0x619Ad2D02dBeE6ebA3CDbDA3F98430410e892882", + proxyCon: { connect: (arg0: any) => { (): any; new(): any; upgradeTo: { (arg0: string): any; new(): any }; callStatic: { (): any; new(): any; implementation: { (): any; new(): any } } }; initialize: (arg0: string, arg1: string, arg2: string) => any }, + Receiver, + receiver: InstaFlashReceiver + + let signer: SignerWithAddress + + const _data = '0x' + let _instaData = '0x' + +//############## + const Dai = ethers.utils.parseUnits('5000', 18) + +//############## + const DAI = '0x6b175474e89094c44da98b954eedeac495271d0f' + const ACC_DAI = '0x9a7a9d980ed6239b89232c012e21f4c210f4bef1' + + + it('Should deploy', async function () { + ;[signer] = await ethers.getSigners() + + ProxyA = new AaveImplementation__factory + proxyA = await ProxyA.deploy() + await proxyA.deployed() + console.log("Aave proxy deployed at: ", proxyA.address); + + ProxyB = new BalancerImplementation__factory + proxyB = await ProxyB.deploy() + await proxyB.deployed() + console.log("Balancer proxy deployed at: ", proxyB.address); + + ProxyM = new MakerImplementation__factory + proxyM = await ProxyM.deploy() + await proxyM.deployed() + console.log("Maker proxy deployed at: ", proxyM.address); + + Aggregator = new InstaFlashAggregator__factory(signer) + aggregator = await Aggregator.deploy() + await aggregator.deployed() + console.log("Aggregator deployed at: ", aggregator.address); + + proxyCon = new hre.ethers.Contract( + proxyAddr, + [{"inputs":[{"internalType":"address","name":"_logic","type":"address"},{"internalType":"address","name":"admin_","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"admin_","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}] + ) + + Receiver = new InstaFlashReceiver__factory(signer) + receiver = await Receiver.deploy(proxyAddr) + await receiver.deployed() + console.log("Receiver deployed at: ", receiver.address); + + const token_dai = new ethers.Contract( + DAI, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_DAI, + ethers.utils.parseEther('10.0').toHexString(), + ]) + }) + + describe('Upgrade proxy implementation', async function () { + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [admin], + }) + + await hre.network.provider.send("hardhat_setBalance", [ + admin, + ethers.utils.parseEther("10.0").toHexString(), + ]); + + let impersonateAcc = await ethers.getSigner(admin); + + let tx = await proxyCon.connect(impersonateAcc).upgradeTo(aggregator.address); + let receipt = tx.wait(); + console.log("Implementation updated!") + + let addr = await proxyCon.connect(impersonateAcc).callStatic.implementation(); + console.log("Implementation at: ", addr); + + await proxyCon.initialize(proxyA.address, proxyB.address, proxyM.address);//todo: doubt + }) + + describe('Single token', async function () { + it('Should be able to take flashLoan of a single token from AAVE', async function () { + await receiver.flashBorrow([DAI], [Dai], 1, _data, _instaData) + }) + }) + }) + \ No newline at end of file From e88ad6a22068295bec01a06a2be72b669b8f2ba0 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Wed, 11 May 2022 00:47:01 +0400 Subject: [PATCH 04/20] flashloan func added in implementations --- contracts/ProxyAave/main.sol | 19 ++ contracts/ProxyBalancer/main.sol | 26 ++ contracts/ProxyMaker/main.sol | 26 ++ .../aggregator/mainnet/flashloan/main.sol | 135 +------- .../mainnet/flashloan/variables.sol | 10 +- test/mainnet/newFlashAggr.ts | 304 ++++++++++++++++-- 6 files changed, 355 insertions(+), 165 deletions(-) diff --git a/contracts/ProxyAave/main.sol b/contracts/ProxyAave/main.sol index 7e9abab5..053dca25 100644 --- a/contracts/ProxyAave/main.sol +++ b/contracts/ProxyAave/main.sol @@ -4,6 +4,25 @@ import "../aggregator/mainnet/flashloan/helpers.sol"; contract AaveImplementation is Helper { + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes calldata // kept for future use by instadapp. Currently not used anywhere. + ) external reentrancy { + require(_route == 1, "invalid AAVE flashloan route"); + routeAave(_tokens, _amounts, _data); + } + /** * @dev Callback function for aave flashloan. * @notice Callback function for aave flashloan. diff --git a/contracts/ProxyBalancer/main.sol b/contracts/ProxyBalancer/main.sol index 0bec320f..cb7bf0c9 100644 --- a/contracts/ProxyBalancer/main.sol +++ b/contracts/ProxyBalancer/main.sol @@ -4,6 +4,32 @@ import "../aggregator/mainnet/flashloan/helpers.sol"; contract BalancerImplementation is Helper { + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes calldata // kept for future use by instadapp. Currently not used anywhere. + ) external reentrancy { + require(_route == 5 || _route == 6 || _route == 7, "invalid BALANCER flashloan route"); + + if (_route == 5) { + routeBalancer(_tokens, _amounts, _data); + } else if (_route == 6) { + routeBalancerCompound(_tokens, _amounts, _data); + } else if (_route == 7) { + routeBalancerAave(_tokens, _amounts, _data); + } + } + /** * @dev Fallback function for balancer flashloan. * @notice Fallback function for balancer flashloan. diff --git a/contracts/ProxyMaker/main.sol b/contracts/ProxyMaker/main.sol index 252e97ad..c0565e2e 100644 --- a/contracts/ProxyMaker/main.sol +++ b/contracts/ProxyMaker/main.sol @@ -4,6 +4,32 @@ import "../aggregator/mainnet/flashloan/helpers.sol"; contract MakerImplementation is Helper { + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes calldata // kept for future use by instadapp. Currently not used anywhere. + ) external reentrancy { + require((_route == 2 || _route == 3 || _route == 4), "invalid MAKER flashloan route"); + + if (_route == 2) { + routeMaker(_tokens[0], _amounts[0], _data); + } else if (_route == 3) { + routeMakerCompound(_tokens, _amounts, _data); + } else if (_route == 4) { + routeMakerAave(_tokens, _amounts, _data); + } + } + /** * @dev Fallback function for makerdao flashloan. * @notice Fallback function for makerdao flashloan. diff --git a/contracts/aggregator/mainnet/flashloan/main.sol b/contracts/aggregator/mainnet/flashloan/main.sol index 2b7d3119..9ca48d66 100644 --- a/contracts/aggregator/mainnet/flashloan/main.sol +++ b/contracts/aggregator/mainnet/flashloan/main.sol @@ -7,7 +7,6 @@ pragma solidity ^0.8.0; */ import "./helpers.sol"; -import "hardhat/console.sol"; import "@openzeppelin/contracts/utils/Address.sol"; contract AdminModule is Helper { @@ -105,7 +104,7 @@ contract FlashAggregator is Setups { address _initiator, bytes memory _data ) external returns (bool) { - bytes memory response = spell(AAVE_PROXY, msg.data); + bytes memory response = spell(AAVE_IMP, msg.data); return (abi.decode(response, (bool))); } @@ -124,7 +123,7 @@ contract FlashAggregator is Setups { uint256 _fee, bytes calldata _data ) external returns (bytes32) { - bytes memory response = spell(MAKER_PROXY, msg.data); + bytes memory response = spell(MAKER_IMP, msg.data); return (abi.decode(response, (bytes32))); } @@ -141,112 +140,7 @@ contract FlashAggregator is Setups { uint256[] memory _fees, bytes memory _data ) external { - spell(BALANCER_PROXY, msg.data); - } - - /** - * @dev Middle function for route 1. - * @notice Middle function for route 1. - * @param _tokens list of token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets or amount of ether to borrow as collateral for flashloan. - * @param _data extra data passed. - */ - function routeAave( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - spell(AAVE_PROXY, msg.data); - } - - /** - * @dev Middle function for route 2. - * @notice Middle function for route 2. - * @param _token token address for flashloan(DAI). - * @param _amount DAI amount for flashloan. - * @param _data extra data passed. - */ - function routeMaker( - address _token, - uint256 _amount, - bytes memory _data - ) internal { - spell(MAKER_PROXY, msg.data); - } - - /** - * @dev Middle function for route 3. - * @notice Middle function for route 3. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - */ - function routeMakerCompound( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - spell(MAKER_PROXY, msg.data); - } - - /** - * @dev Middle function for route 4. - * @notice Middle function for route 4. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - */ - function routeMakerAave( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - spell(MAKER_PROXY, msg.data); - } - - /** - * @dev Middle function for route 5. - * @notice Middle function for route 5. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - */ - function routeBalancer( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - spell(BALANCER_PROXY, msg.data); - } - - /** - * @dev Middle function for route 6. - * @notice Middle function for route 6. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - */ - function routeBalancerCompound( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - spell(BALANCER_PROXY, msg.data); - } - - /** - * @dev Middle function for route 7. - * @notice Middle function for route 7. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - */ - function routeBalancerAave( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - spell(BALANCER_PROXY, msg.data); + spell(BALANCER_IMP, msg.data); } /** @@ -263,26 +157,26 @@ contract FlashAggregator is Setups { uint256 _route, bytes calldata _data, bytes calldata // kept for future use by instadapp. Currently not used anywhere. - ) external reentrancy { + ) external { require(_tokens.length == _amounts.length, "array-lengths-not-same"); (_tokens, _amounts) = bubbleSort(_tokens, _amounts); validateTokens(_tokens); if (_route == 1) { - routeAave(_tokens, _amounts, _data); + spell(AAVE_IMP, msg.data); } else if (_route == 2) { - routeMaker(_tokens[0], _amounts[0], _data); + spell(MAKER_IMP, msg.data); } else if (_route == 3) { - routeMakerCompound(_tokens, _amounts, _data); + spell(MAKER_IMP, msg.data); } else if (_route == 4) { - routeMakerAave(_tokens, _amounts, _data); + spell(MAKER_IMP, msg.data); } else if (_route == 5) { - routeBalancer(_tokens, _amounts, _data); + spell(BALANCER_IMP, msg.data); } else if (_route == 6) { - routeBalancerCompound(_tokens, _amounts, _data); + spell(BALANCER_IMP, msg.data); } else if (_route == 7) { - routeBalancerAave(_tokens, _amounts, _data); + spell(BALANCER_IMP, msg.data); } else { revert("route-does-not-exist"); } @@ -333,13 +227,6 @@ contract FlashAggregator is Setups { contract InstaFlashAggregator is FlashAggregator { using SafeERC20 for IERC20; - function initialize(address aave, address maker, address balancer) public { - AAVE_PROXY = aave; - MAKER_PROXY = maker; - BALANCER_PROXY = balancer; - console.log("initialize call successful! AAVE_PROXY = ", AAVE_PROXY); - } - /* Deprecated */ diff --git a/contracts/aggregator/mainnet/flashloan/variables.sol b/contracts/aggregator/mainnet/flashloan/variables.sol index 75e7f136..1dfbf80e 100644 --- a/contracts/aggregator/mainnet/flashloan/variables.sol +++ b/contracts/aggregator/mainnet/flashloan/variables.sol @@ -31,12 +31,6 @@ contract ConstantVariables { ListInterface internal constant instaList = ListInterface(0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb); uint256 public constant InstaFeeBPS = 5; // in BPS; 1 BPS = 0.01% - // address internal constant AAVE_PROXY; - // address internal constant MAKER_PROXY; - // address internal constant BALANCER_PROXY; - address internal AAVE_PROXY; - address internal MAKER_PROXY; - address internal BALANCER_PROXY; } contract Variables is ConstantVariables { @@ -62,4 +56,8 @@ contract Variables is ConstantVariables { uint256 internal ownerStatus; mapping(address => bool) public isWhitelisted; + + address internal AAVE_IMP; + address internal MAKER_IMP; + address internal BALANCER_IMP; } diff --git a/test/mainnet/newFlashAggr.ts b/test/mainnet/newFlashAggr.ts index 326bafd2..70cc657b 100644 --- a/test/mainnet/newFlashAggr.ts +++ b/test/mainnet/newFlashAggr.ts @@ -26,13 +26,15 @@ import { proxyB : BalancerImplementation, proxyM : MakerImplementation, aggregator : InstaFlashAggregator, + Proxy, + proxy: InstaFlashAggregatorProxy, ProxyA, ProxyB, ProxyM, + aaveImp,BalancerImp,MakerImp, Aggregator, admin = "0xb208CDF8e1c319d0019397dceC8E0bA3Fb9A149F", proxyAddr = "0x619Ad2D02dBeE6ebA3CDbDA3F98430410e892882", - proxyCon: { connect: (arg0: any) => { (): any; new(): any; upgradeTo: { (arg0: string): any; new(): any }; callStatic: { (): any; new(): any; implementation: { (): any; new(): any } } }; initialize: (arg0: string, arg1: string, arg2: string) => any }, Receiver, receiver: InstaFlashReceiver @@ -40,87 +42,319 @@ import { const _data = '0x' let _instaData = '0x' + const master = '0xa8c31E39e40E6765BEdBd83D92D6AA0B33f1CCC5' + const aaveLendingAddr = '0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9' + let ABI = ['function initialize(address[],address,address,address,address)'] + let iface = new ethers.utils.Interface(ABI) -//############## - const Dai = ethers.utils.parseUnits('5000', 18) - -//############## const DAI = '0x6b175474e89094c44da98b954eedeac495271d0f' + const USDT = '0xdac17f958d2ee523a2206206994597c13d831ec7' + const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' + const STETH = '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84' + const ACC_DAI = '0x9a7a9d980ed6239b89232c012e21f4c210f4bef1' + const ACC_USDT = '0x6D5Be15f9Aa170e207C043CDf8E0BaDbF2A48ed0' + const ACC_WETH = '0xe78388b4ce79068e89bf8aa7f218ef6b9ab0e9d0' + const ACC_STETH = '0xdc24316b9ae028f1497c275eb9192a3ea0f67022' + + const dai = ethers.utils.parseUnits('10', 18) + const usdt = ethers.utils.parseUnits('10', 6) + const weth = ethers.utils.parseUnits('10', 18) + const Dai = ethers.utils.parseUnits('5000', 18) + const Usdt = ethers.utils.parseUnits('5000', 6) + const Weth = ethers.utils.parseUnits('1000', 18) + const steth = ethers.utils.parseUnits('1', 18) + const Steth = ethers.utils.parseUnits('100', 18) - it('Should deploy', async function () { + beforeEach(async function () { ;[signer] = await ethers.getSigners() - ProxyA = new AaveImplementation__factory + ProxyA = new AaveImplementation__factory(signer) proxyA = await ProxyA.deploy() await proxyA.deployed() console.log("Aave proxy deployed at: ", proxyA.address); - ProxyB = new BalancerImplementation__factory + + ProxyB = new BalancerImplementation__factory(signer) proxyB = await ProxyB.deploy() await proxyB.deployed() console.log("Balancer proxy deployed at: ", proxyB.address); - ProxyM = new MakerImplementation__factory + + ProxyM = new MakerImplementation__factory(signer) proxyM = await ProxyM.deploy() await proxyM.deployed() console.log("Maker proxy deployed at: ", proxyM.address); + Aggregator = new InstaFlashAggregator__factory(signer) aggregator = await Aggregator.deploy() await aggregator.deployed() console.log("Aggregator deployed at: ", aggregator.address); - proxyCon = new hre.ethers.Contract( - proxyAddr, - [{"inputs":[{"internalType":"address","name":"_logic","type":"address"},{"internalType":"address","name":"admin_","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"admin_","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}] - ) + const data = iface.encodeFunctionData('initialize', [ + [ + '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643', // DAI + '0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9', // USDT + '0x39AA39c021dfbaE8faC545936693aC917d5E7563', // USDC + '0xe65cdb6479bac1e22340e4e755fae7e509ecd06c', // AAVE + '0x6c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e', // BAT + '0x70e36f6bf80a52b3b46b3af8e106cc0ed743e8e4', // COMP + '0xface851a4921ce59e912d19329929ce6da6eb0c7', // LINK + '0x95b4ef2869ebd94beb4eee400a99824bf5dc325b', // MKR + '0x158079ee67fce2f58472a96584a73c7ab9ac95c1', // REP + '0x4b0181102a0112a2ef11abee5563bb4a3176c9d7', // SUSHI + '0x12392f67bdf24fae0af363c24ac620a2f67dad86', // TUSD + '0x35a18000230da775cac24873d00ff85bccded550', // UNI + '0xccf4429db6322d5c611ee964527d42e5d685dd6a', // WBTC2 + '0x80a2ae356fc9ef4305676f7a3e2ed04e12c33946', // YFI + '0xb3319f5d18bc0d84dd1b4825dcde5d5f7266d407', // ZRX + ],master,proxyA.address,proxyB.address,proxyM.address + ]) + + Proxy = new InstaFlashAggregatorProxy__factory(signer) + proxy = await Proxy.deploy(aggregator.address, master, data) + await proxy.deployed() + console.log("Proxy deployed at: ", proxy.address); Receiver = new InstaFlashReceiver__factory(signer) - receiver = await Receiver.deploy(proxyAddr) + receiver = await Receiver.deploy(proxy.address) await receiver.deployed() console.log("Receiver deployed at: ", receiver.address); - + + await hre.network.provider.send('hardhat_setBalance', [ + proxy.address, + ethers.utils.parseEther('10.0').toHexString(), + ]) + const token_dai = new ethers.Contract( - DAI, - IERC20__factory.abi, - ethers.provider, + DAI, + IERC20__factory.abi, + ethers.provider, + ) + + const token_steth = new ethers.Contract( + STETH, + IERC20__factory.abi, + ethers.provider, ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_DAI, + ethers.utils.parseEther('10.0').toHexString(), + ]) await hre.network.provider.send('hardhat_setBalance', [ - ACC_DAI, + ACC_STETH, ethers.utils.parseEther('10.0').toHexString(), ]) - }) - describe('Upgrade proxy implementation', async function () { + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_DAI], + }) + + const signer_dai = await ethers.getSigner(ACC_DAI) + await token_dai.connect(signer_dai).transfer(receiver.address, dai) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_DAI], + }) + await hre.network.provider.request({ method: 'hardhat_impersonateAccount', - params: [admin], - }) + params: [ACC_STETH], + }) - await hre.network.provider.send("hardhat_setBalance", [ - admin, - ethers.utils.parseEther("10.0").toHexString(), - ]); + const signer_steth = await ethers.getSigner(ACC_STETH) + await token_steth.connect(signer_steth).transfer(receiver.address, steth) + await token_steth.connect(signer_steth).transfer(proxy.address, steth) - let impersonateAcc = await ethers.getSigner(admin); + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_STETH], + }) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [proxy.address], + }) - let tx = await proxyCon.connect(impersonateAcc).upgradeTo(aggregator.address); - let receipt = tx.wait(); - console.log("Implementation updated!") + const signer_fla = await ethers.getSigner(proxy.address) + await token_dai.connect(signer_fla).approve(aaveLendingAddr, 100) - let addr = await proxyCon.connect(impersonateAcc).callStatic.implementation(); - console.log("Implementation at: ", addr); - - await proxyCon.initialize(proxyA.address, proxyB.address, proxyM.address);//todo: doubt + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [proxy.address], + }) }) describe('Single token', async function () { it('Should be able to take flashLoan of a single token from AAVE', async function () { await receiver.flashBorrow([DAI], [Dai], 1, _data, _instaData) }) + it('Should be able to take flashLoan of a single token from MakerDAO', async function () { + await receiver.flashBorrow([DAI], [Dai], 2, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from Compound(MakerDAO)', async function () { + await receiver.flashBorrow([DAI], [Dai], 3, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from AAVE(MakerDAO)', async function () { + await receiver.flashBorrow([DAI], [Dai], 4, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from Balancer', async function () { + await receiver.flashBorrow([DAI], [Dai], 5, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from Compound(Balancer)', async function () { + await receiver.flashBorrow([DAI], [Dai], 6, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from AAVE(Balancer)', async function () { + await receiver.flashBorrow([DAI], [Dai], 7, _data, _instaData) + }) + it('Should be able to take flashLoan of a steth token from AAVE(Balancer)', async function () { + await receiver.flashBorrow([STETH], [Steth], 5, _data, _instaData) + }) }) + + describe('Multi token', async function () { + beforeEach(async function () { + const token_usdt = new ethers.Contract( + USDT, + IERC20__factory.abi, + ethers.provider, + ) + + const token_weth = new ethers.Contract( + WETH, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_USDT, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_WETH, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_USDT], + }) + + const signer_usdt = await ethers.getSigner(ACC_USDT) + await token_usdt.connect(signer_usdt).transfer(receiver.address, usdt) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_USDT], + }) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_WETH], + }) + + const signer_weth = await ethers.getSigner(ACC_WETH) + await token_weth.connect(signer_weth).transfer(receiver.address, weth) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_WETH], + }) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [proxy.address], + }) + + const signer_fla = await ethers.getSigner(proxy.address) + await token_usdt.connect(signer_fla).approve(aaveLendingAddr, 100) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [proxy.address], + }) + _instaData = '0x' + }) + + it('Should be able to take flashLoan of multiple tokens together from AAVE', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 1, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from MakerDAO', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 2, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from Compound(MakerDAO)', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 3, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from AAVE(MakerDAO)', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 4, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple sorted tokens together from Balancer', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 5, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple unsorted tokens together from Balancer', async function () { + await receiver.flashBorrow( + [USDT, DAI, WETH], + [Usdt, Dai, Weth], + 5, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from Compound(Balancer)', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 6, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from AAVE(Balancer)', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 7, + _data, + _instaData, + ) + }) + }) }) \ No newline at end of file From 0c5c1586a4a74fa69a84a86a1f2c4088f4d28810 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Wed, 11 May 2022 00:50:00 +0400 Subject: [PATCH 05/20] changed file names --- contracts/{ProxyBalancer => implBalancer}/main.sol | 0 contracts/{ProxyMaker => implMaker}/main.sol | 0 contracts/{ProxyAave => impleAave}/main.sol | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename contracts/{ProxyBalancer => implBalancer}/main.sol (100%) rename contracts/{ProxyMaker => implMaker}/main.sol (100%) rename contracts/{ProxyAave => impleAave}/main.sol (100%) diff --git a/contracts/ProxyBalancer/main.sol b/contracts/implBalancer/main.sol similarity index 100% rename from contracts/ProxyBalancer/main.sol rename to contracts/implBalancer/main.sol diff --git a/contracts/ProxyMaker/main.sol b/contracts/implMaker/main.sol similarity index 100% rename from contracts/ProxyMaker/main.sol rename to contracts/implMaker/main.sol diff --git a/contracts/ProxyAave/main.sol b/contracts/impleAave/main.sol similarity index 100% rename from contracts/ProxyAave/main.sol rename to contracts/impleAave/main.sol From c7d3a69859322ce4d979b021b19c0bac7df0445f Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Wed, 11 May 2022 00:53:30 +0400 Subject: [PATCH 06/20] minor update --- contracts/{impleAave => implAave}/main.sol | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contracts/{impleAave => implAave}/main.sol (100%) diff --git a/contracts/impleAave/main.sol b/contracts/implAave/main.sol similarity index 100% rename from contracts/impleAave/main.sol rename to contracts/implAave/main.sol From 2ba7c66ea11b3b1c2061240e6ee17081b69d5eac Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Sat, 14 May 2022 02:44:26 +0400 Subject: [PATCH 07/20] added common helper and interface --- contracts/aggregator/common/helpers.sol | 114 ++++++++++++++++++++++ contracts/aggregator/common/interface.sol | 35 +++++++ 2 files changed, 149 insertions(+) create mode 100644 contracts/aggregator/common/helpers.sol create mode 100644 contracts/aggregator/common/interface.sol diff --git a/contracts/aggregator/common/helpers.sol b/contracts/aggregator/common/helpers.sol new file mode 100644 index 00000000..853a461a --- /dev/null +++ b/contracts/aggregator/common/helpers.sol @@ -0,0 +1,114 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +contract HelpersCommon { + using SafeERC20 for IERC20; + + /** + * @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 Calculates the balances.. + * @notice Calculates the balances of the account passed for the tokens. + * @param _tokens list of token addresses to calculate balance for. + * @param _account account to calculate balance for. + */ + function calculateBalances(address[] memory _tokens, address _account) + internal + view + returns (uint256[] memory) + { + uint256 _length = _tokens.length; + uint256[] memory balances_ = new uint256[](_length); + for (uint256 i = 0; i < _length; i++) { + IERC20 token = IERC20(_tokens[i]); + balances_[i] = token.balanceOf(_account); + } + return balances_; + } + + /** + * @dev Validates if token addresses are unique. Just need to check adjacent tokens as the array was sorted first + * @notice Validates if token addresses are unique. + * @param _tokens list of token addresses. + */ + function validateTokens(address[] memory _tokens) internal pure { + for (uint256 i = 0; i < _tokens.length - 1; i++) { + require(_tokens[i] != _tokens[i + 1], "non-unique-tokens"); + } + } + + /** + * @dev Calculate fees for the respective amounts and fee in BPS passed. + * @notice Calculate fees for the respective amounts and fee in BPS passed. 1 BPS == 0.01%. + * @param _amounts list of amounts. + * @param _BPS fee in BPS. + */ + function calculateFees(uint256[] memory _amounts, uint256 _BPS) + internal + pure + returns (uint256[] memory) + { + uint256 length_ = _amounts.length; + uint256[] memory InstaFees = new uint256[](length_); + for (uint256 i = 0; i < length_; i++) { + InstaFees[i] = (_amounts[i] * _BPS) / (10**4); + } + return InstaFees; + } + + /** + * @dev Sort the tokens and amounts arrays according to token addresses. + * @notice Sort the tokens and amounts arrays according to token addresses. + * @param _tokens list of token addresses. + * @param _amounts list of respective amounts. + */ + function bubbleSort(address[] memory _tokens, uint256[] memory _amounts) + internal + pure + returns (address[] memory, uint256[] memory) + { + for (uint256 i = 0; i < _tokens.length - 1; i++) { + for (uint256 j = 0; j < _tokens.length - i - 1; j++) { + if (_tokens[j] > _tokens[j + 1]) { + ( + _tokens[j], + _tokens[j + 1], + _amounts[j], + _amounts[j + 1] + ) = ( + _tokens[j + 1], + _tokens[j], + _amounts[j + 1], + _amounts[j] + ); + } + } + } + return (_tokens, _amounts); + } +} diff --git a/contracts/aggregator/common/interface.sol b/contracts/aggregator/common/interface.sol new file mode 100644 index 00000000..b800be8a --- /dev/null +++ b/contracts/aggregator/common/interface.sol @@ -0,0 +1,35 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; +pragma experimental ABIEncoderV2; + +interface IndexInterface { + function master() external view returns (address); + + function list() external view returns (address); +} + +interface ListInterface { + function accountID(address) external view returns (uint64); +} + +interface TokenInterface { + function approve(address, uint256) external; + + function transfer(address, uint256) external; + + function transferFrom( + address, + address, + uint256 + ) external; + + function deposit() external payable; + + function withdraw(uint256) external; + + function balanceOf(address) external view returns (uint256); + + function decimals() external view returns (uint256); + + function totalSupply() external view returns (uint256); +} From c549c3a7753d7f26014981782ad543c991633f43 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Sun, 15 May 2022 02:12:28 +0400 Subject: [PATCH 08/20] Added Implementation proxy - Arbitrum --- .../arbitrum/flashloan/implBalancer/main.sol | 118 +++++++++ .../arbitrum/flashloan/implUniswap/main.sol | 173 ++++++++++++++ .../aggregator/arbitrum/flashloan/main.sol | 223 +----------------- 3 files changed, 298 insertions(+), 216 deletions(-) create mode 100644 contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol create mode 100644 contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol diff --git a/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol b/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol new file mode 100644 index 00000000..849a2e15 --- /dev/null +++ b/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol @@ -0,0 +1,118 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import "../helpers.sol"; + +contract BalancerImplementation is Helper { + + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes memory _instadata + ) external reentrancy { + require(_route == 5 , "invalid BALANCER flashloan route"); + routeBalancer(_tokens, _amounts, _data); + } + + /** + * @dev Callback function for balancer flashloan. + * @notice Fallback function for balancer flashloan. + * @param _amounts list of amounts for the corresponding assets or amount of ether to borrow as collateral for flashloan. + * @param _fees list of fees for the corresponding addresses for flashloan. + * @param _data extra data passed. + */ + function receiveFlashLoan( + IERC20[] memory _tokens, + uint256[] memory _amounts, + uint256[] memory _fees, + bytes memory _data + ) external verifyDataHash(_data) { + require(msg.sender == balancerLendingAddr, "not-balancer-sender"); + + FlashloanVariables memory instaLoanVariables_; + + uint256 length_ = _tokens.length; + instaLoanVariables_._tokens = new address[](length_); + for (uint256 i = 0; i < length_; i++) { + instaLoanVariables_._tokens[i] = address(_tokens[i]); + } + + (address sender_, bytes memory data_) = abi.decode( + _data, + (address, bytes) + ); + + instaLoanVariables_._amounts = _amounts; + instaLoanVariables_._iniBals = calculateBalances( + instaLoanVariables_._tokens, + address(this) + ); + instaLoanVariables_._instaFees = calculateFees( + _amounts, + calculateFeeBPS(5) + ); + + safeTransfer(instaLoanVariables_, sender_); + + if (checkIfDsa(sender_)) { + Address.functionCall( + sender_, + data_, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(sender_).executeOperation( + instaLoanVariables_._tokens, + _amounts, + instaLoanVariables_._instaFees, + sender_, + data_ + ); + } + + instaLoanVariables_._finBals = calculateBalances( + instaLoanVariables_._tokens, + address(this) + ); + validateFlashloan(instaLoanVariables_); + + safeTransferWithFee(instaLoanVariables_, _fees, balancerLendingAddr); + } + + + /** + * @dev Middle function for route 5. + * @notice Middle function for route 5. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + */ + function routeBalancer( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + bytes memory data_ = abi.encode(msg.sender, _data); + uint256 length_ = _tokens.length; + IERC20[] memory tokens_ = new IERC20[](length_); + for (uint256 i = 0; i < length_; i++) { + tokens_[i] = IERC20(_tokens[i]); + } + dataHash = bytes32(keccak256(data_)); + balancerLending.flashLoan( + InstaFlashReceiverInterface(address(this)), + tokens_, + _amounts, + data_ + ); + } +} diff --git a/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol new file mode 100644 index 00000000..a6d1c759 --- /dev/null +++ b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol @@ -0,0 +1,173 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import "../helpers.sol"; + +contract UniswapImplementation is Helper { + + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes memory _instadata + ) external reentrancy { + require(_route == 8, "invalid UNISWAP flashloan route"); + routeUniswap(_tokens, _amounts, _data, _instadata); + } + + struct UniswapFlashInfo { + address sender; + PoolKey key; + bytes data; + } + + /** + * @dev Callback function for uniswap flashloan. + * @notice Callback function for uniswap flashloan. + * @param fee0 The fee from calling flash for token0 + * @param fee1 The fee from calling flash for token1 + * @param data extra data passed(includes route info aswell). + */ + function uniswapV3FlashCallback( + uint256 fee0, + uint256 fee1, + bytes memory data + ) external verifyDataHash(data) { + FlashloanVariables memory instaLoanVariables_; + UniswapFlashInfo memory uniswapFlashData_; + + ( + instaLoanVariables_._tokens, + instaLoanVariables_._amounts, + uniswapFlashData_.sender, + uniswapFlashData_.key, + uniswapFlashData_.data + ) = abi.decode(data, (address[], uint256[], address, PoolKey, bytes)); + + address pool = computeAddress( + uniswapFactoryAddr, + uniswapFlashData_.key + ); + require(msg.sender == pool, "invalid-sender"); + + instaLoanVariables_._iniBals = calculateBalances( + instaLoanVariables_._tokens, + address(this) + ); + + uint256 feeBPS = uint256(uniswapFlashData_.key.fee / 100); + if (feeBPS < InstaFeeBPS) { + feeBPS = InstaFeeBPS; + } + + instaLoanVariables_._instaFees = calculateFees( + instaLoanVariables_._amounts, + feeBPS + ); + + safeTransfer(instaLoanVariables_, uniswapFlashData_.sender); + + if (checkIfDsa(uniswapFlashData_.sender)) { + Address.functionCall( + uniswapFlashData_.sender, + uniswapFlashData_.data, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(uniswapFlashData_.sender) + .executeOperation( + instaLoanVariables_._tokens, + instaLoanVariables_._amounts, + instaLoanVariables_._instaFees, + uniswapFlashData_.sender, + uniswapFlashData_.data + ); + } + + instaLoanVariables_._finBals = calculateBalances( + instaLoanVariables_._tokens, + address(this) + ); + + validateFlashloan(instaLoanVariables_); + + uint256[] memory fees_; + if (instaLoanVariables_._tokens.length == 2) { + fees_ = new uint256[](2); + fees_[0] = fee0; + fees_[1] = fee1; + } else if ( + instaLoanVariables_._tokens[0] == uniswapFlashData_.key.token0 + ) { + fees_ = new uint256[](1); + fees_[0] = fee0; + } else { + fees_ = new uint256[](1); + fees_[0] = fee1; + } + safeTransferWithFee(instaLoanVariables_, fees_, msg.sender); + } + + /** + * @dev Middle function for route 8. + * @notice Middle function for route 8. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + * @param _instadata pool key encoded + */ + function routeUniswap( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data, + bytes memory _instadata + ) internal { + PoolKey memory key = abi.decode(_instadata, (PoolKey)); + + uint256 amount0_; + uint256 amount1_; + + if (_tokens.length == 1) { + require( + (_tokens[0] == key.token0 || _tokens[0] == key.token1), + "tokens-do-not-match-pool" + ); + if (_tokens[0] == key.token0) { + amount0_ = _amounts[0]; + } else { + amount1_ = _amounts[0]; + } + } else if (_tokens.length == 2) { + require( + (_tokens[0] == key.token0 && _tokens[1] == key.token1), + "tokens-do-not-match-pool" + ); + amount0_ = _amounts[0]; + amount1_ = _amounts[1]; + } else { + revert("Number of tokens do not match"); + } + + IUniswapV3Pool pool = IUniswapV3Pool( + computeAddress(uniswapFactoryAddr, key) + ); + + bytes memory data_ = abi.encode( + _tokens, + _amounts, + msg.sender, + key, + _data + ); + dataHash = bytes32(keccak256(data_)); + pool.flash(address(this), amount0_, amount1_, data_); + } +} diff --git a/contracts/aggregator/arbitrum/flashloan/main.sol b/contracts/aggregator/arbitrum/flashloan/main.sol index 7f0470cc..c96d8c6c 100644 --- a/contracts/aggregator/arbitrum/flashloan/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/main.sol @@ -26,63 +26,8 @@ contract FlashAggregatorArbitrum is Helper { uint256[] memory _amounts, uint256[] memory _fees, bytes memory _data - ) external verifyDataHash(_data) { - require(msg.sender == balancerLendingAddr, "not-balancer-sender"); - - FlashloanVariables memory instaLoanVariables_; - - uint256 length_ = _tokens.length; - instaLoanVariables_._tokens = new address[](length_); - for (uint256 i = 0; i < length_; i++) { - instaLoanVariables_._tokens[i] = address(_tokens[i]); - } - - (address sender_, bytes memory data_) = abi.decode( - _data, - (address, bytes) - ); - - instaLoanVariables_._amounts = _amounts; - instaLoanVariables_._iniBals = calculateBalances( - instaLoanVariables_._tokens, - address(this) - ); - instaLoanVariables_._instaFees = calculateFees( - _amounts, - calculateFeeBPS(5) - ); - - safeTransfer(instaLoanVariables_, sender_); - - if (checkIfDsa(sender_)) { - Address.functionCall( - sender_, - data_, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(sender_).executeOperation( - instaLoanVariables_._tokens, - _amounts, - instaLoanVariables_._instaFees, - sender_, - data_ - ); - } - - instaLoanVariables_._finBals = calculateBalances( - instaLoanVariables_._tokens, - address(this) - ); - validateFlashloan(instaLoanVariables_); - - safeTransferWithFee(instaLoanVariables_, _fees, balancerLendingAddr); - } - - struct UniswapFlashInfo { - address sender; - PoolKey key; - bytes data; + ) external { + spell(BALANCER_IMP, msg.data); } /** @@ -96,162 +41,8 @@ contract FlashAggregatorArbitrum is Helper { uint256 fee0, uint256 fee1, bytes memory data - ) external verifyDataHash(data) { - FlashloanVariables memory instaLoanVariables_; - UniswapFlashInfo memory uniswapFlashData_; - - ( - instaLoanVariables_._tokens, - instaLoanVariables_._amounts, - uniswapFlashData_.sender, - uniswapFlashData_.key, - uniswapFlashData_.data - ) = abi.decode(data, (address[], uint256[], address, PoolKey, bytes)); - - address pool = computeAddress( - uniswapFactoryAddr, - uniswapFlashData_.key - ); - require(msg.sender == pool, "invalid-sender"); - - instaLoanVariables_._iniBals = calculateBalances( - instaLoanVariables_._tokens, - address(this) - ); - - uint256 feeBPS = uint256(uniswapFlashData_.key.fee / 100); - if (feeBPS < InstaFeeBPS) { - feeBPS = InstaFeeBPS; - } - - instaLoanVariables_._instaFees = calculateFees( - instaLoanVariables_._amounts, - feeBPS - ); - - safeTransfer(instaLoanVariables_, uniswapFlashData_.sender); - - if (checkIfDsa(uniswapFlashData_.sender)) { - Address.functionCall( - uniswapFlashData_.sender, - uniswapFlashData_.data, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(uniswapFlashData_.sender) - .executeOperation( - instaLoanVariables_._tokens, - instaLoanVariables_._amounts, - instaLoanVariables_._instaFees, - uniswapFlashData_.sender, - uniswapFlashData_.data - ); - } - - instaLoanVariables_._finBals = calculateBalances( - instaLoanVariables_._tokens, - address(this) - ); - - validateFlashloan(instaLoanVariables_); - - uint256[] memory fees_; - if (instaLoanVariables_._tokens.length == 2) { - fees_ = new uint256[](2); - fees_[0] = fee0; - fees_[1] = fee1; - } else if ( - instaLoanVariables_._tokens[0] == uniswapFlashData_.key.token0 - ) { - fees_ = new uint256[](1); - fees_[0] = fee0; - } else { - fees_ = new uint256[](1); - fees_[0] = fee1; - } - safeTransferWithFee(instaLoanVariables_, fees_, msg.sender); - } - - /** - * @dev Middle function for route 5. - * @notice Middle function for route 5. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - */ - function routeBalancer( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - bytes memory data_ = abi.encode(msg.sender, _data); - uint256 length_ = _tokens.length; - IERC20[] memory tokens_ = new IERC20[](length_); - for (uint256 i = 0; i < length_; i++) { - tokens_[i] = IERC20(_tokens[i]); - } - dataHash = bytes32(keccak256(data_)); - balancerLending.flashLoan( - InstaFlashReceiverInterface(address(this)), - tokens_, - _amounts, - data_ - ); - } - - /** - * @dev Middle function for route 8. - * @notice Middle function for route 8. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - * @param _instadata pool key encoded - */ - function routeUniswap( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data, - bytes memory _instadata - ) internal { - PoolKey memory key = abi.decode(_instadata, (PoolKey)); - - uint256 amount0_; - uint256 amount1_; - - if (_tokens.length == 1) { - require( - (_tokens[0] == key.token0 || _tokens[0] == key.token1), - "tokens-do-not-match-pool" - ); - if (_tokens[0] == key.token0) { - amount0_ = _amounts[0]; - } else { - amount1_ = _amounts[0]; - } - } else if (_tokens.length == 2) { - require( - (_tokens[0] == key.token0 && _tokens[1] == key.token1), - "tokens-do-not-match-pool" - ); - amount0_ = _amounts[0]; - amount1_ = _amounts[1]; - } else { - revert("Number of tokens do not match"); - } - - IUniswapV3Pool pool = IUniswapV3Pool( - computeAddress(uniswapFactoryAddr, key) - ); - - bytes memory data_ = abi.encode( - _tokens, - _amounts, - msg.sender, - key, - _data - ); - dataHash = bytes32(keccak256(data_)); - pool.flash(address(this), amount0_, amount1_, data_); + ) external { + spell(UNISWAP_IMP, msg.data); } /** @@ -268,16 +59,16 @@ contract FlashAggregatorArbitrum is Helper { uint256 _route, bytes calldata _data, bytes memory _instadata - ) external reentrancy { + ) external { require(_tokens.length == _amounts.length, "array-lengths-not-same"); (_tokens, _amounts) = bubbleSort(_tokens, _amounts); validateTokens(_tokens); if (_route == 5) { - routeBalancer(_tokens, _amounts, _data); + spell(BALANCER_IMP, msg.data); } else if (_route == 8) { - routeUniswap(_tokens, _amounts, _data, _instadata); + spell(UNISWAP_IMP, msg.data); } else { revert("route-does-not-exist"); } From 4c64449057ff6d7bf5400b04e3a94b3afe276805 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Sun, 15 May 2022 02:26:36 +0400 Subject: [PATCH 09/20] Added implementation proxy - Avalanche --- .../avalanche/flashloan/implAave/main.sol | 90 +++++++++++++++++++ .../aggregator/avalanche/flashloan/main.sol | 59 ++---------- .../avalanche/flashloan/variables.sol | 9 +- 3 files changed, 100 insertions(+), 58 deletions(-) create mode 100644 contracts/aggregator/avalanche/flashloan/implAave/main.sol diff --git a/contracts/aggregator/avalanche/flashloan/implAave/main.sol b/contracts/aggregator/avalanche/flashloan/implAave/main.sol new file mode 100644 index 00000000..7ce12001 --- /dev/null +++ b/contracts/aggregator/avalanche/flashloan/implAave/main.sol @@ -0,0 +1,90 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; +import "../helpers.sol"; + + +contract BalancerImplementation is Helper { + + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes calldata // kept for future use by instadapp. Currently not used anywhere. + ) external reentrancy { + require(_route == 1, "invalid AAVE route"); + routeAave(_tokens, _amounts, _data); + } + + /** + * @dev Callback function for aave flashloan. + * @notice Callback function for aave flashloan. + * @param _assets list of asset addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets for flashloan. + * @param _premiums list of premiums/fees for the corresponding addresses for flashloan. + * @param _initiator initiator address for flashloan. + * @param _data extra data passed. + */ + function executeOperation( + address[] memory _assets, + uint256[] memory _amounts, + uint256[] memory _premiums, + address _initiator, + bytes memory _data + ) external verifyDataHash(_data) returns (bool) { + require(_initiator == address(this), "not-same-sender"); + require(msg.sender == aaveLendingAddr, "not-aave-sender"); + + FlashloanVariables memory instaLoanVariables_; + + (address sender_, bytes memory data_) = abi.decode( + _data, + (address, bytes) + ); + + instaLoanVariables_._tokens = _assets; + instaLoanVariables_._amounts = _amounts; + instaLoanVariables_._instaFees = calculateFees(_amounts, calculateFeeBPS(1)); + instaLoanVariables_._iniBals = calculateBalances(_assets, address(this)); + + safeApprove(instaLoanVariables_, _premiums, aaveLendingAddr); + safeTransfer(instaLoanVariables_, sender_); + + if (checkIfDsa(sender_)) { + Address.functionCall(sender_, data_, "DSA-flashloan-fallback-failed"); + } else { + InstaFlashReceiverInterface(sender_).executeOperation(_assets, _amounts, instaLoanVariables_._instaFees, sender_, data_); + } + + instaLoanVariables_._finBals = calculateBalances(_assets, address(this)); + validateFlashloan(instaLoanVariables_); + + return true; + } + + /** + * @dev Middle function for route 1. + * @notice Middle function for route 1. + * @param _tokens list of token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets or amount of ether to borrow as collateral for flashloan. + * @param _data extra data passed. + */ + function routeAave(address[] memory _tokens, uint256[] memory _amounts, bytes memory _data) internal { + bytes memory data_ = abi.encode(msg.sender, _data); + uint length_ = _tokens.length; + uint[] memory _modes = new uint[](length_); + for (uint i = 0; i < length_; i++) { + _modes[i]=0; + } + dataHash = bytes32(keccak256(data_)); + aaveLending.flashLoan(address(this), _tokens, _amounts, _modes, address(0), data_, 3228); + } +} diff --git a/contracts/aggregator/avalanche/flashloan/main.sol b/contracts/aggregator/avalanche/flashloan/main.sol index 18d56664..383d1452 100644 --- a/contracts/aggregator/avalanche/flashloan/main.sol +++ b/contracts/aggregator/avalanche/flashloan/main.sol @@ -10,11 +10,8 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import { Helper } from "./helpers.sol"; - -import { - TokenInterface, - InstaFlashReceiverInterface -} from "./interfaces.sol"; +import { InstaFlashReceiverInterface } from "./interfaces.sol"; +import { TokenInterface } from "../../common/interface.sol"; contract FlashAggregatorAvalanche is Helper { using SafeERC20 for IERC20; @@ -41,53 +38,9 @@ contract FlashAggregatorAvalanche is Helper { uint256[] memory _premiums, address _initiator, bytes memory _data - ) external verifyDataHash(_data) returns (bool) { - require(_initiator == address(this), "not-same-sender"); - require(msg.sender == aaveLendingAddr, "not-aave-sender"); - - FlashloanVariables memory instaLoanVariables_; - - (address sender_, bytes memory data_) = abi.decode( - _data, - (address, bytes) - ); - - instaLoanVariables_._tokens = _assets; - instaLoanVariables_._amounts = _amounts; - instaLoanVariables_._instaFees = calculateFees(_amounts, calculateFeeBPS(1)); - instaLoanVariables_._iniBals = calculateBalances(_assets, address(this)); - - safeApprove(instaLoanVariables_, _premiums, aaveLendingAddr); - safeTransfer(instaLoanVariables_, sender_); - - if (checkIfDsa(sender_)) { - Address.functionCall(sender_, data_, "DSA-flashloan-fallback-failed"); - } else { - InstaFlashReceiverInterface(sender_).executeOperation(_assets, _amounts, instaLoanVariables_._instaFees, sender_, data_); - } - - instaLoanVariables_._finBals = calculateBalances(_assets, address(this)); - validateFlashloan(instaLoanVariables_); - - return true; - } - - /** - * @dev Middle function for route 1. - * @notice Middle function for route 1. - * @param _tokens list of token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets or amount of ether to borrow as collateral for flashloan. - * @param _data extra data passed. - */ - function routeAave(address[] memory _tokens, uint256[] memory _amounts, bytes memory _data) internal { - bytes memory data_ = abi.encode(msg.sender, _data); - uint length_ = _tokens.length; - uint[] memory _modes = new uint[](length_); - for (uint i = 0; i < length_; i++) { - _modes[i]=0; - } - dataHash = bytes32(keccak256(data_)); - aaveLending.flashLoan(address(this), _tokens, _amounts, _modes, address(0), data_, 3228); + ) external returns (bool) { + bytes memory response = spell(AAVE_IMP, msg.data); + return (abi.decode(response, (bool))); } /** @@ -112,7 +65,7 @@ contract FlashAggregatorAvalanche is Helper { validateTokens(_tokens); if (_route == 1) { - routeAave(_tokens, _amounts, _data); + spell(AAVE_IMP, msg.data); } else if (_route == 2) { revert("this route is only for mainnet"); } else if (_route == 3) { diff --git a/contracts/aggregator/avalanche/flashloan/variables.sol b/contracts/aggregator/avalanche/flashloan/variables.sol index 4fa2dbc5..a0f10cbd 100644 --- a/contracts/aggregator/avalanche/flashloan/variables.sol +++ b/contracts/aggregator/avalanche/flashloan/variables.sol @@ -1,11 +1,8 @@ //SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; -import { - IndexInterface, - ListInterface, - IAaveLending -} from "./interfaces.sol"; +import "./interfaces.sol"; +import "../../common/interface.sol"; contract ConstantVariables { @@ -34,4 +31,6 @@ contract Variables is ConstantVariables { uint256[] _instaFees; } + address internal AAVE_IMP; + } \ No newline at end of file From 2ab801947049a357a2fa32629b4a1458ad97da03 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Sun, 15 May 2022 16:05:38 +0400 Subject: [PATCH 10/20] Added implementation proxy - Optimism --- .../optimism/flashloan/implUniswap/main.sol | 174 ++++++++++++++++++ .../aggregator/optimism/flashloan/main.sol | 136 +------------- .../optimism/flashloan/variables.sol | 3 + 3 files changed, 181 insertions(+), 132 deletions(-) create mode 100644 contracts/aggregator/optimism/flashloan/implUniswap/main.sol diff --git a/contracts/aggregator/optimism/flashloan/implUniswap/main.sol b/contracts/aggregator/optimism/flashloan/implUniswap/main.sol new file mode 100644 index 00000000..ab09c402 --- /dev/null +++ b/contracts/aggregator/optimism/flashloan/implUniswap/main.sol @@ -0,0 +1,174 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../helpers.sol"; + +contract BalancerImplementation is Helper { + + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes calldata _instadata + ) external reentrancy { + require(_route == 8, "invalid route for Uniswap"); + routeUniswap(_tokens, _amounts, _data, _instadata); + } + + /** + * @dev Middle function for route 8. + * @notice Middle function for route 8. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + * @param _instadata pool key encoded + */ + function routeUniswap( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data, + bytes memory _instadata + ) internal { + PoolKey memory key = abi.decode(_instadata, (PoolKey)); + + uint256 amount0_; + uint256 amount1_; + + if (_tokens.length == 1) { + require( + (_tokens[0] == key.token0 || _tokens[0] == key.token1), + "tokens-do-not-match-pool" + ); + if (_tokens[0] == key.token0) { + amount0_ = _amounts[0]; + } else { + amount1_ = _amounts[0]; + } + } else if (_tokens.length == 2) { + require( + (_tokens[0] == key.token0 && _tokens[1] == key.token1), + "tokens-do-not-match-pool" + ); + amount0_ = _amounts[0]; + amount1_ = _amounts[1]; + } else { + revert("Number of tokens do not match"); + } + + IUniswapV3Pool pool = IUniswapV3Pool( + computeAddress(uniswapFactoryAddr, key) + ); + + bytes memory data_ = abi.encode( + _tokens, + _amounts, + msg.sender, + key, + _data + ); + dataHash = bytes32(keccak256(data_)); + pool.flash(address(this), amount0_, amount1_, data_); + } + + struct UniswapFlashInfo { + address sender; + PoolKey key; + bytes data; + } + + /** + * @dev Callback function for uniswap flashloan. + * @notice Callback function for uniswap flashloan. + * @param fee0 The fee from calling flash for token0 + * @param fee1 The fee from calling flash for token1 + * @param data extra data passed(includes route info aswell). + */ + function uniswapV3FlashCallback( + uint256 fee0, + uint256 fee1, + bytes memory data + ) external verifyDataHash(data) { + FlashloanVariables memory instaLoanVariables_; + UniswapFlashInfo memory uniswapFlashData_; + ( + instaLoanVariables_._tokens, + instaLoanVariables_._amounts, + uniswapFlashData_.sender, + uniswapFlashData_.key, + uniswapFlashData_.data + ) = abi.decode(data, (address[], uint256[], address, PoolKey, bytes)); + + address pool = computeAddress( + uniswapFactoryAddr, + uniswapFlashData_.key + ); + require(msg.sender == pool, "invalid-sender"); + instaLoanVariables_._iniBals = calculateBalances( + instaLoanVariables_._tokens, + address(this) + ); + + uint256 feeBPS = uint256(uniswapFlashData_.key.fee / 100); + if (feeBPS < InstaFeeBPS) { + feeBPS = InstaFeeBPS; + } + + instaLoanVariables_._instaFees = calculateFees( + instaLoanVariables_._amounts, + feeBPS + ); + + safeTransfer(instaLoanVariables_, uniswapFlashData_.sender); + + if (checkIfDsa(uniswapFlashData_.sender)) { + Address.functionCall( + uniswapFlashData_.sender, + uniswapFlashData_.data, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(uniswapFlashData_.sender) + .executeOperation( + instaLoanVariables_._tokens, + instaLoanVariables_._amounts, + instaLoanVariables_._instaFees, + uniswapFlashData_.sender, + uniswapFlashData_.data + ); + } + + instaLoanVariables_._finBals = calculateBalances( + instaLoanVariables_._tokens, + address(this) + ); + + validateFlashloan(instaLoanVariables_); + uint256[] memory fees_; + if (instaLoanVariables_._tokens.length == 2) { + fees_ = new uint256[](2); + fees_[0] = fee0; + fees_[1] = fee1; + } else if ( + instaLoanVariables_._tokens[0] == uniswapFlashData_.key.token0 + ) { + fees_ = new uint256[](1); + fees_[0] = fee0; + } else { + fees_ = new uint256[](1); + fees_[0] = fee1; + } + safeTransferWithFee(instaLoanVariables_, fees_, msg.sender); + } + + + +} \ No newline at end of file diff --git a/contracts/aggregator/optimism/flashloan/main.sol b/contracts/aggregator/optimism/flashloan/main.sol index 3198ed3b..1dc2b653 100644 --- a/contracts/aggregator/optimism/flashloan/main.sol +++ b/contracts/aggregator/optimism/flashloan/main.sol @@ -31,132 +31,8 @@ contract FlashAggregatorOptimism is Helper { uint256 fee0, uint256 fee1, bytes memory data - ) external verifyDataHash(data) { - FlashloanVariables memory instaLoanVariables_; - UniswapFlashInfo memory uniswapFlashData_; - ( - instaLoanVariables_._tokens, - instaLoanVariables_._amounts, - uniswapFlashData_.sender, - uniswapFlashData_.key, - uniswapFlashData_.data - ) = abi.decode(data, (address[], uint256[], address, PoolKey, bytes)); - - address pool = computeAddress( - uniswapFactoryAddr, - uniswapFlashData_.key - ); - require(msg.sender == pool, "invalid-sender"); - instaLoanVariables_._iniBals = calculateBalances( - instaLoanVariables_._tokens, - address(this) - ); - - uint256 feeBPS = uint256(uniswapFlashData_.key.fee / 100); - if (feeBPS < InstaFeeBPS) { - feeBPS = InstaFeeBPS; - } - - instaLoanVariables_._instaFees = calculateFees( - instaLoanVariables_._amounts, - feeBPS - ); - - safeTransfer(instaLoanVariables_, uniswapFlashData_.sender); - - if (checkIfDsa(uniswapFlashData_.sender)) { - Address.functionCall( - uniswapFlashData_.sender, - uniswapFlashData_.data, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(uniswapFlashData_.sender) - .executeOperation( - instaLoanVariables_._tokens, - instaLoanVariables_._amounts, - instaLoanVariables_._instaFees, - uniswapFlashData_.sender, - uniswapFlashData_.data - ); - } - - instaLoanVariables_._finBals = calculateBalances( - instaLoanVariables_._tokens, - address(this) - ); - - validateFlashloan(instaLoanVariables_); - uint256[] memory fees_; - if (instaLoanVariables_._tokens.length == 2) { - fees_ = new uint256[](2); - fees_[0] = fee0; - fees_[1] = fee1; - } else if ( - instaLoanVariables_._tokens[0] == uniswapFlashData_.key.token0 - ) { - fees_ = new uint256[](1); - fees_[0] = fee0; - } else { - fees_ = new uint256[](1); - fees_[0] = fee1; - } - safeTransferWithFee(instaLoanVariables_, fees_, msg.sender); - } - - /** - * @dev Middle function for route 8. - * @notice Middle function for route 8. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - * @param _instadata pool key encoded - */ - function routeUniswap( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data, - bytes memory _instadata - ) internal { - PoolKey memory key = abi.decode(_instadata, (PoolKey)); - - uint256 amount0_; - uint256 amount1_; - - if (_tokens.length == 1) { - require( - (_tokens[0] == key.token0 || _tokens[0] == key.token1), - "tokens-do-not-match-pool" - ); - if (_tokens[0] == key.token0) { - amount0_ = _amounts[0]; - } else { - amount1_ = _amounts[0]; - } - } else if (_tokens.length == 2) { - require( - (_tokens[0] == key.token0 && _tokens[1] == key.token1), - "tokens-do-not-match-pool" - ); - amount0_ = _amounts[0]; - amount1_ = _amounts[1]; - } else { - revert("Number of tokens do not match"); - } - - IUniswapV3Pool pool = IUniswapV3Pool( - computeAddress(uniswapFactoryAddr, key) - ); - - bytes memory data_ = abi.encode( - _tokens, - _amounts, - msg.sender, - key, - _data - ); - dataHash = bytes32(keccak256(data_)); - pool.flash(address(this), amount0_, amount1_, data_); + ) external { + spell(UNISWAP_IMP, msg.data); } /** @@ -173,17 +49,13 @@ contract FlashAggregatorOptimism is Helper { uint256 _route, bytes calldata _data, bytes calldata _instadata - ) external reentrancy { + ) external { require(_tokens.length == _amounts.length, "array-lengths-not-same"); (_tokens, _amounts) = bubbleSort(_tokens, _amounts); validateTokens(_tokens); - if (_route == 8) { - routeUniswap(_tokens, _amounts, _data, _instadata); - } else { - revert("route-does-not-exist"); - } + spell(UNISWAP_IMP, msg.data); emit LogFlashloan(msg.sender, _route, _tokens, _amounts); } diff --git a/contracts/aggregator/optimism/flashloan/variables.sol b/contracts/aggregator/optimism/flashloan/variables.sol index 0cd3b06e..b8fffd4e 100644 --- a/contracts/aggregator/optimism/flashloan/variables.sol +++ b/contracts/aggregator/optimism/flashloan/variables.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import "./interfaces.sol"; +import "../../common/interface.sol"; contract ConstantVariables { address public constant treasuryAddr = @@ -37,4 +38,6 @@ contract Variables is ConstantVariables { address token1; uint24 fee; } + + address internal UNISWAP_IMP; } From 907b1ec5676a95c2b71ec01ed000dd7d17785bd5 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Sun, 15 May 2022 16:22:44 +0400 Subject: [PATCH 11/20] Added implementation proxy - Polygon --- .../polygon/flashloan/implAave/main.sol | 122 ++++++ .../polygon/flashloan/implBalancer/main.sol | 207 +++++++++ .../polygon/flashloan/implUniswap/main.sol | 175 ++++++++ .../aggregator/polygon/flashloan/main.sol | 393 +----------------- .../polygon/flashloan/variables.sol | 5 + 5 files changed, 521 insertions(+), 381 deletions(-) create mode 100644 contracts/aggregator/polygon/flashloan/implAave/main.sol create mode 100644 contracts/aggregator/polygon/flashloan/implBalancer/main.sol create mode 100644 contracts/aggregator/polygon/flashloan/implUniswap/main.sol diff --git a/contracts/aggregator/polygon/flashloan/implAave/main.sol b/contracts/aggregator/polygon/flashloan/implAave/main.sol new file mode 100644 index 00000000..be4c8f60 --- /dev/null +++ b/contracts/aggregator/polygon/flashloan/implAave/main.sol @@ -0,0 +1,122 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../helpers.sol"; + +contract AaveImplementation is Helper { + + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes calldata _instadata + ) external reentrancy { + require(_route == 1, "invalid route for Aave"); + routeAave(_tokens, _amounts, _data); + } + + /** + * @dev Callback function for aave flashloan. + * @notice Callback function for aave flashloan. + * @param _assets list of asset addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets for flashloan. + * @param _premiums list of premiums/fees for the corresponding addresses for flashloan. + * @param _initiator initiator address for flashloan. + * @param _data extra data passed. + */ + function executeOperation( + address[] memory _assets, + uint256[] memory _amounts, + uint256[] memory _premiums, + address _initiator, + bytes memory _data + ) external verifyDataHash(_data) returns (bool) { + require(_initiator == address(this), "not-same-sender"); + require(msg.sender == aaveLendingAddr, "not-aave-sender"); + + FlashloanVariables memory instaLoanVariables_; + + (address sender_, bytes memory data_) = abi.decode( + _data, + (address, bytes) + ); + + instaLoanVariables_._tokens = _assets; + instaLoanVariables_._amounts = _amounts; + instaLoanVariables_._instaFees = calculateFees( + _amounts, + calculateFeeBPS(1) + ); + instaLoanVariables_._iniBals = calculateBalances( + _assets, + address(this) + ); + + safeApprove(instaLoanVariables_, _premiums, aaveLendingAddr); + safeTransfer(instaLoanVariables_, sender_); + + if (checkIfDsa(sender_)) { + Address.functionCall( + sender_, + data_, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(sender_).executeOperation( + _assets, + _amounts, + instaLoanVariables_._instaFees, + sender_, + data_ + ); + } + + instaLoanVariables_._finBals = calculateBalances( + _assets, + address(this) + ); + validateFlashloan(instaLoanVariables_); + + return true; + } + + /** + * @dev Middle function for route 1. + * @notice Middle function for route 1. + * @param _tokens list of token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets or amount of ether to borrow as collateral for flashloan. + * @param _data extra data passed. + */ + function routeAave( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + bytes memory data_ = abi.encode(msg.sender, _data); + uint256 length_ = _tokens.length; + uint256[] memory _modes = new uint256[](length_); + for (uint256 i = 0; i < length_; i++) { + _modes[i] = 0; + } + dataHash = bytes32(keccak256(data_)); + aaveLending.flashLoan( + address(this), + _tokens, + _amounts, + _modes, + address(0), + data_, + 3228 + ); + } + +} \ No newline at end of file diff --git a/contracts/aggregator/polygon/flashloan/implBalancer/main.sol b/contracts/aggregator/polygon/flashloan/implBalancer/main.sol new file mode 100644 index 00000000..473b3e1e --- /dev/null +++ b/contracts/aggregator/polygon/flashloan/implBalancer/main.sol @@ -0,0 +1,207 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../helpers.sol"; + +contract BalancerImplementation is Helper { + + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes calldata _instadata + ) external reentrancy { + require(_route == 5 || _route == 7, "inavlid route for BALANCER"); + + if (_route == 5) { + routeBalancer(_tokens, _amounts, _data); + } else if (_route == 7) { + routeBalancerAave(_tokens, _amounts, _data); + } + } + + /** + * @dev Callback function for balancer flashloan. + * @notice Callback function for balancer flashloan. + * @param _amounts list of amounts for the corresponding assets or amount of ether to borrow as collateral for flashloan. + * @param _fees list of fees for the corresponding addresses for flashloan. + * @param _data extra data passed(includes route info aswell). + */ + function receiveFlashLoan( + IERC20[] memory, + uint256[] memory _amounts, + uint256[] memory _fees, + bytes memory _data + ) external verifyDataHash(_data) { + require(msg.sender == balancerLendingAddr, "not-balancer-sender"); + + FlashloanVariables memory instaLoanVariables_; + + ( + uint256 route_, + address[] memory tokens_, + uint256[] memory amounts_, + address sender_, + bytes memory data_ + ) = abi.decode(_data, (uint256, address[], uint256[], address, bytes)); + + instaLoanVariables_._tokens = tokens_; + instaLoanVariables_._amounts = amounts_; + instaLoanVariables_._iniBals = calculateBalances( + tokens_, + address(this) + ); + instaLoanVariables_._instaFees = calculateFees( + amounts_, + calculateFeeBPS(route_) + ); + + if (route_ == 5) { + safeTransfer(instaLoanVariables_, sender_); + + if (checkIfDsa(sender_)) { + Address.functionCall( + sender_, + data_, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(sender_).executeOperation( + tokens_, + amounts_, + instaLoanVariables_._instaFees, + sender_, + data_ + ); + } + + instaLoanVariables_._finBals = calculateBalances( + tokens_, + address(this) + ); + validateFlashloan(instaLoanVariables_); + safeTransferWithFee( + instaLoanVariables_, + _fees, + balancerLendingAddr + ); + } else if (route_ == 7) { + require(_fees[0] == 0, "flash-ETH-fee-not-0"); + + address[] memory wEthTokenList = new address[](1); + wEthTokenList[0] = wEthToken; + + aaveSupply(wEthTokenList, _amounts); + aaveBorrow(tokens_, amounts_); + safeTransfer(instaLoanVariables_, sender_); + + if (checkIfDsa(sender_)) { + Address.functionCall( + sender_, + data_, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(sender_).executeOperation( + tokens_, + amounts_, + instaLoanVariables_._instaFees, + sender_, + data_ + ); + } + + aavePayback(tokens_, amounts_); + aaveWithdraw(wEthTokenList, _amounts); + instaLoanVariables_._finBals = calculateBalances( + tokens_, + address(this) + ); + validateFlashloan(instaLoanVariables_); + instaLoanVariables_._amounts = _amounts; + instaLoanVariables_._tokens = wEthTokenList; + safeTransferWithFee( + instaLoanVariables_, + _fees, + balancerLendingAddr + ); + } else { + revert("wrong-route"); + } + } + + /** + * @dev Middle function for route 5. + * @notice Middle function for route 5. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + */ + function routeBalancer( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + uint256 length_ = _tokens.length; + IERC20[] memory tokens_ = new IERC20[](length_); + for (uint256 i = 0; i < length_; i++) { + tokens_[i] = IERC20(_tokens[i]); + } + bytes memory data_ = abi.encode( + 5, + _tokens, + _amounts, + msg.sender, + _data + ); + dataHash = bytes32(keccak256(data_)); + balancerLending.flashLoan( + InstaFlashReceiverInterface(address(this)), + tokens_, + _amounts, + data_ + ); + } + + /** + * @dev Middle function for route 7. + * @notice Middle function for route 7. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + */ + function routeBalancerAave( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data + ) internal { + bytes memory data_ = abi.encode( + 7, + _tokens, + _amounts, + msg.sender, + _data + ); + IERC20[] memory wethTokenList_ = new IERC20[](1); + uint256[] memory wethAmountList_ = new uint256[](1); + wethTokenList_[0] = IERC20(wEthToken); + wethAmountList_[0] = getWEthBorrowAmount(); + dataHash = bytes32(keccak256(data_)); + balancerLending.flashLoan( + InstaFlashReceiverInterface(address(this)), + wethTokenList_, + wethAmountList_, + data_ + ); + } + +} \ No newline at end of file diff --git a/contracts/aggregator/polygon/flashloan/implUniswap/main.sol b/contracts/aggregator/polygon/flashloan/implUniswap/main.sol new file mode 100644 index 00000000..1f17d788 --- /dev/null +++ b/contracts/aggregator/polygon/flashloan/implUniswap/main.sol @@ -0,0 +1,175 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../helpers.sol"; + +contract UniswapImplementation is Helper { + + /** + * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. + * @notice Main function for flashloan for all routes. Calls the middle functions according to routes. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _route route for flashloan. + * @param _data extra data passed. + */ + function flashLoan( + address[] memory _tokens, + uint256[] memory _amounts, + uint256 _route, + bytes calldata _data, + bytes calldata _instadata + ) external reentrancy { + require(_route == 8, "invalid route for UNISWAP"); + routeUniswap(_tokens, _amounts, _data, _instadata); + } + + struct UniswapFlashInfo { + address sender; + PoolKey key; + bytes data; + } + + /** + * @dev Callback function for uniswap flashloan. + * @notice Callback function for uniswap flashloan. + * @param fee0 The fee from calling flash for token0 + * @param fee1 The fee from calling flash for token1 + * @param data extra data passed(includes route info aswell). + */ + function uniswapV3FlashCallback( + uint256 fee0, + uint256 fee1, + bytes memory data + ) external verifyDataHash(data) { + FlashloanVariables memory instaLoanVariables_; + UniswapFlashInfo memory uniswapFlashData_; + + ( + instaLoanVariables_._tokens, + instaLoanVariables_._amounts, + uniswapFlashData_.sender, + uniswapFlashData_.key, + uniswapFlashData_.data + ) = abi.decode(data, (address[], uint256[], address, PoolKey, bytes)); + + address pool = computeAddress( + uniswapFactoryAddr, + uniswapFlashData_.key + ); + require(msg.sender == pool, "invalid-sender"); + + instaLoanVariables_._iniBals = calculateBalances( + instaLoanVariables_._tokens, + address(this) + ); + + uint256 feeBPS = uint256(uniswapFlashData_.key.fee / 100); + if (feeBPS < InstaFeeBPS) { + feeBPS = InstaFeeBPS; + } + + instaLoanVariables_._instaFees = calculateFees( + instaLoanVariables_._amounts, + feeBPS + ); + + safeTransfer(instaLoanVariables_, uniswapFlashData_.sender); + + if (checkIfDsa(uniswapFlashData_.sender)) { + Address.functionCall( + uniswapFlashData_.sender, + uniswapFlashData_.data, + "DSA-flashloan-fallback-failed" + ); + } else { + InstaFlashReceiverInterface(uniswapFlashData_.sender) + .executeOperation( + instaLoanVariables_._tokens, + instaLoanVariables_._amounts, + instaLoanVariables_._instaFees, + uniswapFlashData_.sender, + uniswapFlashData_.data + ); + } + + instaLoanVariables_._finBals = calculateBalances( + instaLoanVariables_._tokens, + address(this) + ); + + validateFlashloan(instaLoanVariables_); + + uint256[] memory fees_; + if (instaLoanVariables_._tokens.length == 2) { + fees_ = new uint256[](2); + fees_[0] = fee0; + fees_[1] = fee1; + } else if ( + instaLoanVariables_._tokens[0] == uniswapFlashData_.key.token0 + ) { + fees_ = new uint256[](1); + fees_[0] = fee0; + } else { + fees_ = new uint256[](1); + fees_[0] = fee1; + } + safeTransferWithFee(instaLoanVariables_, fees_, msg.sender); + } + + /** + * @dev Middle function for route 8. + * @notice Middle function for route 8. + * @param _tokens token addresses for flashloan. + * @param _amounts list of amounts for the corresponding assets. + * @param _data extra data passed. + *@param _instadata pool key encoded + */ + function routeUniswap( + address[] memory _tokens, + uint256[] memory _amounts, + bytes memory _data, + bytes memory _instadata + ) internal { + PoolKey memory key = abi.decode(_instadata, (PoolKey)); + + uint256 amount0_; + uint256 amount1_; + + if (_tokens.length == 1) { + require( + (_tokens[0] == key.token0 || _tokens[0] == key.token1), + "tokens-do-not-match-pool" + ); + if (_tokens[0] == key.token0) { + amount0_ = _amounts[0]; + } else { + amount1_ = _amounts[0]; + } + } else if (_tokens.length == 2) { + require( + (_tokens[0] == key.token0 && _tokens[1] == key.token1), + "tokens-do-not-match-pool" + ); + amount0_ = _amounts[0]; + amount1_ = _amounts[1]; + } else { + revert("Number of tokens do not match"); + } + + IUniswapV3Pool pool = IUniswapV3Pool( + computeAddress(uniswapFactoryAddr, key) + ); + + bytes memory data_ = abi.encode( + _tokens, + _amounts, + msg.sender, + key, + _data + ); + dataHash = bytes32(keccak256(data_)); + pool.flash(address(this), amount0_, amount1_, data_); + } + +} \ No newline at end of file diff --git a/contracts/aggregator/polygon/flashloan/main.sol b/contracts/aggregator/polygon/flashloan/main.sol index b4323e61..fe10a7b8 100644 --- a/contracts/aggregator/polygon/flashloan/main.sol +++ b/contracts/aggregator/polygon/flashloan/main.sol @@ -29,54 +29,9 @@ contract FlashAggregatorPolygon is Helper { uint256[] memory _premiums, address _initiator, bytes memory _data - ) external verifyDataHash(_data) returns (bool) { - require(_initiator == address(this), "not-same-sender"); - require(msg.sender == aaveLendingAddr, "not-aave-sender"); - - FlashloanVariables memory instaLoanVariables_; - - (address sender_, bytes memory data_) = abi.decode( - _data, - (address, bytes) - ); - - instaLoanVariables_._tokens = _assets; - instaLoanVariables_._amounts = _amounts; - instaLoanVariables_._instaFees = calculateFees( - _amounts, - calculateFeeBPS(1) - ); - instaLoanVariables_._iniBals = calculateBalances( - _assets, - address(this) - ); - - safeApprove(instaLoanVariables_, _premiums, aaveLendingAddr); - safeTransfer(instaLoanVariables_, sender_); - - if (checkIfDsa(sender_)) { - Address.functionCall( - sender_, - data_, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(sender_).executeOperation( - _assets, - _amounts, - instaLoanVariables_._instaFees, - sender_, - data_ - ); - } - - instaLoanVariables_._finBals = calculateBalances( - _assets, - address(this) - ); - validateFlashloan(instaLoanVariables_); - - return true; + ) external returns (bool) { + bytes memory response_ = spell(AAVE_IMP, msg.data); + return (abi.decode(response_, (bool))); } /** @@ -91,108 +46,8 @@ contract FlashAggregatorPolygon is Helper { uint256[] memory _amounts, uint256[] memory _fees, bytes memory _data - ) external verifyDataHash(_data) { - require(msg.sender == balancerLendingAddr, "not-balancer-sender"); - - FlashloanVariables memory instaLoanVariables_; - - ( - uint256 route_, - address[] memory tokens_, - uint256[] memory amounts_, - address sender_, - bytes memory data_ - ) = abi.decode(_data, (uint256, address[], uint256[], address, bytes)); - - instaLoanVariables_._tokens = tokens_; - instaLoanVariables_._amounts = amounts_; - instaLoanVariables_._iniBals = calculateBalances( - tokens_, - address(this) - ); - instaLoanVariables_._instaFees = calculateFees( - amounts_, - calculateFeeBPS(route_) - ); - - if (route_ == 5) { - safeTransfer(instaLoanVariables_, sender_); - - if (checkIfDsa(sender_)) { - Address.functionCall( - sender_, - data_, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(sender_).executeOperation( - tokens_, - amounts_, - instaLoanVariables_._instaFees, - sender_, - data_ - ); - } - - instaLoanVariables_._finBals = calculateBalances( - tokens_, - address(this) - ); - validateFlashloan(instaLoanVariables_); - safeTransferWithFee( - instaLoanVariables_, - _fees, - balancerLendingAddr - ); - } else if (route_ == 7) { - require(_fees[0] == 0, "flash-ETH-fee-not-0"); - - address[] memory wEthTokenList = new address[](1); - wEthTokenList[0] = wEthToken; - - aaveSupply(wEthTokenList, _amounts); - aaveBorrow(tokens_, amounts_); - safeTransfer(instaLoanVariables_, sender_); - - if (checkIfDsa(sender_)) { - Address.functionCall( - sender_, - data_, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(sender_).executeOperation( - tokens_, - amounts_, - instaLoanVariables_._instaFees, - sender_, - data_ - ); - } - - aavePayback(tokens_, amounts_); - aaveWithdraw(wEthTokenList, _amounts); - instaLoanVariables_._finBals = calculateBalances( - tokens_, - address(this) - ); - validateFlashloan(instaLoanVariables_); - instaLoanVariables_._amounts = _amounts; - instaLoanVariables_._tokens = wEthTokenList; - safeTransferWithFee( - instaLoanVariables_, - _fees, - balancerLendingAddr - ); - } else { - revert("wrong-route"); - } - } - - struct UniswapFlashInfo { - address sender; - PoolKey key; - bytes data; + ) external { + spell(BALANCER_IMP, msg.data); } /** @@ -206,230 +61,8 @@ contract FlashAggregatorPolygon is Helper { uint256 fee0, uint256 fee1, bytes memory data - ) external verifyDataHash(data) { - FlashloanVariables memory instaLoanVariables_; - UniswapFlashInfo memory uniswapFlashData_; - - ( - instaLoanVariables_._tokens, - instaLoanVariables_._amounts, - uniswapFlashData_.sender, - uniswapFlashData_.key, - uniswapFlashData_.data - ) = abi.decode(data, (address[], uint256[], address, PoolKey, bytes)); - - address pool = computeAddress( - uniswapFactoryAddr, - uniswapFlashData_.key - ); - require(msg.sender == pool, "invalid-sender"); - - instaLoanVariables_._iniBals = calculateBalances( - instaLoanVariables_._tokens, - address(this) - ); - - uint256 feeBPS = uint256(uniswapFlashData_.key.fee / 100); - if (feeBPS < InstaFeeBPS) { - feeBPS = InstaFeeBPS; - } - - instaLoanVariables_._instaFees = calculateFees( - instaLoanVariables_._amounts, - feeBPS - ); - - safeTransfer(instaLoanVariables_, uniswapFlashData_.sender); - - if (checkIfDsa(uniswapFlashData_.sender)) { - Address.functionCall( - uniswapFlashData_.sender, - uniswapFlashData_.data, - "DSA-flashloan-fallback-failed" - ); - } else { - InstaFlashReceiverInterface(uniswapFlashData_.sender) - .executeOperation( - instaLoanVariables_._tokens, - instaLoanVariables_._amounts, - instaLoanVariables_._instaFees, - uniswapFlashData_.sender, - uniswapFlashData_.data - ); - } - - instaLoanVariables_._finBals = calculateBalances( - instaLoanVariables_._tokens, - address(this) - ); - - validateFlashloan(instaLoanVariables_); - - uint256[] memory fees_; - if (instaLoanVariables_._tokens.length == 2) { - fees_ = new uint256[](2); - fees_[0] = fee0; - fees_[1] = fee1; - } else if ( - instaLoanVariables_._tokens[0] == uniswapFlashData_.key.token0 - ) { - fees_ = new uint256[](1); - fees_[0] = fee0; - } else { - fees_ = new uint256[](1); - fees_[0] = fee1; - } - safeTransferWithFee(instaLoanVariables_, fees_, msg.sender); - } - - /** - * @dev Middle function for route 1. - * @notice Middle function for route 1. - * @param _tokens list of token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets or amount of ether to borrow as collateral for flashloan. - * @param _data extra data passed. - */ - function routeAave( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - bytes memory data_ = abi.encode(msg.sender, _data); - uint256 length_ = _tokens.length; - uint256[] memory _modes = new uint256[](length_); - for (uint256 i = 0; i < length_; i++) { - _modes[i] = 0; - } - dataHash = bytes32(keccak256(data_)); - aaveLending.flashLoan( - address(this), - _tokens, - _amounts, - _modes, - address(0), - data_, - 3228 - ); - } - - /** - * @dev Middle function for route 5. - * @notice Middle function for route 5. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - */ - function routeBalancer( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - uint256 length_ = _tokens.length; - IERC20[] memory tokens_ = new IERC20[](length_); - for (uint256 i = 0; i < length_; i++) { - tokens_[i] = IERC20(_tokens[i]); - } - bytes memory data_ = abi.encode( - 5, - _tokens, - _amounts, - msg.sender, - _data - ); - dataHash = bytes32(keccak256(data_)); - balancerLending.flashLoan( - InstaFlashReceiverInterface(address(this)), - tokens_, - _amounts, - data_ - ); - } - - /** - * @dev Middle function for route 7. - * @notice Middle function for route 7. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - */ - function routeBalancerAave( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data - ) internal { - bytes memory data_ = abi.encode( - 7, - _tokens, - _amounts, - msg.sender, - _data - ); - IERC20[] memory wethTokenList_ = new IERC20[](1); - uint256[] memory wethAmountList_ = new uint256[](1); - wethTokenList_[0] = IERC20(wEthToken); - wethAmountList_[0] = getWEthBorrowAmount(); - dataHash = bytes32(keccak256(data_)); - balancerLending.flashLoan( - InstaFlashReceiverInterface(address(this)), - wethTokenList_, - wethAmountList_, - data_ - ); - } - - /** - * @dev Middle function for route 8. - * @notice Middle function for route 8. - * @param _tokens token addresses for flashloan. - * @param _amounts list of amounts for the corresponding assets. - * @param _data extra data passed. - *@param _instadata pool key encoded - */ - function routeUniswap( - address[] memory _tokens, - uint256[] memory _amounts, - bytes memory _data, - bytes memory _instadata - ) internal { - PoolKey memory key = abi.decode(_instadata, (PoolKey)); - - uint256 amount0_; - uint256 amount1_; - - if (_tokens.length == 1) { - require( - (_tokens[0] == key.token0 || _tokens[0] == key.token1), - "tokens-do-not-match-pool" - ); - if (_tokens[0] == key.token0) { - amount0_ = _amounts[0]; - } else { - amount1_ = _amounts[0]; - } - } else if (_tokens.length == 2) { - require( - (_tokens[0] == key.token0 && _tokens[1] == key.token1), - "tokens-do-not-match-pool" - ); - amount0_ = _amounts[0]; - amount1_ = _amounts[1]; - } else { - revert("Number of tokens do not match"); - } - - IUniswapV3Pool pool = IUniswapV3Pool( - computeAddress(uniswapFactoryAddr, key) - ); - - bytes memory data_ = abi.encode( - _tokens, - _amounts, - msg.sender, - key, - _data - ); - dataHash = bytes32(keccak256(data_)); - pool.flash(address(this), amount0_, amount1_, data_); + ) external { + spell(UNISWAP_IMP, msg.data); } /** @@ -446,20 +79,18 @@ contract FlashAggregatorPolygon is Helper { uint256 _route, bytes calldata _data, bytes calldata _instadata - ) external reentrancy { + ) external { require(_tokens.length == _amounts.length, "array-lengths-not-same"); (_tokens, _amounts) = bubbleSort(_tokens, _amounts); validateTokens(_tokens); if (_route == 1) { - routeAave(_tokens, _amounts, _data); - } else if (_route == 5) { - routeBalancer(_tokens, _amounts, _data); - } else if (_route == 7) { - routeBalancerAave(_tokens, _amounts, _data); + spell(AAVE_IMP, msg.data); + } else if (_route == 5 || _route == 7) { + spell(BALANCER_IMP, msg.data); } else if (_route == 8) { - routeUniswap(_tokens, _amounts, _data, _instadata); + spell(UNISWAP_IMP, msg.data); } else { revert("route-does-not-exist"); } diff --git a/contracts/aggregator/polygon/flashloan/variables.sol b/contracts/aggregator/polygon/flashloan/variables.sol index 9d533e3c..f71ffced 100644 --- a/contracts/aggregator/polygon/flashloan/variables.sol +++ b/contracts/aggregator/polygon/flashloan/variables.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import "./interfaces.sol"; +import "../../common/interface.sol"; contract ConstantVariables { address public constant aaveLendingAddr = @@ -50,4 +51,8 @@ contract Variables is ConstantVariables { address token1; uint24 fee; } + + address internal AAVE_IMP; + address internal BALANCER_IMP; + address internal UNISWAP_IMP; } From cd8a4845a462dce218758a43697769dab8b1dfdb Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Sun, 15 May 2022 17:06:48 +0400 Subject: [PATCH 12/20] code refactored --- .../aggregator/arbitrum/flashloan/helpers.sol | 83 +----------- .../arbitrum/flashloan/implBalancer/main.sol | 2 +- .../arbitrum/flashloan/implUniswap/main.sol | 2 +- .../arbitrum/flashloan/interfaces.sol | 32 ----- .../arbitrum/flashloan/variables.sol | 4 + .../avalanche/flashloan/helpers.sol | 73 +---------- .../avalanche/flashloan/implAave/main.sol | 4 +- .../avalanche/flashloan/interfaces.sol | 28 ---- .../aggregator/avalanche/flashloan/main.sol | 6 +- .../aggregator/mainnet/flashloan/helpers.sol | 121 +----------------- .../mainnet/flashloan}/implAave/main.sol | 6 +- .../mainnet/flashloan}/implBalancer/main.sol | 7 +- .../mainnet/flashloan}/implMaker/main.sol | 4 +- .../mainnet/flashloan/interfaces.sol | 32 ----- .../mainnet/flashloan/variables.sol | 1 + .../aggregator/optimism/flashloan/helpers.sol | 84 +----------- .../optimism/flashloan/implUniswap/main.sol | 4 +- .../optimism/flashloan/interfaces.sol | 32 ----- .../aggregator/polygon/flashloan/helpers.sol | 84 +----------- .../polygon/flashloan/implAave/main.sol | 2 +- .../polygon/flashloan/implBalancer/main.sol | 2 +- .../polygon/flashloan/implUniswap/main.sol | 2 +- .../polygon/flashloan/interfaces.sol | 32 ----- 23 files changed, 41 insertions(+), 606 deletions(-) rename contracts/{ => aggregator/mainnet/flashloan}/implAave/main.sol (97%) rename contracts/{ => aggregator/mainnet/flashloan}/implBalancer/main.sol (99%) rename contracts/{ => aggregator/mainnet/flashloan}/implMaker/main.sol (98%) diff --git a/contracts/aggregator/arbitrum/flashloan/helpers.sol b/contracts/aggregator/arbitrum/flashloan/helpers.sol index 1929b714..2ac4bd41 100644 --- a/contracts/aggregator/arbitrum/flashloan/helpers.sol +++ b/contracts/aggregator/arbitrum/flashloan/helpers.sol @@ -2,9 +2,10 @@ pragma solidity ^0.8.0; import "./variables.sol"; +import "../../common/helpers.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -contract Helper is Variables { +contract Helper is HelpersCommon, Variables { using SafeERC20 for IERC20; /** @@ -102,25 +103,6 @@ contract Helper is Variables { } } - /** - * @dev Calculates the balances.. - * @notice Calculates the balances of the account passed for the tokens. - * @param _tokens list of token addresses to calculate balance for. - * @param _account account to calculate balance for. - */ - function calculateBalances(address[] memory _tokens, address _account) - internal - view - returns (uint256[] memory) - { - uint256 _length = _tokens.length; - uint256[] memory balances_ = new uint256[](_length); - for (uint256 i = 0; i < _length; i++) { - IERC20 token = IERC20(_tokens[i]); - balances_[i] = token.balanceOf(_account); - } - return balances_; - } /** * @dev Validates if the receiver sent the correct amounts of funds. @@ -141,17 +123,6 @@ contract Helper is Variables { } } - /** - * @dev Validates if token addresses are unique. Just need to check adjacent tokens as the array was sorted first - * @notice Validates if token addresses are unique. - * @param _tokens list of token addresses. - */ - function validateTokens(address[] memory _tokens) internal pure { - for (uint256 i = 0; i < _tokens.length - 1; i++) { - require(_tokens[i] != _tokens[i + 1], "non-unique-tokens"); - } - } - /** * @dev Returns fee for the passed route in BPS. * @notice Returns fee for the passed route in BPS. 1 BPS == 0.01%. @@ -179,56 +150,6 @@ contract Helper is Variables { } } - /** - * @dev Calculate fees for the respective amounts and fee in BPS passed. - * @notice Calculate fees for the respective amounts and fee in BPS passed. 1 BPS == 0.01%. - * @param _amounts list of amounts. - * @param _BPS fee in BPS. - */ - function calculateFees(uint256[] memory _amounts, uint256 _BPS) - internal - pure - returns (uint256[] memory) - { - uint256 length_ = _amounts.length; - uint256[] memory InstaFees = new uint256[](length_); - for (uint256 i = 0; i < length_; i++) { - InstaFees[i] = (_amounts[i] * _BPS) / (10**4); - } - return InstaFees; - } - - /** - * @dev Sort the tokens and amounts arrays according to token addresses. - * @notice Sort the tokens and amounts arrays according to token addresses. - * @param _tokens list of token addresses. - * @param _amounts list of respective amounts. - */ - function bubbleSort(address[] memory _tokens, uint256[] memory _amounts) - internal - pure - returns (address[] memory, uint256[] memory) - { - for (uint256 i = 0; i < _tokens.length - 1; i++) { - for (uint256 j = 0; j < _tokens.length - i - 1; j++) { - if (_tokens[j] > _tokens[j + 1]) { - ( - _tokens[j], - _tokens[j + 1], - _amounts[j], - _amounts[j + 1] - ) = ( - _tokens[j + 1], - _tokens[j], - _amounts[j + 1], - _amounts[j] - ); - } - } - } - return (_tokens, _amounts); - } - /** * @dev Returns to true if the passed address is a DSA else returns false. * @notice Returns to true if the passed address is a DSA else returns false. diff --git a/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol b/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol index 849a2e15..df36e67b 100644 --- a/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol @@ -19,7 +19,7 @@ contract BalancerImplementation is Helper { bytes calldata _data, bytes memory _instadata ) external reentrancy { - require(_route == 5 , "invalid BALANCER flashloan route"); + require(_route == 5 , "invalid-BALANCER-route"); routeBalancer(_tokens, _amounts, _data); } diff --git a/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol index a6d1c759..00327815 100644 --- a/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol @@ -19,7 +19,7 @@ contract UniswapImplementation is Helper { bytes calldata _data, bytes memory _instadata ) external reentrancy { - require(_route == 8, "invalid UNISWAP flashloan route"); + require(_route == 8, "invalid-UNISWAP-route"); routeUniswap(_tokens, _amounts, _data, _instadata); } diff --git a/contracts/aggregator/arbitrum/flashloan/interfaces.sol b/contracts/aggregator/arbitrum/flashloan/interfaces.sol index 7c6dbacb..333d9a63 100644 --- a/contracts/aggregator/arbitrum/flashloan/interfaces.sol +++ b/contracts/aggregator/arbitrum/flashloan/interfaces.sol @@ -12,38 +12,6 @@ interface InstaFlashReceiverInterface { ) external returns (bool); } -interface IndexInterface { - function master() external view returns (address); - - function list() external view returns (address); -} - -interface ListInterface { - function accountID(address) external view returns (uint64); -} - -interface TokenInterface { - function approve(address, uint256) external; - - function transfer(address, uint256) external; - - function transferFrom( - address, - address, - uint256 - ) external; - - function deposit() external payable; - - function withdraw(uint256) external; - - function balanceOf(address) external view returns (uint256); - - function decimals() external view returns (uint256); - - function totalSupply() external view returns (uint256); -} - interface ProtocolFeesCollector { function getFlashLoanFeePercentage() external view returns (uint256); } diff --git a/contracts/aggregator/arbitrum/flashloan/variables.sol b/contracts/aggregator/arbitrum/flashloan/variables.sol index f790c033..2cd3d413 100644 --- a/contracts/aggregator/arbitrum/flashloan/variables.sol +++ b/contracts/aggregator/arbitrum/flashloan/variables.sol @@ -1,6 +1,7 @@ //SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import "../../common/interface.sol"; import "./interfaces.sol"; contract ConstantVariables { @@ -43,4 +44,7 @@ contract Variables is ConstantVariables { address token1; uint24 fee; } + + address internal BALANCER_IMP; + address internal UNISWAP_IMP; } diff --git a/contracts/aggregator/avalanche/flashloan/helpers.sol b/contracts/aggregator/avalanche/flashloan/helpers.sol index 779c45f1..d3e80cd2 100644 --- a/contracts/aggregator/avalanche/flashloan/helpers.sol +++ b/contracts/aggregator/avalanche/flashloan/helpers.sol @@ -2,16 +2,13 @@ pragma solidity ^0.8.0; import {Variables} from "./variables.sol"; - +import "../../common/helpers.sol"; +import "./interfaces.sol"; +import "../../common/interface.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { - TokenInterface, - InstaFlashReceiverInterface -} from "./interfaces.sol"; - -contract Helper is Variables { +contract Helper is HelpersCommon, Variables { using SafeERC20 for IERC20; /** @@ -70,25 +67,6 @@ contract Helper is Variables { } } - /** - * @dev Calculates the balances.. - * @notice Calculates the balances of the account passed for the tokens. - * @param _tokens list of token addresses to calculate balance for. - * @param _account account to calculate balance for. - */ - function calculateBalances( - address[] memory _tokens, - address _account - ) internal view returns (uint256[] memory) { - uint256 _length = _tokens.length; - uint256[] memory balances_ = new uint256[](_length); - for (uint i = 0; i < _length; i++) { - IERC20 token = IERC20(_tokens[i]); - balances_[i] = token.balanceOf(_account); - } - return balances_; - } - /** * @dev Validates if the receiver sent the correct amounts of funds. * @notice Validates if the receiver sent the correct amounts of funds. @@ -102,17 +80,6 @@ contract Helper is Variables { } } - /** - * @dev Validates if token addresses are unique. Just need to check adjacent tokens as the array was sorted first - * @notice Validates if token addresses are unique. - * @param _tokens list of token addresses. - */ - function validateTokens(address[] memory _tokens) internal pure { - for (uint i = 0; i < _tokens.length - 1; i++) { - require(_tokens[i] != _tokens[i+1], "non-unique-tokens"); - } - } - /** * @dev Returns fee for the passed route in BPS. * @notice Returns fee for the passed route in BPS. 1 BPS == 0.01%. @@ -130,38 +97,6 @@ contract Helper is Variables { } } - /** - * @dev Calculate fees for the respective amounts and fee in BPS passed. - * @notice Calculate fees for the respective amounts and fee in BPS passed. 1 BPS == 0.01%. - * @param _amounts list of amounts. - * @param _BPS fee in BPS. - */ - function calculateFees(uint256[] memory _amounts, uint256 _BPS) internal pure returns (uint256[] memory) { - uint256 length_ = _amounts.length; - uint256[] memory InstaFees = new uint256[](length_); - for (uint i = 0; i < length_; i++) { - InstaFees[i] = (_amounts[i] * _BPS) / (10 ** 4); - } - return InstaFees; - } - - /** - * @dev Sort the tokens and amounts arrays according to token addresses. - * @notice Sort the tokens and amounts arrays according to token addresses. - * @param _tokens list of token addresses. - * @param _amounts list of respective amounts. - */ - function bubbleSort(address[] memory _tokens, uint256[] memory _amounts) internal pure returns (address[] memory, uint256[] memory) { - for (uint256 i = 0; i < _tokens.length - 1; i++) { - for( uint256 j = 0; j < _tokens.length - i - 1 ; j++) { - if(_tokens[j] > _tokens[j+1]) { - (_tokens[j], _tokens[j+1], _amounts[j], _amounts[j+1]) = (_tokens[j+1], _tokens[j], _amounts[j+1], _amounts[j]); - } - } - } - return (_tokens, _amounts); - } - /** * @dev Returns to true if the passed address is a DSA else returns false. * @notice Returns to true if the passed address is a DSA else returns false. diff --git a/contracts/aggregator/avalanche/flashloan/implAave/main.sol b/contracts/aggregator/avalanche/flashloan/implAave/main.sol index 7ce12001..9916abfa 100644 --- a/contracts/aggregator/avalanche/flashloan/implAave/main.sol +++ b/contracts/aggregator/avalanche/flashloan/implAave/main.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "../helpers.sol"; -contract BalancerImplementation is Helper { +contract AaveImplementation is Helper { /** * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. @@ -20,7 +20,7 @@ contract BalancerImplementation is Helper { bytes calldata _data, bytes calldata // kept for future use by instadapp. Currently not used anywhere. ) external reentrancy { - require(_route == 1, "invalid AAVE route"); + require(_route == 1, "invalid-AAVE-route"); routeAave(_tokens, _amounts, _data); } diff --git a/contracts/aggregator/avalanche/flashloan/interfaces.sol b/contracts/aggregator/avalanche/flashloan/interfaces.sol index 5c226c95..61279c6e 100644 --- a/contracts/aggregator/avalanche/flashloan/interfaces.sol +++ b/contracts/aggregator/avalanche/flashloan/interfaces.sol @@ -12,34 +12,6 @@ interface InstaFlashReceiverInterface { ) external returns (bool); } -interface IndexInterface { - function master() external view returns (address); - - function list() external view returns (address); -} - -interface ListInterface { - function accountID(address) external view returns (uint64); -} - -interface TokenInterface { - function approve(address, uint256) external; - - function transfer(address, uint) external; - - function transferFrom(address, address, uint) external; - - function deposit() external payable; - - function withdraw(uint) external; - - function balanceOf(address) external view returns (uint256); - - function decimals() external view returns (uint256); - - function totalSupply() external view returns (uint256); -} - interface IAaveLending { function flashLoan( address receiverAddress, diff --git a/contracts/aggregator/avalanche/flashloan/main.sol b/contracts/aggregator/avalanche/flashloan/main.sol index 383d1452..f8b98242 100644 --- a/contracts/aggregator/avalanche/flashloan/main.sol +++ b/contracts/aggregator/avalanche/flashloan/main.sol @@ -6,9 +6,7 @@ pragma solidity ^0.8.0; * @dev Flashloan aggregator. */ -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/utils/Address.sol"; import { Helper } from "./helpers.sol"; import { InstaFlashReceiverInterface } from "./interfaces.sol"; import { TokenInterface } from "../../common/interface.sol"; @@ -39,8 +37,8 @@ contract FlashAggregatorAvalanche is Helper { address _initiator, bytes memory _data ) external returns (bool) { - bytes memory response = spell(AAVE_IMP, msg.data); - return (abi.decode(response, (bool))); + bytes memory response_ = spell(AAVE_IMP, msg.data); + return (abi.decode(response_, (bool))); } /** diff --git a/contracts/aggregator/mainnet/flashloan/helpers.sol b/contracts/aggregator/mainnet/flashloan/helpers.sol index 3b53b13a..6fb8ae4d 100644 --- a/contracts/aggregator/mainnet/flashloan/helpers.sol +++ b/contracts/aggregator/mainnet/flashloan/helpers.sol @@ -2,50 +2,24 @@ pragma solidity ^0.8.0; import "./variables.sol"; +import "../../common/helpers.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -contract Helper is Variables { +contract Helper is HelpersCommon, Variables { using SafeERC20 for IERC20; - /** - * @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 Approves the token to the spender address with allowance amount. * @notice Approves the token to the spender address with allowance amount. * @param token_ token for which allowance is to be given. * @param spender_ the address to which the allowance is to be given. * @param amount_ amount of token. - */ - function approve( - address token_, - address spender_, - uint256 amount_ - ) internal { + */ + function approve(address token_, address spender_, uint256 amount_) internal { TokenInterface tokenContract_ = TokenInterface(token_); - try tokenContract_.approve(spender_, amount_) {} catch { + try tokenContract_.approve(spender_, amount_) { + + } catch { IERC20 token = IERC20(token_); token.safeApprove(spender_, 0); token.safeApprove(spender_, amount_); @@ -127,26 +101,6 @@ contract Helper is Variables { } } - /** - * @dev Calculates the balances.. - * @notice Calculates the balances of the account passed for the tokens. - * @param _tokens list of token addresses to calculate balance for. - * @param _account account to calculate balance for. - */ - function calculateBalances(address[] memory _tokens, address _account) - internal - view - returns (uint256[] memory) - { - uint256 _length = _tokens.length; - uint256[] memory balances_ = new uint256[](_length); - for (uint256 i = 0; i < _length; i++) { - IERC20 token = IERC20(_tokens[i]); - balances_[i] = token.balanceOf(_account); - } - return balances_; - } - /** * @dev Validates if the receiver sent the correct amounts of funds. * @notice Validates if the receiver sent the correct amounts of funds. @@ -166,17 +120,6 @@ contract Helper is Variables { } } - /** - * @dev Validates if token addresses are unique. Just need to check adjacent tokens as the array was sorted first - * @notice Validates if token addresses are unique. - * @param _tokens list of token addresses. - */ - function validateTokens(address[] memory _tokens) internal pure { - for (uint256 i = 0; i < _tokens.length - 1; i++) { - require(_tokens[i] != _tokens[i + 1], "non-unique-tokens"); - } - } - /** * @dev Supply tokens for the amounts to compound. * @notice Supply tokens for the amounts to compound. @@ -388,56 +331,6 @@ contract Helper is Variables { } } - /** - * @dev Calculate fees for the respective amounts and fee in BPS passed. - * @notice Calculate fees for the respective amounts and fee in BPS passed. 1 BPS == 0.01%. - * @param _amounts list of amounts. - * @param _BPS fee in BPS. - */ - function calculateFees(uint256[] memory _amounts, uint256 _BPS) - internal - pure - returns (uint256[] memory) - { - uint256 length_ = _amounts.length; - uint256[] memory InstaFees = new uint256[](length_); - for (uint256 i = 0; i < length_; i++) { - InstaFees[i] = (_amounts[i] * _BPS) / (10**4); - } - return InstaFees; - } - - /** - * @dev Sort the tokens and amounts arrays according to token addresses. - * @notice Sort the tokens and amounts arrays according to token addresses. - * @param _tokens list of token addresses. - * @param _amounts list of respective amounts. - */ - function bubbleSort(address[] memory _tokens, uint256[] memory _amounts) - internal - pure - returns (address[] memory, uint256[] memory) - { - for (uint256 i = 0; i < _tokens.length - 1; i++) { - for (uint256 j = 0; j < _tokens.length - i - 1; j++) { - if (_tokens[j] > _tokens[j + 1]) { - ( - _tokens[j], - _tokens[j + 1], - _amounts[j], - _amounts[j + 1] - ) = ( - _tokens[j + 1], - _tokens[j], - _amounts[j + 1], - _amounts[j] - ); - } - } - } - return (_tokens, _amounts); - } - /** * @dev Returns to wEth amount to be borrowed. * @notice Returns to wEth amount to be borrowed. diff --git a/contracts/implAave/main.sol b/contracts/aggregator/mainnet/flashloan/implAave/main.sol similarity index 97% rename from contracts/implAave/main.sol rename to contracts/aggregator/mainnet/flashloan/implAave/main.sol index 053dca25..09359d83 100644 --- a/contracts/implAave/main.sol +++ b/contracts/aggregator/mainnet/flashloan/implAave/main.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; -import "../aggregator/mainnet/flashloan/helpers.sol"; +import "../helpers.sol"; contract AaveImplementation is Helper { @@ -19,7 +19,7 @@ contract AaveImplementation is Helper { bytes calldata _data, bytes calldata // kept for future use by instadapp. Currently not used anywhere. ) external reentrancy { - require(_route == 1, "invalid AAVE flashloan route"); + require(_route == 1, "invalid-AAVE-route"); routeAave(_tokens, _amounts, _data); } @@ -117,4 +117,4 @@ contract AaveImplementation is Helper { 3228 ); } -} \ No newline at end of file +} diff --git a/contracts/implBalancer/main.sol b/contracts/aggregator/mainnet/flashloan/implBalancer/main.sol similarity index 99% rename from contracts/implBalancer/main.sol rename to contracts/aggregator/mainnet/flashloan/implBalancer/main.sol index cb7bf0c9..e13185d0 100644 --- a/contracts/implBalancer/main.sol +++ b/contracts/aggregator/mainnet/flashloan/implBalancer/main.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; -import "../aggregator/mainnet/flashloan/helpers.sol"; +import "../helpers.sol"; contract BalancerImplementation is Helper { @@ -19,7 +19,7 @@ contract BalancerImplementation is Helper { bytes calldata _data, bytes calldata // kept for future use by instadapp. Currently not used anywhere. ) external reentrancy { - require(_route == 5 || _route == 6 || _route == 7, "invalid BALANCER flashloan route"); + require(_route == 5 || _route == 6 || _route == 7, "invalid-BALANCER-route"); if (_route == 5) { routeBalancer(_tokens, _amounts, _data); @@ -265,5 +265,4 @@ contract BalancerImplementation is Helper { data_ ); } - -} \ No newline at end of file +} diff --git a/contracts/implMaker/main.sol b/contracts/aggregator/mainnet/flashloan/implMaker/main.sol similarity index 98% rename from contracts/implMaker/main.sol rename to contracts/aggregator/mainnet/flashloan/implMaker/main.sol index c0565e2e..1586e21c 100644 --- a/contracts/implMaker/main.sol +++ b/contracts/aggregator/mainnet/flashloan/implMaker/main.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; -import "../aggregator/mainnet/flashloan/helpers.sol"; +import "../helpers.sol"; contract MakerImplementation is Helper { @@ -19,7 +19,7 @@ contract MakerImplementation is Helper { bytes calldata _data, bytes calldata // kept for future use by instadapp. Currently not used anywhere. ) external reentrancy { - require((_route == 2 || _route == 3 || _route == 4), "invalid MAKER flashloan route"); + require((_route == 2 || _route == 3 || _route == 4), "invalid-MAKER-route"); if (_route == 2) { routeMaker(_tokens[0], _amounts[0], _data); diff --git a/contracts/aggregator/mainnet/flashloan/interfaces.sol b/contracts/aggregator/mainnet/flashloan/interfaces.sol index 9516f055..4d3f4d70 100644 --- a/contracts/aggregator/mainnet/flashloan/interfaces.sol +++ b/contracts/aggregator/mainnet/flashloan/interfaces.sol @@ -13,38 +13,6 @@ interface InstaFlashReceiverInterface { ) external returns (bool); } -interface IndexInterface { - function master() external view returns (address); - - function list() external view returns (address); -} - -interface ListInterface { - function accountID(address) external view returns (uint64); -} - -interface TokenInterface { - function approve(address, uint256) external; - - function transfer(address, uint256) external; - - function transferFrom( - address, - address, - uint256 - ) external; - - function deposit() external payable; - - function withdraw(uint256) external; - - function balanceOf(address) external view returns (uint256); - - function decimals() external view returns (uint256); - - function totalSupply() external view returns (uint256); -} - interface CTokenInterface { function mint(uint256) external returns (uint256); diff --git a/contracts/aggregator/mainnet/flashloan/variables.sol b/contracts/aggregator/mainnet/flashloan/variables.sol index 1dfbf80e..b97fa14c 100644 --- a/contracts/aggregator/mainnet/flashloan/variables.sol +++ b/contracts/aggregator/mainnet/flashloan/variables.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import "./interfaces.sol"; +import "../../common/interface.sol"; contract ConstantVariables { IWeth internal constant wethToken = diff --git a/contracts/aggregator/optimism/flashloan/helpers.sol b/contracts/aggregator/optimism/flashloan/helpers.sol index ebb04218..a4d92c3e 100644 --- a/contracts/aggregator/optimism/flashloan/helpers.sol +++ b/contracts/aggregator/optimism/flashloan/helpers.sol @@ -2,9 +2,10 @@ pragma solidity ^0.8.0; import "./variables.sol"; +import "../../common/helpers.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -contract Helper is Variables { +contract Helper is HelpersCommon, Variables { using SafeERC20 for IERC20; /** @@ -102,26 +103,6 @@ contract Helper is Variables { } } - /** - * @dev Calculates the balances.. - * @notice Calculates the balances of the account passed for the tokens. - * @param _tokens list of token addresses to calculate balance for. - * @param _account account to calculate balances for. - */ - function calculateBalances(address[] memory _tokens, address _account) - internal - view - returns (uint256[] memory) - { - uint256 _length = _tokens.length; - uint256[] memory balances_ = new uint256[](_length); - for (uint256 i = 0; i < _length; i++) { - IERC20 token = IERC20(_tokens[i]); - balances_[i] = token.balanceOf(_account); - } - return balances_; - } - /** * @dev Validates if the receiver sent the correct amounts of funds. * @notice Validates if the receiver sent the correct amounts of funds. @@ -141,67 +122,6 @@ contract Helper is Variables { } } - /** - * @dev Validates if token addresses are unique. Just need to check adjacent tokens as the array was sorted first - * @notice Validates if token addresses are unique. - * @param _tokens list of token addresses. - */ - function validateTokens(address[] memory _tokens) internal pure { - for (uint256 i = 0; i < _tokens.length - 1; i++) { - require(_tokens[i] != _tokens[i + 1], "non-unique-tokens"); - } - } - - /** - * @dev Calculate fees for the respective amounts and fee in BPS passed. - * @notice Calculate fees for the respective amounts and fee in BPS passed. 1 BPS == 0.01%. - * @param _amounts list of amounts. - * @param _BPS fee in BPS. - */ - function calculateFees(uint256[] memory _amounts, uint256 _BPS) - internal - pure - returns (uint256[] memory) - { - uint256 length_ = _amounts.length; - uint256[] memory InstaFees = new uint256[](length_); - for (uint256 i = 0; i < length_; i++) { - InstaFees[i] = (_amounts[i] * _BPS) / (10**4); - } - return InstaFees; - } - - /** - * @dev Sort the tokens and amounts arrays according to token addresses. - * @notice Sort the tokens and amounts arrays according to token addresses. - * @param _tokens list of token addresses. - * @param _amounts list of respective amounts. - */ - function bubbleSort(address[] memory _tokens, uint256[] memory _amounts) - internal - pure - returns (address[] memory, uint256[] memory) - { - for (uint256 i = 0; i < _tokens.length - 1; i++) { - for (uint256 j = 0; j < _tokens.length - i - 1; j++) { - if (_tokens[j] > _tokens[j + 1]) { - ( - _tokens[j], - _tokens[j + 1], - _amounts[j], - _amounts[j + 1] - ) = ( - _tokens[j + 1], - _tokens[j], - _amounts[j + 1], - _amounts[j] - ); - } - } - } - return (_tokens, _amounts); - } - /** * @dev Returns to true if the passed address is a DSA else returns false. * @notice Returns to true if the passed address is a DSA else returns false. diff --git a/contracts/aggregator/optimism/flashloan/implUniswap/main.sol b/contracts/aggregator/optimism/flashloan/implUniswap/main.sol index ab09c402..d69fd98b 100644 --- a/contracts/aggregator/optimism/flashloan/implUniswap/main.sol +++ b/contracts/aggregator/optimism/flashloan/implUniswap/main.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "../helpers.sol"; -contract BalancerImplementation is Helper { +contract UniswapImplementation is Helper { /** * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. @@ -20,7 +20,7 @@ contract BalancerImplementation is Helper { bytes calldata _data, bytes calldata _instadata ) external reentrancy { - require(_route == 8, "invalid route for Uniswap"); + require(_route == 8, "invalid-UNISWAP-route"); routeUniswap(_tokens, _amounts, _data, _instadata); } diff --git a/contracts/aggregator/optimism/flashloan/interfaces.sol b/contracts/aggregator/optimism/flashloan/interfaces.sol index 0a8c4c3d..5e63eebb 100644 --- a/contracts/aggregator/optimism/flashloan/interfaces.sol +++ b/contracts/aggregator/optimism/flashloan/interfaces.sol @@ -12,38 +12,6 @@ interface InstaFlashReceiverInterface { ) external returns (bool); } -interface IndexInterface { - function master() external view returns (address); - - function list() external view returns (address); -} - -interface ListInterface { - function accountID(address) external view returns (uint64); -} - -interface TokenInterface { - function approve(address, uint256) external; - - function transfer(address, uint256) external; - - function transferFrom( - address, - address, - uint256 - ) external; - - function deposit() external payable; - - function withdraw(uint256) external; - - function balanceOf(address) external view returns (uint256); - - function decimals() external view returns (uint256); - - function totalSupply() external view returns (uint256); -} - interface IUniswapV3Pool { function flash( address recipient, diff --git a/contracts/aggregator/polygon/flashloan/helpers.sol b/contracts/aggregator/polygon/flashloan/helpers.sol index 2f18ce0d..d1eeb83f 100644 --- a/contracts/aggregator/polygon/flashloan/helpers.sol +++ b/contracts/aggregator/polygon/flashloan/helpers.sol @@ -2,10 +2,11 @@ pragma solidity ^0.8.0; import "./variables.sol"; +import "../../common/helpers.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -contract Helper is Variables { +contract Helper is HelpersCommon, Variables { using SafeERC20 for IERC20; /** @@ -103,26 +104,6 @@ contract Helper is Variables { } } - /** - * @dev Calculates the balances.. - * @notice Calculates the balances of the account passed for the tokens. - * @param _tokens list of token addresses to calculate balance for. - * @param _account account to calculate balance for. - */ - function calculateBalances(address[] memory _tokens, address _account) - internal - view - returns (uint256[] memory) - { - uint256 _length = _tokens.length; - uint256[] memory balances_ = new uint256[](_length); - for (uint256 i = 0; i < _length; i++) { - IERC20 token = IERC20(_tokens[i]); - balances_[i] = token.balanceOf(_account); - } - return balances_; - } - /** * @dev Validates if the receiver sent the correct amounts of funds. * @notice Validates if the receiver sent the correct amounts of funds. @@ -142,17 +123,6 @@ contract Helper is Variables { } } - /** - * @dev Validates if token addresses are unique. Just need to check adjacent tokens as the array was sorted first - * @notice Validates if token addresses are unique. - * @param _tokens list of token addresses. - */ - function validateTokens(address[] memory _tokens) internal pure { - for (uint256 i = 0; i < _tokens.length - 1; i++) { - require(_tokens[i] != _tokens[i + 1], "non-unique-tokens"); - } - } - /** * @dev Supply tokens to aave. * @notice Supply tokens to aave. @@ -249,56 +219,6 @@ contract Helper is Variables { } } - /** - * @dev Calculate fees for the respective amounts and fee in BPS passed. - * @notice Calculate fees for the respective amounts and fee in BPS passed. 1 BPS == 0.01%. - * @param _amounts list of amounts. - * @param _BPS fee in BPS. - */ - function calculateFees(uint256[] memory _amounts, uint256 _BPS) - internal - pure - returns (uint256[] memory) - { - uint256 length_ = _amounts.length; - uint256[] memory InstaFees = new uint256[](length_); - for (uint256 i = 0; i < length_; i++) { - InstaFees[i] = (_amounts[i] * _BPS) / (10**4); - } - return InstaFees; - } - - /** - * @dev Sort the tokens and amounts arrays according to token addresses. - * @notice Sort the tokens and amounts arrays according to token addresses. - * @param _tokens list of token addresses. - * @param _amounts list of respective amounts. - */ - function bubbleSort(address[] memory _tokens, uint256[] memory _amounts) - internal - pure - returns (address[] memory, uint256[] memory) - { - for (uint256 i = 0; i < _tokens.length - 1; i++) { - for (uint256 j = 0; j < _tokens.length - i - 1; j++) { - if (_tokens[j] > _tokens[j + 1]) { - ( - _tokens[j], - _tokens[j + 1], - _amounts[j], - _amounts[j + 1] - ) = ( - _tokens[j + 1], - _tokens[j], - _amounts[j + 1], - _amounts[j] - ); - } - } - } - return (_tokens, _amounts); - } - /** * @dev Returns to wEth amount to be borrowed. * @notice Returns to wEth amount to be borrowed. diff --git a/contracts/aggregator/polygon/flashloan/implAave/main.sol b/contracts/aggregator/polygon/flashloan/implAave/main.sol index be4c8f60..282e23c1 100644 --- a/contracts/aggregator/polygon/flashloan/implAave/main.sol +++ b/contracts/aggregator/polygon/flashloan/implAave/main.sol @@ -20,7 +20,7 @@ contract AaveImplementation is Helper { bytes calldata _data, bytes calldata _instadata ) external reentrancy { - require(_route == 1, "invalid route for Aave"); + require(_route == 1, "invalid-AAVE-route"); routeAave(_tokens, _amounts, _data); } diff --git a/contracts/aggregator/polygon/flashloan/implBalancer/main.sol b/contracts/aggregator/polygon/flashloan/implBalancer/main.sol index 473b3e1e..825ebbf4 100644 --- a/contracts/aggregator/polygon/flashloan/implBalancer/main.sol +++ b/contracts/aggregator/polygon/flashloan/implBalancer/main.sol @@ -20,7 +20,7 @@ contract BalancerImplementation is Helper { bytes calldata _data, bytes calldata _instadata ) external reentrancy { - require(_route == 5 || _route == 7, "inavlid route for BALANCER"); + require(_route == 5 || _route == 7, "invalid-BALANCER-route"); if (_route == 5) { routeBalancer(_tokens, _amounts, _data); diff --git a/contracts/aggregator/polygon/flashloan/implUniswap/main.sol b/contracts/aggregator/polygon/flashloan/implUniswap/main.sol index 1f17d788..65750f06 100644 --- a/contracts/aggregator/polygon/flashloan/implUniswap/main.sol +++ b/contracts/aggregator/polygon/flashloan/implUniswap/main.sol @@ -20,7 +20,7 @@ contract UniswapImplementation is Helper { bytes calldata _data, bytes calldata _instadata ) external reentrancy { - require(_route == 8, "invalid route for UNISWAP"); + require(_route == 8, "invalid-UNISWAP-route"); routeUniswap(_tokens, _amounts, _data, _instadata); } diff --git a/contracts/aggregator/polygon/flashloan/interfaces.sol b/contracts/aggregator/polygon/flashloan/interfaces.sol index 866c7d12..94cae8b6 100644 --- a/contracts/aggregator/polygon/flashloan/interfaces.sol +++ b/contracts/aggregator/polygon/flashloan/interfaces.sol @@ -12,38 +12,6 @@ interface InstaFlashReceiverInterface { ) external returns (bool); } -interface IndexInterface { - function master() external view returns (address); - - function list() external view returns (address); -} - -interface ListInterface { - function accountID(address) external view returns (uint64); -} - -interface TokenInterface { - function approve(address, uint256) external; - - function transfer(address, uint256) external; - - function transferFrom( - address, - address, - uint256 - ) external; - - function deposit() external payable; - - function withdraw(uint256) external; - - function balanceOf(address) external view returns (uint256); - - function decimals() external view returns (uint256); - - function totalSupply() external view returns (uint256); -} - interface IAaveLending { function flashLoan( address receiverAddress, From 7c7e650f7d9a6487192688cb962b62dff7d8e4b5 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Thu, 19 May 2022 16:57:44 +0530 Subject: [PATCH 13/20] arbitrum updates + testcases --- .../arbitrum/flashloan/implBalancer/main.sol | 2 +- .../arbitrum/flashloan/implUniswap/main.sol | 2 +- .../aggregator/arbitrum/flashloan/main.sol | 16 +- .../arbitrum/flashloan/variables.sol | 4 +- test/arbitrum/newFlashloan.ts | 202 ++++++++++++++++++ 5 files changed, 216 insertions(+), 10 deletions(-) create mode 100644 test/arbitrum/newFlashloan.ts diff --git a/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol b/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol index df36e67b..21ed405d 100644 --- a/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import "../helpers.sol"; -contract BalancerImplementation is Helper { +contract BalancerImplementationArbitrum is Helper { /** * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. diff --git a/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol index 00327815..a4934469 100644 --- a/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import "../helpers.sol"; -contract UniswapImplementation is Helper { +contract UniswapImplementationArbitrum is Helper { /** * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. diff --git a/contracts/aggregator/arbitrum/flashloan/main.sol b/contracts/aggregator/arbitrum/flashloan/main.sol index c96d8c6c..3ce047dd 100644 --- a/contracts/aggregator/arbitrum/flashloan/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/main.sol @@ -1,8 +1,6 @@ //SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - import "./helpers.sol"; -import "@openzeppelin/contracts/utils/Address.sol"; contract FlashAggregatorArbitrum is Helper { using SafeERC20 for IERC20; @@ -27,7 +25,7 @@ contract FlashAggregatorArbitrum is Helper { uint256[] memory _fees, bytes memory _data ) external { - spell(BALANCER_IMP, msg.data); + spell(BALANCER_IMPL, msg.data); } /** @@ -42,7 +40,7 @@ contract FlashAggregatorArbitrum is Helper { uint256 fee1, bytes memory data ) external { - spell(UNISWAP_IMP, msg.data); + spell(UNISWAP_IMPL, msg.data); } /** @@ -66,9 +64,9 @@ contract FlashAggregatorArbitrum is Helper { validateTokens(_tokens); if (_route == 5) { - spell(BALANCER_IMP, msg.data); + spell(BALANCER_IMPL, msg.data); } else if (_route == 8) { - spell(UNISWAP_IMP, msg.data); + spell(UNISWAP_IMPL, msg.data); } else { revert("route-does-not-exist"); } @@ -118,5 +116,11 @@ contract InstaFlashAggregatorArbitrum is FlashAggregatorArbitrum { // status = 1; // } + + function initialize(address bImp, address uImp) public { + BALANCER_IMPL = bImp; + UNISWAP_IMPL = uImp; + } + receive() external payable {} } diff --git a/contracts/aggregator/arbitrum/flashloan/variables.sol b/contracts/aggregator/arbitrum/flashloan/variables.sol index 2cd3d413..5649b65c 100644 --- a/contracts/aggregator/arbitrum/flashloan/variables.sol +++ b/contracts/aggregator/arbitrum/flashloan/variables.sol @@ -45,6 +45,6 @@ contract Variables is ConstantVariables { uint24 fee; } - address internal BALANCER_IMP; - address internal UNISWAP_IMP; + address internal BALANCER_IMPL; + address internal UNISWAP_IMPL; } diff --git a/test/arbitrum/newFlashloan.ts b/test/arbitrum/newFlashloan.ts new file mode 100644 index 00000000..88a4b763 --- /dev/null +++ b/test/arbitrum/newFlashloan.ts @@ -0,0 +1,202 @@ +const hre = require('hardhat') +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +const { ethers } = hre + +import { + BalancerImplementationArbitrum__factory, + UniswapImplementationArbitrum__factory, + InstaFlashAggregatorProxy__factory, + IERC20__factory, + InstaFlashReceiver__factory, + InstaFlashReceiver, + InstaFlashAggregatorArbitrum__factory, + } from '../../typechain' + + describe('FlashLoan', function () { + let Aggregator, + aggregator, + Receiver, + receiver: InstaFlashReceiver, + BalancerImp, + UniswapImp, + balancerImpl, + uniswapImpl, + proxyAddr = "0x1f882522DF99820dF8e586b6df8bAae2b91a782d", + admin = "0x82D57efa1cE59A0cA3492e189c72B360c7a1Dcdd", + adminSigner; + + let signer: SignerWithAddress + + const master = '0xa8c31E39e40E6765BEdBd83D92D6AA0B33f1CCC5' + const aaveLendingAddr = '0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9' + + let iface = new ethers.utils.Interface(["function initialize(address bImp,address uImp)"]); + + const USDC = "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8"; + const USDT = "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9"; + const ACC_USDC = "0xce2cc46682e9c6d5f174af598fb4931a9c0be68e"; + const ACC_USDT = "0x0db3fe3b770c95a0b99d1ed6f2627933466c0dd8"; + + const usdc = ethers.utils.parseUnits("10", 6); + const usdt = ethers.utils.parseUnits("10", 6); + const Usdc = ethers.utils.parseUnits("5000", 6); + const Usdt = ethers.utils.parseUnits("5000", 6); + + const _data = '0x' + + let _instaData = '0x' + + beforeEach('Should set up', async function () { + ;[signer] = await ethers.getSigners() + + Aggregator = new InstaFlashAggregatorArbitrum__factory(signer) + aggregator = await Aggregator.deploy() + await aggregator.deployed() + console.log("aggregator: ", aggregator.address) + + BalancerImp = new BalancerImplementationArbitrum__factory(signer) + balancerImpl = await BalancerImp.deploy() + await balancerImpl.deployed() + console.log("balancerImpl: ", balancerImpl.address) + + UniswapImp = new UniswapImplementationArbitrum__factory(signer) + uniswapImpl = await UniswapImp.deploy() + await uniswapImpl.deployed() + console.log("uniswapImpl: ", uniswapImpl.address) + + const proxy = new ethers.Contract( + proxyAddr, + InstaFlashAggregatorProxy__factory.abi, + ethers.provider, + ) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [admin], + }) + + adminSigner = await ethers.getSigner(admin); + + await hre.network.provider.send('hardhat_setBalance', [ + admin, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + const dataNew = await iface.encodeFunctionData('initialize', [balancerImpl.address,uniswapImpl.address]) + console.log("dataNew: ", dataNew) + await proxy.connect(adminSigner).upgradeToAndCall(aggregator.address, dataNew); + + Receiver = new InstaFlashReceiver__factory(signer); + receiver = await Receiver.deploy(proxyAddr); + await receiver.deployed(); + console.log("receiver: ", receiver.address) + + const token_usdc = new ethers.Contract( + USDC, + IERC20__factory.abi, + ethers.provider + ); + + await hre.network.provider.send("hardhat_setBalance", [ + ACC_USDC, + ethers.utils.parseEther("10.0").toHexString(), + ]); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [ACC_USDC], + }); + + const signer_usdc = await ethers.getSigner(ACC_USDC); + await token_usdc.connect(signer_usdc).transfer(receiver.address, usdc); + + await hre.network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [ACC_USDC], + }); + _instaData = "0x"; + }) + + describe("Single token", async function () { + it("Should be able to take flashLoan of a single token from Balancer", async function () { + await receiver.flashBorrow([USDC], [Usdc], 5, _data, _instaData); + }); + }); + + describe("Uniswap Route", async function () { + beforeEach(async function () { + _instaData = await ethers.utils.defaultAbiCoder.encode( + ["tuple(address, address, uint24)"], + [[USDT, USDC, "500"]] + ); + }); + it("Should be able to take flashLoan of a single token from Uniswap", async function () { + await receiver.flashBorrow([USDC], [Usdc], 8, _data, _instaData); + }); + }); + + describe("Multi token", async function () { + beforeEach(async function () { + const token = new ethers.Contract( + USDT, + IERC20__factory.abi, + ethers.provider + ); + + await hre.network.provider.send("hardhat_setBalance", [ + ACC_USDT, + ethers.utils.parseEther("10.0").toHexString(), + ]); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [ACC_USDT], + }); + + const signer_usdt = await ethers.getSigner(ACC_USDT); + await token.connect(signer_usdt).transfer(receiver.address, usdt); + + await hre.network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [ACC_USDT], + }); + _instaData = "0x"; + }); + it("Should be able to take flashLoan of multiple sorted tokens together from Balancer", async function () { + await receiver.flashBorrow( + [USDT, USDC], + [Usdt, Usdc], + 5, + _data, + _instaData + ); + }); + it("Should be able to take flashLoan of multiple unsorted tokens together from Balancer", async function () { + await receiver.flashBorrow( + [USDT, USDC], + [Usdc, Usdt], + 5, + _data, + _instaData + ); + }); + + describe("Uniswap Route", async function () { + beforeEach(async function () { + _instaData = await ethers.utils.defaultAbiCoder.encode( + ["tuple(address, address, uint24)"], + [[USDT, USDC, "500"]] + ); + }); + it("Should be able to take flashLoan of multiple tokens together from Uniswap", async function () { + await receiver.flashBorrow( + [USDT, USDC], + [Usdc, Usdt], + 8, + _data, + _instaData + ); + }); + }); + }); + }) From 4c232b19a28db60e50cd92c21bcf17a8c22f282a Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Fri, 20 May 2022 19:37:27 +0530 Subject: [PATCH 14/20] added sortTokens for uniswap key sorting --- contracts/aggregator/common/helpers.sol | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/contracts/aggregator/common/helpers.sol b/contracts/aggregator/common/helpers.sol index 853a461a..e1ba1740 100644 --- a/contracts/aggregator/common/helpers.sol +++ b/contracts/aggregator/common/helpers.sol @@ -111,4 +111,21 @@ contract HelpersCommon { } return (_tokens, _amounts); } + + /** + * @dev Sort the tokens and amounts arrays according to token addresses. + * @notice Sort the tokens and amounts arrays according to token addresses. + * @param _token0 address of token0. + * @param _token1 address of token1. + */ + function sortTokens(address _token0, address _token1) + internal + pure + returns (address, address) + { + if(_token1 < _token0) { + (_token0, _token1) = (_token1, _token0); + } + return (_token0 , _token1); + } } From 57b3aca7239782d49c0034a27b480a0c5da673a1 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Fri, 20 May 2022 19:42:56 +0530 Subject: [PATCH 15/20] minor updates + optimism testcases --- .../aggregator/optimism/flashloan/main.sol | 19 ++- .../optimism/flashloan/variables.sol | 2 +- test/optimism/newFlash.ts | 153 ++++++++++++++++++ 3 files changed, 163 insertions(+), 11 deletions(-) create mode 100644 test/optimism/newFlash.ts diff --git a/contracts/aggregator/optimism/flashloan/main.sol b/contracts/aggregator/optimism/flashloan/main.sol index 1dc2b653..c1ad2fb7 100644 --- a/contracts/aggregator/optimism/flashloan/main.sol +++ b/contracts/aggregator/optimism/flashloan/main.sol @@ -32,7 +32,7 @@ contract FlashAggregatorOptimism is Helper { uint256 fee1, bytes memory data ) external { - spell(UNISWAP_IMP, msg.data); + spell(UNISWAP_IMPL, msg.data); } /** @@ -51,11 +51,7 @@ contract FlashAggregatorOptimism is Helper { bytes calldata _instadata ) external { require(_tokens.length == _amounts.length, "array-lengths-not-same"); - - (_tokens, _amounts) = bubbleSort(_tokens, _amounts); - validateTokens(_tokens); - - spell(UNISWAP_IMP, msg.data); + spell(UNISWAP_IMPL, msg.data); emit LogFlashloan(msg.sender, _route, _tokens, _amounts); } @@ -93,10 +89,13 @@ contract FlashAggregatorOptimism is Helper { } contract InstaFlashAggregatorOptimism is FlashAggregatorOptimism { - function initialize() public { - require(status == 0, "cannot-call-again"); - status = 1; - } + // function initialize() public { + // require(status == 0, "cannot-call-again"); + // status = 1; + // } + // function initialize(address uniswap) public { + // UNISWAP_IMPL = uniswap; + // } receive() external payable {} } diff --git a/contracts/aggregator/optimism/flashloan/variables.sol b/contracts/aggregator/optimism/flashloan/variables.sol index b8fffd4e..6541ae2a 100644 --- a/contracts/aggregator/optimism/flashloan/variables.sol +++ b/contracts/aggregator/optimism/flashloan/variables.sol @@ -39,5 +39,5 @@ contract Variables is ConstantVariables { uint24 fee; } - address internal UNISWAP_IMP; + address internal UNISWAP_IMPL; } diff --git a/test/optimism/newFlash.ts b/test/optimism/newFlash.ts new file mode 100644 index 00000000..6ced1dc8 --- /dev/null +++ b/test/optimism/newFlash.ts @@ -0,0 +1,153 @@ +const hre = require('hardhat') +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +const { ethers } = hre + +import { + InstaFlashAggregatorOptimism__factory, + IERC20__factory, + InstaFlashReceiver__factory, + InstaFlashReceiver, + InstaFlashAggregatorProxy__factory, + UniswapImplementationOptimism, + UniswapImplementationOptimism__factory +} from '../../typechain' + +describe('FlashLoan', function () { + let Aggregator, + aggregator, + Receiver, + receiver: InstaFlashReceiver, + implUniswap : UniswapImplementationOptimism, + ImplUniswap, + proxyAddr = "0x84E6b05A089d5677A702cF61dc14335b4bE5b282", + admin = "0xd4e5e20ef32b4750d4cd185a8e970b89851e7775", + adminSigner + + let signer: SignerWithAddress + + const master = '0xa9061100d29C3C562a2e2421eb035741C1b42137' + + let ABI = ['function initialize(address)'] + let iface = new ethers.utils.Interface(ABI) + + const DAI = '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1' + const USDT = '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58' + const ACC_DAI = '0xadb35413ec50e0afe41039eac8b930d313e94fa4' + const ACC_USDT = '0x9d39fc627a6d9d9f8c831c16995b209548cc3401' + + const dai = ethers.utils.parseUnits('1000', 18) + const usdt = ethers.utils.parseUnits('1000', 6) + const Dai = ethers.utils.parseUnits('5000', 18) + const Usdt = ethers.utils.parseUnits('5000', 6) + + const _data = '0x' + + let _instaData = '0x' + + beforeEach(async function () { + ;[signer] = await ethers.getSigners() + Aggregator = new InstaFlashAggregatorOptimism__factory(signer) + aggregator = await Aggregator.deploy() + await aggregator.deployed() + + ImplUniswap = new UniswapImplementationOptimism__factory(signer) + implUniswap = await ImplUniswap.deploy() + await implUniswap.deployed() + + const proxy = new ethers.Contract( + proxyAddr, + InstaFlashAggregatorProxy__factory.abi, + ethers.provider, + ) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [admin], + }) + + adminSigner = await ethers.getSigner(admin); + + await hre.network.provider.send('hardhat_setBalance', [ + admin, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + const data = iface.encodeFunctionData('initialize',[implUniswap.address]) + console.log("data: ", data) + await proxy.connect(adminSigner).upgradeToAndCall(aggregator.address, data); + + Receiver = new InstaFlashReceiver__factory(signer) + receiver = await Receiver.deploy(proxy.address) + await receiver.deployed() + + const token_dai = new ethers.Contract( + DAI, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_DAI, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_DAI], + }) + + const signer_dai = await ethers.getSigner(ACC_DAI) + await token_dai.connect(signer_dai).transfer(receiver.address, dai) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_DAI], + }) + + _instaData = await ethers.utils.defaultAbiCoder.encode( + ['tuple(address, address, uint24)'], + [[USDT, DAI, '500']], + ) + }) + + describe('Single token', async function () { + it('Should be able to take flashLoan of a single token from Uniswap', async function () { + await receiver.flashBorrow([DAI], [Dai], 8, _data, _instaData) + }) + }) + + describe('Multi token', async function () { + beforeEach(async function () { + const token = new ethers.Contract( + USDT, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_USDT, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_USDT], + }) + + const signer_usdt = await ethers.getSigner(ACC_USDT) + await token.connect(signer_usdt).transfer(receiver.address, usdt) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_USDT], + }) + _instaData = await ethers.utils.defaultAbiCoder.encode( + ['tuple(address, address, uint24)'], + [[USDT, DAI, '500']], + ) + }) + it('Should be able to take flashLoan of multiple tokens together from Uniswap', async function () { + await receiver.flashBorrow([DAI, USDT], [Dai, Usdt], 8, _data, _instaData) + }) + }) +}) From 8ddef00a8a3fbc02e997ce0a8ccf1a3df0100c27 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Fri, 20 May 2022 19:45:33 +0530 Subject: [PATCH 16/20] bubbleSort added in new implementations --- .../arbitrum/flashloan/implBalancer/main.sol | 2 ++ .../arbitrum/flashloan/implUniswap/main.sol | 2 ++ contracts/aggregator/arbitrum/flashloan/main.sol | 16 +++++++++------- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol b/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol index 21ed405d..934b3451 100644 --- a/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/implBalancer/main.sol @@ -20,6 +20,8 @@ contract BalancerImplementationArbitrum is Helper { bytes memory _instadata ) external reentrancy { require(_route == 5 , "invalid-BALANCER-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); routeBalancer(_tokens, _amounts, _data); } diff --git a/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol index a4934469..dde48a5e 100644 --- a/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol @@ -20,6 +20,8 @@ contract UniswapImplementationArbitrum is Helper { bytes memory _instadata ) external reentrancy { require(_route == 8, "invalid-UNISWAP-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); routeUniswap(_tokens, _amounts, _data, _instadata); } diff --git a/contracts/aggregator/arbitrum/flashloan/main.sol b/contracts/aggregator/arbitrum/flashloan/main.sol index 3ce047dd..09c9c498 100644 --- a/contracts/aggregator/arbitrum/flashloan/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/main.sol @@ -1,5 +1,10 @@ //SPDX-License-Identifier: MIT pragma solidity ^0.8.0; + +/** + * @title Flashloan. + * @dev Flashloan aggregator for Arbitrum. + */ import "./helpers.sol"; contract FlashAggregatorArbitrum is Helper { @@ -60,9 +65,6 @@ contract FlashAggregatorArbitrum is Helper { ) external { require(_tokens.length == _amounts.length, "array-lengths-not-same"); - (_tokens, _amounts) = bubbleSort(_tokens, _amounts); - validateTokens(_tokens); - if (_route == 5) { spell(BALANCER_IMPL, msg.data); } else if (_route == 8) { @@ -117,10 +119,10 @@ contract InstaFlashAggregatorArbitrum is FlashAggregatorArbitrum { // } - function initialize(address bImp, address uImp) public { - BALANCER_IMPL = bImp; - UNISWAP_IMPL = uImp; - } + // function initialize(address bImp, address uImp) public { + // BALANCER_IMPL = bImp; + // UNISWAP_IMPL = uImp; + // } receive() external payable {} } From 6cd9969752ecfa5328d7a38e3a0e478916be293b Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Fri, 20 May 2022 19:54:36 +0530 Subject: [PATCH 17/20] minor updates on all chains --- .../avalanche/flashloan/implAave/main.sol | 5 +- .../aggregator/avalanche/flashloan/main.sol | 20 ++++---- .../mainnet/flashloan/implAave/main.sol | 2 + .../mainnet/flashloan/implBalancer/main.sol | 2 + .../mainnet/flashloan/implMaker/main.sol | 2 + .../aggregator/mainnet/flashloan/main.sol | 49 ++++++++----------- .../polygon/flashloan/implAave/main.sol | 2 + .../polygon/flashloan/implBalancer/main.sol | 2 + .../polygon/flashloan/implUniswap/main.sol | 2 + .../aggregator/polygon/flashloan/main.sol | 3 -- 10 files changed, 45 insertions(+), 44 deletions(-) diff --git a/contracts/aggregator/avalanche/flashloan/implAave/main.sol b/contracts/aggregator/avalanche/flashloan/implAave/main.sol index 9916abfa..7504067f 100644 --- a/contracts/aggregator/avalanche/flashloan/implAave/main.sol +++ b/contracts/aggregator/avalanche/flashloan/implAave/main.sol @@ -2,8 +2,7 @@ pragma solidity ^0.8.0; import "../helpers.sol"; - -contract AaveImplementation is Helper { +contract AaveImplementationAvalanche is Helper { /** * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. @@ -21,6 +20,8 @@ contract AaveImplementation is Helper { bytes calldata // kept for future use by instadapp. Currently not used anywhere. ) external reentrancy { require(_route == 1, "invalid-AAVE-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); routeAave(_tokens, _amounts, _data); } diff --git a/contracts/aggregator/avalanche/flashloan/main.sol b/contracts/aggregator/avalanche/flashloan/main.sol index f8b98242..053a1519 100644 --- a/contracts/aggregator/avalanche/flashloan/main.sol +++ b/contracts/aggregator/avalanche/flashloan/main.sol @@ -3,13 +3,9 @@ pragma solidity ^0.8.0; /** * @title Flashloan. - * @dev Flashloan aggregator. + * @dev Flashloan aggregator for Avalanche. */ - -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { Helper } from "./helpers.sol"; -import { InstaFlashReceiverInterface } from "./interfaces.sol"; -import { TokenInterface } from "../../common/interface.sol"; +import "./helpers.sol"; contract FlashAggregatorAvalanche is Helper { using SafeERC20 for IERC20; @@ -37,7 +33,7 @@ contract FlashAggregatorAvalanche is Helper { address _initiator, bytes memory _data ) external returns (bool) { - bytes memory response_ = spell(AAVE_IMP, msg.data); + bytes memory response_ = spell(AAVE_IMPL, msg.data); return (abi.decode(response_, (bool))); } @@ -55,15 +51,14 @@ contract FlashAggregatorAvalanche is Helper { uint256 _route, bytes calldata _data, bytes calldata // kept for future use by instadapp. Currently not used anywhere. - ) external reentrancy { - + ) external { require(_tokens.length == _amounts.length, "array-lengths-not-same"); (_tokens, _amounts) = bubbleSort(_tokens, _amounts); validateTokens(_tokens); if (_route == 1) { - spell(AAVE_IMP, msg.data); + spell(AAVE_IMPL, msg.data); } else if (_route == 2) { revert("this route is only for mainnet"); } else if (_route == 3) { @@ -76,6 +71,8 @@ contract FlashAggregatorAvalanche is Helper { revert("this route is only for mainnet"); } else if (_route == 7) { revert("this route is only for mainnet and polygon"); + } else if (_route == 8) { + revert("this route is only for arbitrum, polygon and optimism"); } else { revert("route-does-not-exist"); } @@ -117,9 +114,10 @@ contract InstaFlashAggregatorAvalanche is FlashAggregatorAvalanche { /* Deprecated */ - // function initialize() public { + // function initialize(address aave) public { // require(status == 0, "cannot-call-again"); // status = 1; + // AAVE_IMPL = aave; // } receive() external payable {} diff --git a/contracts/aggregator/mainnet/flashloan/implAave/main.sol b/contracts/aggregator/mainnet/flashloan/implAave/main.sol index 09359d83..cc14dcd3 100644 --- a/contracts/aggregator/mainnet/flashloan/implAave/main.sol +++ b/contracts/aggregator/mainnet/flashloan/implAave/main.sol @@ -20,6 +20,8 @@ contract AaveImplementation is Helper { bytes calldata // kept for future use by instadapp. Currently not used anywhere. ) external reentrancy { require(_route == 1, "invalid-AAVE-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); routeAave(_tokens, _amounts, _data); } diff --git a/contracts/aggregator/mainnet/flashloan/implBalancer/main.sol b/contracts/aggregator/mainnet/flashloan/implBalancer/main.sol index e13185d0..6ee1f141 100644 --- a/contracts/aggregator/mainnet/flashloan/implBalancer/main.sol +++ b/contracts/aggregator/mainnet/flashloan/implBalancer/main.sol @@ -20,6 +20,8 @@ contract BalancerImplementation is Helper { bytes calldata // kept for future use by instadapp. Currently not used anywhere. ) external reentrancy { require(_route == 5 || _route == 6 || _route == 7, "invalid-BALANCER-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); if (_route == 5) { routeBalancer(_tokens, _amounts, _data); diff --git a/contracts/aggregator/mainnet/flashloan/implMaker/main.sol b/contracts/aggregator/mainnet/flashloan/implMaker/main.sol index 1586e21c..90c23e4d 100644 --- a/contracts/aggregator/mainnet/flashloan/implMaker/main.sol +++ b/contracts/aggregator/mainnet/flashloan/implMaker/main.sol @@ -20,6 +20,8 @@ contract MakerImplementation is Helper { bytes calldata // kept for future use by instadapp. Currently not used anywhere. ) external reentrancy { require((_route == 2 || _route == 3 || _route == 4), "invalid-MAKER-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); if (_route == 2) { routeMaker(_tokens[0], _amounts[0], _data); diff --git a/contracts/aggregator/mainnet/flashloan/main.sol b/contracts/aggregator/mainnet/flashloan/main.sol index 9ca48d66..5cd65cbb 100644 --- a/contracts/aggregator/mainnet/flashloan/main.sol +++ b/contracts/aggregator/mainnet/flashloan/main.sol @@ -9,6 +9,7 @@ pragma solidity ^0.8.0; import "./helpers.sol"; import "@openzeppelin/contracts/utils/Address.sol"; + contract AdminModule is Helper { event updateOwnerLog(address indexed oldOwner, address indexed newOwner); @@ -82,12 +83,6 @@ contract FlashAggregator is Setups { uint256[] amounts ); - event LogCollectRevenue( - address to, - address[] tokens, - uint256[] amounts - ); - /** * @dev Callback function for aave flashloan. * @notice Callback function for aave flashloan. @@ -104,8 +99,8 @@ contract FlashAggregator is Setups { address _initiator, bytes memory _data ) external returns (bool) { - bytes memory response = spell(AAVE_IMP, msg.data); - return (abi.decode(response, (bool))); + bytes memory response_ = spell(AAVE_IMPL, msg.data); + return (abi.decode(response_, (bool))); } /** @@ -123,8 +118,8 @@ contract FlashAggregator is Setups { uint256 _fee, bytes calldata _data ) external returns (bytes32) { - bytes memory response = spell(MAKER_IMP, msg.data); - return (abi.decode(response, (bytes32))); + bytes memory response_ = spell(MAKER_IMPL, msg.data); + return (abi.decode(response_, (bytes32))); } /** @@ -140,7 +135,7 @@ contract FlashAggregator is Setups { uint256[] memory _fees, bytes memory _data ) external { - spell(BALANCER_IMP, msg.data); + spell(BALANCER_IMPL, msg.data); } /** @@ -160,23 +155,20 @@ contract FlashAggregator is Setups { ) external { require(_tokens.length == _amounts.length, "array-lengths-not-same"); - (_tokens, _amounts) = bubbleSort(_tokens, _amounts); - validateTokens(_tokens); - if (_route == 1) { - spell(AAVE_IMP, msg.data); + spell(AAVE_IMPL, msg.data); } else if (_route == 2) { - spell(MAKER_IMP, msg.data); + spell(MAKER_IMPL, msg.data); } else if (_route == 3) { - spell(MAKER_IMP, msg.data); + spell(MAKER_IMPL, msg.data); } else if (_route == 4) { - spell(MAKER_IMP, msg.data); + spell(MAKER_IMPL, msg.data); } else if (_route == 5) { - spell(BALANCER_IMP, msg.data); + spell(BALANCER_IMPL, msg.data); } else if (_route == 6) { - spell(BALANCER_IMP, msg.data); + spell(BALANCER_IMPL, msg.data); } else if (_route == 7) { - spell(BALANCER_IMP, msg.data); + spell(BALANCER_IMPL, msg.data); } else { revert("route-does-not-exist"); } @@ -204,8 +196,7 @@ contract FlashAggregator is Setups { * @notice Function to transfer fee to the treasury. Will be called manually. * @param _tokens token addresses for transferring fee to treasury. */ - function transferFee(address[] memory _tokens, address _to) public onlyOwner { - uint256[] memory _amts = new uint256[](_tokens.length); + function transferFeeToTreasury(address[] memory _tokens) public { for (uint256 i = 0; i < _tokens.length; i++) { IERC20 token_ = IERC20(_tokens[i]); uint256 decimals_ = TokenInterface(_tokens[i]).decimals(); @@ -214,13 +205,12 @@ contract FlashAggregator is Setups { : decimals_ > 7 ? 100 : 10; - _amts[i] = token_.balanceOf(address(this)) > amtToSub_ + uint256 amtToTransfer_ = token_.balanceOf(address(this)) > amtToSub_ ? (token_.balanceOf(address(this)) - amtToSub_) : 0; - if (_amts[i] > 0) - token_.safeTransfer(_to, _amts[i]); + if (amtToTransfer_ > 0) + token_.safeTransfer(treasuryAddr, amtToTransfer_); } - emit LogCollectRevenue(_to, _tokens, _amts); } } @@ -230,7 +220,7 @@ contract InstaFlashAggregator is FlashAggregator { /* Deprecated */ - // function initialize(address[] memory _ctokens, address owner_) public { + // function initialize(address[] memory _ctokens, address owner_, address aave, address balancer, address maker) public { // require(status == 0, "cannot-call-again"); // require(stETHStatus == 0, "only-once"); // require(ownerStatus == 0, "only-once"); @@ -248,6 +238,9 @@ contract InstaFlashAggregator is FlashAggregator { // ownerStatus = 1; // stETHStatus = 1; // status = 1; + // AAVE_IMPL = aave; + // BALANCER_IMPL = balancer; + // MAKER_IMPL = maker; // } receive() external payable {} diff --git a/contracts/aggregator/polygon/flashloan/implAave/main.sol b/contracts/aggregator/polygon/flashloan/implAave/main.sol index 282e23c1..e3a3078e 100644 --- a/contracts/aggregator/polygon/flashloan/implAave/main.sol +++ b/contracts/aggregator/polygon/flashloan/implAave/main.sol @@ -21,6 +21,8 @@ contract AaveImplementation is Helper { bytes calldata _instadata ) external reentrancy { require(_route == 1, "invalid-AAVE-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); routeAave(_tokens, _amounts, _data); } diff --git a/contracts/aggregator/polygon/flashloan/implBalancer/main.sol b/contracts/aggregator/polygon/flashloan/implBalancer/main.sol index 825ebbf4..be05ce96 100644 --- a/contracts/aggregator/polygon/flashloan/implBalancer/main.sol +++ b/contracts/aggregator/polygon/flashloan/implBalancer/main.sol @@ -21,6 +21,8 @@ contract BalancerImplementation is Helper { bytes calldata _instadata ) external reentrancy { require(_route == 5 || _route == 7, "invalid-BALANCER-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); if (_route == 5) { routeBalancer(_tokens, _amounts, _data); diff --git a/contracts/aggregator/polygon/flashloan/implUniswap/main.sol b/contracts/aggregator/polygon/flashloan/implUniswap/main.sol index 65750f06..17a48848 100644 --- a/contracts/aggregator/polygon/flashloan/implUniswap/main.sol +++ b/contracts/aggregator/polygon/flashloan/implUniswap/main.sol @@ -21,6 +21,8 @@ contract UniswapImplementation is Helper { bytes calldata _instadata ) external reentrancy { require(_route == 8, "invalid-UNISWAP-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); routeUniswap(_tokens, _amounts, _data, _instadata); } diff --git a/contracts/aggregator/polygon/flashloan/main.sol b/contracts/aggregator/polygon/flashloan/main.sol index fe10a7b8..4f266980 100644 --- a/contracts/aggregator/polygon/flashloan/main.sol +++ b/contracts/aggregator/polygon/flashloan/main.sol @@ -82,9 +82,6 @@ contract FlashAggregatorPolygon is Helper { ) external { require(_tokens.length == _amounts.length, "array-lengths-not-same"); - (_tokens, _amounts) = bubbleSort(_tokens, _amounts); - validateTokens(_tokens); - if (_route == 1) { spell(AAVE_IMP, msg.data); } else if (_route == 5 || _route == 7) { From 76ab257eb69a1e5366ae99c9bf138a9d5a32e43f Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Sat, 21 May 2022 02:08:56 +0530 Subject: [PATCH 18/20] polygon testcase + polygon updates --- .../polygon/flashloan/implAave/main.sol | 2 +- .../polygon/flashloan/implBalancer/main.sol | 2 +- .../polygon/flashloan/implUniswap/main.sol | 5 +- .../aggregator/polygon/flashloan/main.sol | 26 ++- .../polygon/flashloan/variables.sol | 6 +- test/polygon/newFlashloan.ts | 218 ++++++++++++++++++ 6 files changed, 246 insertions(+), 13 deletions(-) create mode 100644 test/polygon/newFlashloan.ts diff --git a/contracts/aggregator/polygon/flashloan/implAave/main.sol b/contracts/aggregator/polygon/flashloan/implAave/main.sol index e3a3078e..8ceb737b 100644 --- a/contracts/aggregator/polygon/flashloan/implAave/main.sol +++ b/contracts/aggregator/polygon/flashloan/implAave/main.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "../helpers.sol"; -contract AaveImplementation is Helper { +contract AaveImplementationPolygon is Helper { /** * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. diff --git a/contracts/aggregator/polygon/flashloan/implBalancer/main.sol b/contracts/aggregator/polygon/flashloan/implBalancer/main.sol index be05ce96..e2cd6573 100644 --- a/contracts/aggregator/polygon/flashloan/implBalancer/main.sol +++ b/contracts/aggregator/polygon/flashloan/implBalancer/main.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "../helpers.sol"; -contract BalancerImplementation is Helper { +contract BalancerImplementationPolygon is Helper { /** * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. diff --git a/contracts/aggregator/polygon/flashloan/implUniswap/main.sol b/contracts/aggregator/polygon/flashloan/implUniswap/main.sol index 17a48848..d807ecad 100644 --- a/contracts/aggregator/polygon/flashloan/implUniswap/main.sol +++ b/contracts/aggregator/polygon/flashloan/implUniswap/main.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "../helpers.sol"; -contract UniswapImplementation is Helper { +contract UniswapImplementationPolygon is Helper { /** * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. @@ -134,13 +134,14 @@ contract UniswapImplementation is Helper { bytes memory _instadata ) internal { PoolKey memory key = abi.decode(_instadata, (PoolKey)); + (key.token0, key.token1) = sortTokens(key.token0, key.token1); uint256 amount0_; uint256 amount1_; if (_tokens.length == 1) { require( - (_tokens[0] == key.token0 || _tokens[0] == key.token1), + (_tokens[0] == key.token0 ), "tokens-do-not-match-pool" ); if (_tokens[0] == key.token0) { diff --git a/contracts/aggregator/polygon/flashloan/main.sol b/contracts/aggregator/polygon/flashloan/main.sol index 4f266980..c4833300 100644 --- a/contracts/aggregator/polygon/flashloan/main.sol +++ b/contracts/aggregator/polygon/flashloan/main.sol @@ -1,6 +1,11 @@ //SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +/** + * @title Flashloan. + * @dev Flashloan aggregator for Polygon. + */ + import "./helpers.sol"; import "@openzeppelin/contracts/utils/Address.sol"; @@ -30,7 +35,7 @@ contract FlashAggregatorPolygon is Helper { address _initiator, bytes memory _data ) external returns (bool) { - bytes memory response_ = spell(AAVE_IMP, msg.data); + bytes memory response_ = spell(AAVE_IMPL, msg.data); return (abi.decode(response_, (bool))); } @@ -47,7 +52,7 @@ contract FlashAggregatorPolygon is Helper { uint256[] memory _fees, bytes memory _data ) external { - spell(BALANCER_IMP, msg.data); + spell(BALANCER_IMPL, msg.data); } /** @@ -62,7 +67,7 @@ contract FlashAggregatorPolygon is Helper { uint256 fee1, bytes memory data ) external { - spell(UNISWAP_IMP, msg.data); + spell(UNISWAP_IMPL, msg.data); } /** @@ -83,11 +88,13 @@ contract FlashAggregatorPolygon is Helper { require(_tokens.length == _amounts.length, "array-lengths-not-same"); if (_route == 1) { - spell(AAVE_IMP, msg.data); + spell(AAVE_IMPL, msg.data); } else if (_route == 5 || _route == 7) { - spell(BALANCER_IMP, msg.data); + spell(BALANCER_IMPL, msg.data); } else if (_route == 8) { - spell(UNISWAP_IMP, msg.data); + spell(UNISWAP_IMPL, msg.data); + } else if (_route == 2 || _route == 3 || _route == 4 || _route == 6) { + revert("this route is only for mainnet"); } else { revert("route-does-not-exist"); } @@ -139,5 +146,12 @@ contract InstaFlashAggregatorPolygon is FlashAggregatorPolygon { // status = 1; // } + //Function created for testing upgradable implementations + // function initialize(address aave, address balancer, address uniswap) public { + // AAVE_IMPL = aave; + // BALANCER_IMPL = balancer; + // UNISWAP_IMPL = uniswap; + // } + receive() external payable {} } diff --git a/contracts/aggregator/polygon/flashloan/variables.sol b/contracts/aggregator/polygon/flashloan/variables.sol index f71ffced..999bda49 100644 --- a/contracts/aggregator/polygon/flashloan/variables.sol +++ b/contracts/aggregator/polygon/flashloan/variables.sol @@ -52,7 +52,7 @@ contract Variables is ConstantVariables { uint24 fee; } - address internal AAVE_IMP; - address internal BALANCER_IMP; - address internal UNISWAP_IMP; + address internal AAVE_IMPL; + address internal BALANCER_IMPL; + address internal UNISWAP_IMPL; } diff --git a/test/polygon/newFlashloan.ts b/test/polygon/newFlashloan.ts new file mode 100644 index 00000000..f25a4e0e --- /dev/null +++ b/test/polygon/newFlashloan.ts @@ -0,0 +1,218 @@ +const hre = require('hardhat') +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +const { ethers } = hre + +import { + InstaFlashAggregatorPolygon__factory, + IERC20__factory, + InstaFlashReceiver__factory, + InstaFlashReceiver, + InstaFlashAggregatorProxy__factory, + UniswapImplementationPolygon__factory, + BalancerImplementationPolygon__factory, + AaveImplementationPolygon__factory +} from '../../typechain' + +describe('FlashLoan', function () { + let Aggregator, + aggregator, + Receiver, + receiver: InstaFlashReceiver, + implUniswap, + ImplUniswap, + implBalancer, + ImplBalancer, + implAave, + ImplAave, + proxyAddr = "0xB2A7F20D10A006B0bEA86Ce42F2524Fde5D6a0F4", + admin = "0x90cf378a297c7ef6dabed36ea5e112c6646bb3a4", + adminSigner + + let signer: SignerWithAddress + + const master = '0xa9061100d29C3C562a2e2421eb035741C1b42137' + + let ABI = ['function initialize(address aave, address balancer, address uniswap)'] + let iface = new ethers.utils.Interface(ABI) + + const DAI = '0x8f3cf7ad23cd3cadbd9735aff958023239c6a063' + const USDT = '0xc2132d05d31c914a87c6611c10748aeb04b58e8f' + const ACC_DAI = '0x4a35582a710e1f4b2030a3f826da20bfb6703c09' + const ACC_USDT = '0x0d0707963952f2fba59dd06f2b425ace40b492fe' + //dai < usdt + + const dai = ethers.utils.parseUnits('1000', 18) + const usdt = ethers.utils.parseUnits('1000', 6) + const Dai = ethers.utils.parseUnits('5000', 18) + const Usdt = ethers.utils.parseUnits('5000', 6) + + const _data = '0x' + + let _instaData = '0x' + + beforeEach(async function () { + ;[signer] = await ethers.getSigners() + Aggregator = new InstaFlashAggregatorPolygon__factory(signer) + aggregator = await Aggregator.deploy() + await aggregator.deployed() + console.log("aggregator deployed at: ", aggregator.address); + + ImplAave = new AaveImplementationPolygon__factory(signer) + implAave = await ImplAave.deploy() + await implAave.deployed() + console.log("implAave deployed at: ", implAave.address); + + ImplBalancer = new BalancerImplementationPolygon__factory(signer) + implBalancer = await ImplBalancer.deploy() + await implBalancer.deployed() + console.log("implBalancer deployed at: ", implBalancer.address); + + ImplUniswap = new UniswapImplementationPolygon__factory(signer) + implUniswap = await ImplUniswap.deploy() + await implUniswap.deployed() + console.log("implUniswap deployed at: ", implUniswap.address); + + const proxy = new ethers.Contract( + proxyAddr, + InstaFlashAggregatorProxy__factory.abi, + ethers.provider, + ) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [admin], + }) + + adminSigner = await ethers.getSigner(admin); + + await hre.network.provider.send('hardhat_setBalance', [ + admin, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + const data = iface.encodeFunctionData('initialize', [implAave.address, implBalancer.address,implUniswap.address]) + await proxy.connect(adminSigner).upgradeToAndCall(aggregator.address, data); + + Receiver = new InstaFlashReceiver__factory(signer) + receiver = await Receiver.deploy(proxy.address) + await receiver.deployed() + console.log("receiver deployed at: ", receiver.address); + + const token_dai = new ethers.Contract( + DAI, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_DAI, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_DAI], + }) + + const signer_dai = await ethers.getSigner(ACC_DAI) + await token_dai.connect(signer_dai).transfer(receiver.address, dai) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_DAI], + }) + _instaData = '0x' + }) + + describe('Single token', async function () { + it('Should be able to take flashLoan of a single token from AAVE', async function () { + await receiver.flashBorrow([DAI], [Dai], 1, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from Balancer', async function () { + await receiver.flashBorrow([DAI], [Dai], 5, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from AAVE(Balancer)', async function () { + await receiver.flashBorrow([DAI], [Dai], 7, _data, _instaData) + }) + + describe('Uniswap Route', async function () { + beforeEach(async function () { + _instaData = await ethers.utils.defaultAbiCoder.encode( + ['tuple(address, address, uint24)'], + [[DAI, USDT, '500']], + ) + }) + it('Should be able to take flashLoan of a single token from Uniswap', async function () { + await receiver.flashBorrow([DAI], [Dai], 8, _data, _instaData) + }) + }) + }) + + describe('Multi token', async function () { + beforeEach(async function () { + const token = new ethers.Contract( + USDT, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_USDT, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_USDT], + }) + + const signer_usdt = await ethers.getSigner(ACC_USDT) + await token.connect(signer_usdt).transfer(receiver.address, usdt) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_USDT], + }) + _instaData = '0x' + }) + it('Should be able to take flashLoan of multiple tokens together from AAVE', async function () { + await receiver.flashBorrow([DAI, USDT], [Dai, Usdt], 1, _data, _instaData) + }) + it('Should be able to take flashLoan of multiple sorted tokens together from Balancer', async function () { + await receiver.flashBorrow([DAI, USDT], [Dai, Usdt], 5, _data, _instaData) + }) + it('Should be able to take flashLoan of multiple unsorted tokens together from Balancer', async function () { + await receiver.flashBorrow([USDT, DAI], [Usdt, Dai], 5, _data, _instaData) + }) + it('Should be able to take flashLoan of multiple tokens together from AAVE(Balancer)', async function () { + await receiver.flashBorrow([DAI, USDT], [Dai, Usdt], 7, _data, _instaData) + }) + + describe('Uniswap Route', async function () { + beforeEach(async function () { + _instaData = await ethers.utils.defaultAbiCoder.encode( + ['tuple(address, address, uint24)'], + [[USDT, DAI, '500']], + ) + }) + it('Should be able to take flashLoan of multiple unsorted tokens together from Uniswap', async function () { + await receiver.flashBorrow( + [USDT, DAI], + [Usdt, Dai], + 8, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens sorted together from Uniswap', async function () { + await receiver.flashBorrow( + [DAI, USDT], + [Dai, Usdt], + 8, + _data, + _instaData, + ) + }) + }) + }) +}) From cc7ca71e67cc15e9adbb4e289ce82bf0f358a4d7 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Sat, 21 May 2022 02:26:48 +0530 Subject: [PATCH 19/20] Avalanche testcases + new updates --- README.md | 15 -- .../arbitrum/flashloan/implUniswap/main.sol | 1 + .../aggregator/arbitrum/flashloan/main.sol | 4 +- .../avalanche/flashloan/helpers.sol | 7 +- .../aggregator/avalanche/flashloan/main.sol | 3 +- .../avalanche/flashloan/variables.sol | 2 +- .../aggregator/polygon/flashloan/main.sol | 4 +- test/avalanche/newFlashloan.ts | 137 ++++++++++++++++++ 8 files changed, 147 insertions(+), 26 deletions(-) create mode 100644 test/avalanche/newFlashloan.ts diff --git a/README.md b/README.md index 88bd68b0..381da85e 100644 --- a/README.md +++ b/README.md @@ -47,18 +47,3 @@ Deploy the contracts to Hardhat Network: ```sh $ npm run deploy ``` - -## Syntax Highlighting - -If you use VSCode, you can enjoy syntax highlighting for your Solidity code via the -[vscode-solidity](https://github.com/juanfranblanco/vscode-solidity) extension. The recommended approach to set the -compiler version is to add the following fields to your VSCode user settings: - -```json -{ - "solidity.compileUsingRemoteVersion": "v0.8.4+commit.c7e474f2", - "solidity.defaultCompiler": "remote" -} -``` - -Where of course `v0.8.4+commit.c7e474f2` can be replaced with any other version. diff --git a/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol index dde48a5e..02b8f2c3 100644 --- a/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/implUniswap/main.sol @@ -133,6 +133,7 @@ contract UniswapImplementationArbitrum is Helper { bytes memory _instadata ) internal { PoolKey memory key = abi.decode(_instadata, (PoolKey)); + (key.token0, key.token1) = sortTokens(key.token0, key.token1); uint256 amount0_; uint256 amount1_; diff --git a/contracts/aggregator/arbitrum/flashloan/main.sol b/contracts/aggregator/arbitrum/flashloan/main.sol index 09c9c498..93e89cdc 100644 --- a/contracts/aggregator/arbitrum/flashloan/main.sol +++ b/contracts/aggregator/arbitrum/flashloan/main.sol @@ -118,7 +118,9 @@ contract InstaFlashAggregatorArbitrum is FlashAggregatorArbitrum { // status = 1; // } - + /** + * @dev Function created for testing upgradable implementations + */ // function initialize(address bImp, address uImp) public { // BALANCER_IMPL = bImp; // UNISWAP_IMPL = uImp; diff --git a/contracts/aggregator/avalanche/flashloan/helpers.sol b/contracts/aggregator/avalanche/flashloan/helpers.sol index d3e80cd2..7392e3dd 100644 --- a/contracts/aggregator/avalanche/flashloan/helpers.sol +++ b/contracts/aggregator/avalanche/flashloan/helpers.sol @@ -1,12 +1,7 @@ //SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; - -import {Variables} from "./variables.sol"; +import "./variables.sol"; import "../../common/helpers.sol"; -import "./interfaces.sol"; -import "../../common/interface.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract Helper is HelpersCommon, Variables { using SafeERC20 for IERC20; diff --git a/contracts/aggregator/avalanche/flashloan/main.sol b/contracts/aggregator/avalanche/flashloan/main.sol index 053a1519..642a0cc0 100644 --- a/contracts/aggregator/avalanche/flashloan/main.sol +++ b/contracts/aggregator/avalanche/flashloan/main.sol @@ -114,10 +114,9 @@ contract InstaFlashAggregatorAvalanche is FlashAggregatorAvalanche { /* Deprecated */ - // function initialize(address aave) public { + // function initialize() public { // require(status == 0, "cannot-call-again"); // status = 1; - // AAVE_IMPL = aave; // } receive() external payable {} diff --git a/contracts/aggregator/avalanche/flashloan/variables.sol b/contracts/aggregator/avalanche/flashloan/variables.sol index a0f10cbd..9e75fd6a 100644 --- a/contracts/aggregator/avalanche/flashloan/variables.sol +++ b/contracts/aggregator/avalanche/flashloan/variables.sol @@ -31,6 +31,6 @@ contract Variables is ConstantVariables { uint256[] _instaFees; } - address internal AAVE_IMP; + address internal AAVE_IMPL; } \ No newline at end of file diff --git a/contracts/aggregator/polygon/flashloan/main.sol b/contracts/aggregator/polygon/flashloan/main.sol index c4833300..61a642a8 100644 --- a/contracts/aggregator/polygon/flashloan/main.sol +++ b/contracts/aggregator/polygon/flashloan/main.sol @@ -146,7 +146,9 @@ contract InstaFlashAggregatorPolygon is FlashAggregatorPolygon { // status = 1; // } - //Function created for testing upgradable implementations + /** + * @dev Function created for testing upgradable implementations + */ // function initialize(address aave, address balancer, address uniswap) public { // AAVE_IMPL = aave; // BALANCER_IMPL = balancer; diff --git a/test/avalanche/newFlashloan.ts b/test/avalanche/newFlashloan.ts new file mode 100644 index 00000000..54e58fcf --- /dev/null +++ b/test/avalanche/newFlashloan.ts @@ -0,0 +1,137 @@ +const hre = require('hardhat') +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +const { ethers } = hre + +import { + InstaFlashAggregatorAvalanche__factory, + IERC20__factory, + InstaFlashReceiver__factory, + InstaFlashReceiver, + InstaFlashAggregatorProxy__factory, + AaveImplementationAvalanche, + AaveImplementationAvalanche__factory +} from '../../typechain' + +describe('FlashLoan', function () { + let Aggregator, + aggregator, + Receiver, + receiver: InstaFlashReceiver, + Proxy, + proxy, + ImplAave, + implAave, + proxyAddr = "0x2b65731A085B55DBe6c7DcC8D717Ac36c00F6d19", + admin = "0x7b0990a249a215c9a88ebec3849920e29725f2d0", + adminSigner + + let signer: SignerWithAddress + + const master = '0xa9061100d29C3C562a2e2421eb035741C1b42137' + + let ABI = ['function initialize(address aave)'] + let iface = new ethers.utils.Interface(ABI) + + const DAI = '0xd586e7f844cea2f87f50152665bcbc2c279d8d70' + const USDT = '0xc7198437980c041c805a1edcba50c1ce5db95118' + const ACC_DAI = '0xed2a7edd7413021d440b09d654f3b87712abab66' + const ACC_USDT = '0xed2a7edd7413021d440b09d654f3b87712abab66' + + const dai = ethers.utils.parseUnits('10', 18) + const usdt = ethers.utils.parseUnits('10', 6) + const Dai = ethers.utils.parseUnits('5000', 18) + const Usdt = ethers.utils.parseUnits('5000', 6) + + const zeroAddr = + '0x0000000000000000000000000000000000000000000000000000000000000000' + let _instaData = '' + + + beforeEach(async function () { + ;[signer] = await ethers.getSigners() + Aggregator = new InstaFlashAggregatorAvalanche__factory(signer) + aggregator = await Aggregator.deploy() + await aggregator.deployed() + console.log("aggregator: ", aggregator.address) + + ImplAave = new AaveImplementationAvalanche__factory(signer) + implAave = await ImplAave.deploy() + await implAave.deployed() + console.log("implAave: ", implAave.address) + + const data = iface.encodeFunctionData('initialize',[implAave.address]) + + Proxy = new InstaFlashAggregatorProxy__factory(signer) + proxy = await Proxy.deploy(aggregator.address, master, data) + await proxy.deployed() + console.log("proxy: ", proxy.address) + + Receiver = new InstaFlashReceiver__factory(signer) + receiver = await Receiver.deploy(proxy.address) + await receiver.deployed() + console.log("receiver: ", receiver.address) + + const token_dai = new ethers.Contract( + DAI, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_DAI, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_DAI], + }) + + const signer_dai = await ethers.getSigner(ACC_DAI) + await token_dai.connect(signer_dai).transfer(receiver.address, dai) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_DAI], + }) + _instaData = '0x' + }) + + describe('Single token', async function () { + it('Should be able to take flashLoan of a single token from AAVE', async function () { + await receiver.flashBorrow([DAI], [Dai], 1, zeroAddr,_instaData) + }) + }) + + describe('Multi token', async function () { + beforeEach(async function () { + const token = new ethers.Contract( + USDT, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_USDT, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_USDT], + }) + + const signer_usdt = await ethers.getSigner(ACC_USDT) + await token.connect(signer_usdt).transfer(receiver.address, usdt) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_USDT], + }) + _instaData = '0x' + }) + it('Should be able to take flashLoan of multiple tokens together from AAVE', async function () { + await receiver.flashBorrow([DAI, USDT], [Dai, Usdt], 1, zeroAddr,_instaData ) + }) + }) +}) From 3d93a5745d156200900b10657a81595bffd6c7f7 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Sat, 21 May 2022 02:43:39 +0530 Subject: [PATCH 20/20] minor updates --- .../aggregator/mainnet/flashloan/main.sol | 5 +- .../mainnet/flashloan/variables.sol | 6 +- .../optimism/flashloan/implUniswap/main.sol | 5 +- .../aggregator/optimism/flashloan/main.sol | 4 + test/arbitrum/newFlashloan.ts | 5 +- test/mainnet/newFlash.ts | 360 ++++++++++++++++++ test/mainnet/newFlashAggr.ts | 360 ------------------ test/polygon/flashloan.ts | 5 + 8 files changed, 380 insertions(+), 370 deletions(-) create mode 100644 test/mainnet/newFlash.ts delete mode 100644 test/mainnet/newFlashAggr.ts diff --git a/contracts/aggregator/mainnet/flashloan/main.sol b/contracts/aggregator/mainnet/flashloan/main.sol index 5cd65cbb..c57a33df 100644 --- a/contracts/aggregator/mainnet/flashloan/main.sol +++ b/contracts/aggregator/mainnet/flashloan/main.sol @@ -220,7 +220,7 @@ contract InstaFlashAggregator is FlashAggregator { /* Deprecated */ - // function initialize(address[] memory _ctokens, address owner_, address aave, address balancer, address maker) public { + // function initialize(address[] memory _ctokens, address owner_) public { // require(status == 0, "cannot-call-again"); // require(stETHStatus == 0, "only-once"); // require(ownerStatus == 0, "only-once"); @@ -238,9 +238,6 @@ contract InstaFlashAggregator is FlashAggregator { // ownerStatus = 1; // stETHStatus = 1; // status = 1; - // AAVE_IMPL = aave; - // BALANCER_IMPL = balancer; - // MAKER_IMPL = maker; // } receive() external payable {} diff --git a/contracts/aggregator/mainnet/flashloan/variables.sol b/contracts/aggregator/mainnet/flashloan/variables.sol index b97fa14c..483b3dbc 100644 --- a/contracts/aggregator/mainnet/flashloan/variables.sol +++ b/contracts/aggregator/mainnet/flashloan/variables.sol @@ -58,7 +58,7 @@ contract Variables is ConstantVariables { mapping(address => bool) public isWhitelisted; - address internal AAVE_IMP; - address internal MAKER_IMP; - address internal BALANCER_IMP; + address internal AAVE_IMPL; + address internal MAKER_IMPL; + address internal BALANCER_IMPL; } diff --git a/contracts/aggregator/optimism/flashloan/implUniswap/main.sol b/contracts/aggregator/optimism/flashloan/implUniswap/main.sol index d69fd98b..33c08aa4 100644 --- a/contracts/aggregator/optimism/flashloan/implUniswap/main.sol +++ b/contracts/aggregator/optimism/flashloan/implUniswap/main.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "../helpers.sol"; -contract UniswapImplementation is Helper { +contract UniswapImplementationOptimism is Helper { /** * @dev Main function for flashloan for all routes. Calls the middle functions according to routes. @@ -21,6 +21,8 @@ contract UniswapImplementation is Helper { bytes calldata _instadata ) external reentrancy { require(_route == 8, "invalid-UNISWAP-route"); + (_tokens, _amounts) = bubbleSort(_tokens, _amounts); + validateTokens(_tokens); routeUniswap(_tokens, _amounts, _data, _instadata); } @@ -39,6 +41,7 @@ contract UniswapImplementation is Helper { bytes memory _instadata ) internal { PoolKey memory key = abi.decode(_instadata, (PoolKey)); + (key.token0, key.token1) = sortTokens(key.token0, key.token1); uint256 amount0_; uint256 amount1_; diff --git a/contracts/aggregator/optimism/flashloan/main.sol b/contracts/aggregator/optimism/flashloan/main.sol index c1ad2fb7..6a91dc5f 100644 --- a/contracts/aggregator/optimism/flashloan/main.sol +++ b/contracts/aggregator/optimism/flashloan/main.sol @@ -93,6 +93,10 @@ contract InstaFlashAggregatorOptimism is FlashAggregatorOptimism { // require(status == 0, "cannot-call-again"); // status = 1; // } + + /** + * @dev Function created for testing upgradable implementations + */ // function initialize(address uniswap) public { // UNISWAP_IMPL = uniswap; // } diff --git a/test/arbitrum/newFlashloan.ts b/test/arbitrum/newFlashloan.ts index 88a4b763..11b0b53b 100644 --- a/test/arbitrum/newFlashloan.ts +++ b/test/arbitrum/newFlashloan.ts @@ -36,6 +36,7 @@ import { const USDT = "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9"; const ACC_USDC = "0xce2cc46682e9c6d5f174af598fb4931a9c0be68e"; const ACC_USDT = "0x0db3fe3b770c95a0b99d1ed6f2627933466c0dd8"; + //usdt < usdc const usdc = ethers.utils.parseUnits("10", 6); const usdt = ethers.utils.parseUnits("10", 6); @@ -173,7 +174,7 @@ import { }); it("Should be able to take flashLoan of multiple unsorted tokens together from Balancer", async function () { await receiver.flashBorrow( - [USDT, USDC], + [USDC, USDT], [Usdc, Usdt], 5, _data, @@ -191,7 +192,7 @@ import { it("Should be able to take flashLoan of multiple tokens together from Uniswap", async function () { await receiver.flashBorrow( [USDT, USDC], - [Usdc, Usdt], + [Usdt, Usdc], 8, _data, _instaData diff --git a/test/mainnet/newFlash.ts b/test/mainnet/newFlash.ts new file mode 100644 index 00000000..dbba0eca --- /dev/null +++ b/test/mainnet/newFlash.ts @@ -0,0 +1,360 @@ +const hre = require('hardhat') +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +const { ethers } = hre + +import { + InstaFlashAggregator, + InstaFlashAggregator__factory, + IERC20__factory, + IERC20, + InstaFlashReceiver__factory, + InstaFlashReceiver, + InstaFlashAggregatorProxy, + InstaFlashAggregatorProxy__factory, + AaveImplementation__factory, + AaveImplementation, + BalancerImplementation, + MakerImplementation, + BalancerImplementation__factory, + MakerImplementation__factory +} from '../../typechain' + +describe('FlashLoan', function () { + let Aggregator, + aggregator, + Receiver, + receiver: InstaFlashReceiver, + Proxy, + proxy: InstaFlashAggregatorProxy, + proxyA : AaveImplementation, + proxyB : BalancerImplementation, + proxyM : MakerImplementation, + ProxyA, + ProxyB, + ProxyM, + admin = "0xb208CDF8e1c319d0019397dceC8E0bA3Fb9A149F", + proxyAddr = "0x619Ad2D02dBeE6ebA3CDbDA3F98430410e892882", + adminSigner + + let signer: SignerWithAddress + + const master = '0xa8c31E39e40E6765BEdBd83D92D6AA0B33f1CCC5' + const aaveLendingAddr = '0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9' + + let ABI = ['function initialize(address[],address,address,address,address)'] + let iface = new ethers.utils.Interface(ABI) + + const DAI = '0x6b175474e89094c44da98b954eedeac495271d0f' + const USDT = '0xdac17f958d2ee523a2206206994597c13d831ec7' + const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' + const ACC_DAI = '0x9a7a9d980ed6239b89232c012e21f4c210f4bef1' + const ACC_USDT = '0x6D5Be15f9Aa170e207C043CDf8E0BaDbF2A48ed0' + const ACC_WETH = '0xe78388b4ce79068e89bf8aa7f218ef6b9ab0e9d0' + + const STETH = '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84' + const ACC_STETH = '0xdc24316b9ae028f1497c275eb9192a3ea0f67022' + + const dai = ethers.utils.parseUnits('10', 18) + const usdt = ethers.utils.parseUnits('10', 6) + const weth = ethers.utils.parseUnits('10', 18) + const Dai = ethers.utils.parseUnits('5000', 18) + const Usdt = ethers.utils.parseUnits('5000', 6) + const Weth = ethers.utils.parseUnits('1000', 18) + const steth = ethers.utils.parseUnits('1', 18) + const Steth = ethers.utils.parseUnits('100', 18) + + const _data = '0x' + + let _instaData = '0x' + + beforeEach(async function () { + ;[signer] = await ethers.getSigners() + + ProxyA = new AaveImplementation__factory(signer) + proxyA = await ProxyA.deploy() + await proxyA.deployed() + console.log("Aave proxy deployed at: ", proxyA.address); + + ProxyB = new BalancerImplementation__factory(signer) + proxyB = await ProxyB.deploy() + await proxyB.deployed() + console.log("Balancer proxy deployed at: ", proxyB.address); + + + ProxyM = new MakerImplementation__factory(signer) + proxyM = await ProxyM.deploy() + await proxyM.deployed() + console.log("Maker proxy deployed at: ", proxyM.address); + + + Aggregator = new InstaFlashAggregator__factory(signer) + aggregator = await Aggregator.deploy() + await aggregator.deployed() + console.log("aggregator deployed at: ", aggregator.address); + + const data = iface.encodeFunctionData('initialize', [ + [ + '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643', // DAI + '0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9', // USDT + '0x39AA39c021dfbaE8faC545936693aC917d5E7563', // USDC + '0xe65cdb6479bac1e22340e4e755fae7e509ecd06c', // AAVE + '0x6c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e', // BAT + '0x70e36f6bf80a52b3b46b3af8e106cc0ed743e8e4', // COMP + '0xface851a4921ce59e912d19329929ce6da6eb0c7', // LINK + '0x95b4ef2869ebd94beb4eee400a99824bf5dc325b', // MKR + '0x158079ee67fce2f58472a96584a73c7ab9ac95c1', // REP + '0x4b0181102a0112a2ef11abee5563bb4a3176c9d7', // SUSHI + '0x12392f67bdf24fae0af363c24ac620a2f67dad86', // TUSD + '0x35a18000230da775cac24873d00ff85bccded550', // UNI + '0xccf4429db6322d5c611ee964527d42e5d685dd6a', // WBTC2 + '0x80a2ae356fc9ef4305676f7a3e2ed04e12c33946', // YFI + '0xb3319f5d18bc0d84dd1b4825dcde5d5f7266d407', // ZRX + ],master,proxyA.address,proxyB.address,proxyM.address + ]) + + Proxy = new InstaFlashAggregatorProxy__factory(signer) + proxy = await Proxy.deploy(aggregator.address, master, data) + await proxy.deployed() + console.log("Proxy deployed at: ", proxy.address); + + + Receiver = new InstaFlashReceiver__factory(signer) + receiver = await Receiver.deploy(proxy.address) + await receiver.deployed() + console.log("receiver deployed at: ", receiver.address); + + const token_steth = new ethers.Contract( + STETH, + IERC20__factory.abi, + ethers.provider, + ) + + const token_dai = new ethers.Contract( + DAI, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_DAI, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_STETH, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.send('hardhat_setBalance', [ + proxy.address, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_DAI], + }) + + const signer_dai = await ethers.getSigner(ACC_DAI) + await token_dai.connect(signer_dai).transfer(receiver.address, dai) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_DAI], + }) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_STETH], + }) + + const signer_steth = await ethers.getSigner(ACC_STETH) + await token_steth.connect(signer_steth).transfer(receiver.address, steth) + await token_steth.connect(signer_steth).transfer(proxy.address, steth) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_STETH], + }) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [proxy.address], + }) + + const signer_fla = await ethers.getSigner(proxy.address) + await token_dai.connect(signer_fla).approve(aaveLendingAddr, 100) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [proxy.address], + }) + _instaData = '0x' + }) + + describe('Single token', async function () { + it('Should be able to take flashLoan of a single token from AAVE', async function () { + await receiver.flashBorrow([DAI], [Dai], 1, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from MakerDAO', async function () { + await receiver.flashBorrow([DAI], [Dai], 2, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from Compound(MakerDAO)', async function () { + await receiver.flashBorrow([DAI], [Dai], 3, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from AAVE(MakerDAO)', async function () { + await receiver.flashBorrow([DAI], [Dai], 4, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from Balancer', async function () { + await receiver.flashBorrow([DAI], [Dai], 5, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from Compound(Balancer)', async function () { + await receiver.flashBorrow([DAI], [Dai], 6, _data, _instaData) + }) + it('Should be able to take flashLoan of a single token from AAVE(Balancer)', async function () { + await receiver.flashBorrow([DAI], [Dai], 7, _data, _instaData) + }) + it('Should be able to take flashLoan of a steth token from AAVE(Balancer)', async function () { + await receiver.flashBorrow([STETH], [Steth], 5, _data, _instaData) + }) + }) + + describe('Multi token', async function () { + beforeEach(async function () { + const token_usdt = new ethers.Contract( + USDT, + IERC20__factory.abi, + ethers.provider, + ) + + const token_weth = new ethers.Contract( + WETH, + IERC20__factory.abi, + ethers.provider, + ) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_USDT, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.send('hardhat_setBalance', [ + ACC_WETH, + ethers.utils.parseEther('10.0').toHexString(), + ]) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_USDT], + }) + + const signer_usdt = await ethers.getSigner(ACC_USDT) + await token_usdt.connect(signer_usdt).transfer(receiver.address, usdt) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_USDT], + }) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [ACC_WETH], + }) + + const signer_weth = await ethers.getSigner(ACC_WETH) + await token_weth.connect(signer_weth).transfer(receiver.address, weth) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [ACC_WETH], + }) + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [proxy.address], + }) + + const signer_fla = await ethers.getSigner(proxy.address) + await token_usdt.connect(signer_fla).approve(aaveLendingAddr, 100) + + await hre.network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: [proxy.address], + }) + _instaData = '0x' + }) + + it('Should be able to take flashLoan of multiple tokens together from AAVE', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 1, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from MakerDAO', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 2, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from Compound(MakerDAO)', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 3, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from AAVE(MakerDAO)', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 4, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple sorted tokens together from Balancer', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 5, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple unsorted tokens together from Balancer', async function () { + await receiver.flashBorrow( + [USDT, DAI, WETH], + [Usdt, Dai, Weth], + 5, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from Compound(Balancer)', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 6, + _data, + _instaData, + ) + }) + it('Should be able to take flashLoan of multiple tokens together from AAVE(Balancer)', async function () { + await receiver.flashBorrow( + [DAI, USDT, WETH], + [Dai, Usdt, Weth], + 7, + _data, + _instaData, + ) + }) + }) +}) diff --git a/test/mainnet/newFlashAggr.ts b/test/mainnet/newFlashAggr.ts deleted file mode 100644 index 70cc657b..00000000 --- a/test/mainnet/newFlashAggr.ts +++ /dev/null @@ -1,360 +0,0 @@ -const hre = require('hardhat') -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' -const { ethers } = hre - - -import { - AaveImplementation, - BalancerImplementation, - MakerImplementation, - AaveImplementation__factory, - BalancerImplementation__factory, - MakerImplementation__factory, - InstaFlashAggregator, - InstaFlashAggregator__factory, - IERC20__factory, - IERC20, - InstaFlashReceiver__factory, - InstaFlashReceiver, - InstaFlashAggregatorProxy, - InstaFlashAggregatorProxy__factory, - } from '../../typechain' - - describe('FlashLoan', function () { - - let proxyA : AaveImplementation, - proxyB : BalancerImplementation, - proxyM : MakerImplementation, - aggregator : InstaFlashAggregator, - Proxy, - proxy: InstaFlashAggregatorProxy, - ProxyA, - ProxyB, - ProxyM, - aaveImp,BalancerImp,MakerImp, - Aggregator, - admin = "0xb208CDF8e1c319d0019397dceC8E0bA3Fb9A149F", - proxyAddr = "0x619Ad2D02dBeE6ebA3CDbDA3F98430410e892882", - Receiver, - receiver: InstaFlashReceiver - - let signer: SignerWithAddress - - const _data = '0x' - let _instaData = '0x' - const master = '0xa8c31E39e40E6765BEdBd83D92D6AA0B33f1CCC5' - const aaveLendingAddr = '0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9' - let ABI = ['function initialize(address[],address,address,address,address)'] - let iface = new ethers.utils.Interface(ABI) - - const DAI = '0x6b175474e89094c44da98b954eedeac495271d0f' - const USDT = '0xdac17f958d2ee523a2206206994597c13d831ec7' - const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' - const STETH = '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84' - - const ACC_DAI = '0x9a7a9d980ed6239b89232c012e21f4c210f4bef1' - const ACC_USDT = '0x6D5Be15f9Aa170e207C043CDf8E0BaDbF2A48ed0' - const ACC_WETH = '0xe78388b4ce79068e89bf8aa7f218ef6b9ab0e9d0' - const ACC_STETH = '0xdc24316b9ae028f1497c275eb9192a3ea0f67022' - - const dai = ethers.utils.parseUnits('10', 18) - const usdt = ethers.utils.parseUnits('10', 6) - const weth = ethers.utils.parseUnits('10', 18) - const Dai = ethers.utils.parseUnits('5000', 18) - const Usdt = ethers.utils.parseUnits('5000', 6) - const Weth = ethers.utils.parseUnits('1000', 18) - const steth = ethers.utils.parseUnits('1', 18) - const Steth = ethers.utils.parseUnits('100', 18) - - - beforeEach(async function () { - ;[signer] = await ethers.getSigners() - - ProxyA = new AaveImplementation__factory(signer) - proxyA = await ProxyA.deploy() - await proxyA.deployed() - console.log("Aave proxy deployed at: ", proxyA.address); - - - ProxyB = new BalancerImplementation__factory(signer) - proxyB = await ProxyB.deploy() - await proxyB.deployed() - console.log("Balancer proxy deployed at: ", proxyB.address); - - - ProxyM = new MakerImplementation__factory(signer) - proxyM = await ProxyM.deploy() - await proxyM.deployed() - console.log("Maker proxy deployed at: ", proxyM.address); - - - Aggregator = new InstaFlashAggregator__factory(signer) - aggregator = await Aggregator.deploy() - await aggregator.deployed() - console.log("Aggregator deployed at: ", aggregator.address); - - const data = iface.encodeFunctionData('initialize', [ - [ - '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643', // DAI - '0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9', // USDT - '0x39AA39c021dfbaE8faC545936693aC917d5E7563', // USDC - '0xe65cdb6479bac1e22340e4e755fae7e509ecd06c', // AAVE - '0x6c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e', // BAT - '0x70e36f6bf80a52b3b46b3af8e106cc0ed743e8e4', // COMP - '0xface851a4921ce59e912d19329929ce6da6eb0c7', // LINK - '0x95b4ef2869ebd94beb4eee400a99824bf5dc325b', // MKR - '0x158079ee67fce2f58472a96584a73c7ab9ac95c1', // REP - '0x4b0181102a0112a2ef11abee5563bb4a3176c9d7', // SUSHI - '0x12392f67bdf24fae0af363c24ac620a2f67dad86', // TUSD - '0x35a18000230da775cac24873d00ff85bccded550', // UNI - '0xccf4429db6322d5c611ee964527d42e5d685dd6a', // WBTC2 - '0x80a2ae356fc9ef4305676f7a3e2ed04e12c33946', // YFI - '0xb3319f5d18bc0d84dd1b4825dcde5d5f7266d407', // ZRX - ],master,proxyA.address,proxyB.address,proxyM.address - ]) - - Proxy = new InstaFlashAggregatorProxy__factory(signer) - proxy = await Proxy.deploy(aggregator.address, master, data) - await proxy.deployed() - console.log("Proxy deployed at: ", proxy.address); - - Receiver = new InstaFlashReceiver__factory(signer) - receiver = await Receiver.deploy(proxy.address) - await receiver.deployed() - console.log("Receiver deployed at: ", receiver.address); - - await hre.network.provider.send('hardhat_setBalance', [ - proxy.address, - ethers.utils.parseEther('10.0').toHexString(), - ]) - - const token_dai = new ethers.Contract( - DAI, - IERC20__factory.abi, - ethers.provider, - ) - - const token_steth = new ethers.Contract( - STETH, - IERC20__factory.abi, - ethers.provider, - ) - - await hre.network.provider.send('hardhat_setBalance', [ - ACC_DAI, - ethers.utils.parseEther('10.0').toHexString(), - ]) - - await hre.network.provider.send('hardhat_setBalance', [ - ACC_STETH, - ethers.utils.parseEther('10.0').toHexString(), - ]) - - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [ACC_DAI], - }) - - const signer_dai = await ethers.getSigner(ACC_DAI) - await token_dai.connect(signer_dai).transfer(receiver.address, dai) - - await hre.network.provider.request({ - method: 'hardhat_stopImpersonatingAccount', - params: [ACC_DAI], - }) - - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [ACC_STETH], - }) - - const signer_steth = await ethers.getSigner(ACC_STETH) - await token_steth.connect(signer_steth).transfer(receiver.address, steth) - await token_steth.connect(signer_steth).transfer(proxy.address, steth) - - await hre.network.provider.request({ - method: 'hardhat_stopImpersonatingAccount', - params: [ACC_STETH], - }) - - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [proxy.address], - }) - - const signer_fla = await ethers.getSigner(proxy.address) - await token_dai.connect(signer_fla).approve(aaveLendingAddr, 100) - - await hre.network.provider.request({ - method: 'hardhat_stopImpersonatingAccount', - params: [proxy.address], - }) - }) - - describe('Single token', async function () { - it('Should be able to take flashLoan of a single token from AAVE', async function () { - await receiver.flashBorrow([DAI], [Dai], 1, _data, _instaData) - }) - it('Should be able to take flashLoan of a single token from MakerDAO', async function () { - await receiver.flashBorrow([DAI], [Dai], 2, _data, _instaData) - }) - it('Should be able to take flashLoan of a single token from Compound(MakerDAO)', async function () { - await receiver.flashBorrow([DAI], [Dai], 3, _data, _instaData) - }) - it('Should be able to take flashLoan of a single token from AAVE(MakerDAO)', async function () { - await receiver.flashBorrow([DAI], [Dai], 4, _data, _instaData) - }) - it('Should be able to take flashLoan of a single token from Balancer', async function () { - await receiver.flashBorrow([DAI], [Dai], 5, _data, _instaData) - }) - it('Should be able to take flashLoan of a single token from Compound(Balancer)', async function () { - await receiver.flashBorrow([DAI], [Dai], 6, _data, _instaData) - }) - it('Should be able to take flashLoan of a single token from AAVE(Balancer)', async function () { - await receiver.flashBorrow([DAI], [Dai], 7, _data, _instaData) - }) - it('Should be able to take flashLoan of a steth token from AAVE(Balancer)', async function () { - await receiver.flashBorrow([STETH], [Steth], 5, _data, _instaData) - }) - }) - - describe('Multi token', async function () { - beforeEach(async function () { - const token_usdt = new ethers.Contract( - USDT, - IERC20__factory.abi, - ethers.provider, - ) - - const token_weth = new ethers.Contract( - WETH, - IERC20__factory.abi, - ethers.provider, - ) - - await hre.network.provider.send('hardhat_setBalance', [ - ACC_USDT, - ethers.utils.parseEther('10.0').toHexString(), - ]) - - await hre.network.provider.send('hardhat_setBalance', [ - ACC_WETH, - ethers.utils.parseEther('10.0').toHexString(), - ]) - - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [ACC_USDT], - }) - - const signer_usdt = await ethers.getSigner(ACC_USDT) - await token_usdt.connect(signer_usdt).transfer(receiver.address, usdt) - - await hre.network.provider.request({ - method: 'hardhat_stopImpersonatingAccount', - params: [ACC_USDT], - }) - - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [ACC_WETH], - }) - - const signer_weth = await ethers.getSigner(ACC_WETH) - await token_weth.connect(signer_weth).transfer(receiver.address, weth) - - await hre.network.provider.request({ - method: 'hardhat_stopImpersonatingAccount', - params: [ACC_WETH], - }) - - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [proxy.address], - }) - - const signer_fla = await ethers.getSigner(proxy.address) - await token_usdt.connect(signer_fla).approve(aaveLendingAddr, 100) - - await hre.network.provider.request({ - method: 'hardhat_stopImpersonatingAccount', - params: [proxy.address], - }) - _instaData = '0x' - }) - - it('Should be able to take flashLoan of multiple tokens together from AAVE', async function () { - await receiver.flashBorrow( - [DAI, USDT, WETH], - [Dai, Usdt, Weth], - 1, - _data, - _instaData, - ) - }) - it('Should be able to take flashLoan of multiple tokens together from MakerDAO', async function () { - await receiver.flashBorrow( - [DAI, USDT, WETH], - [Dai, Usdt, Weth], - 2, - _data, - _instaData, - ) - }) - it('Should be able to take flashLoan of multiple tokens together from Compound(MakerDAO)', async function () { - await receiver.flashBorrow( - [DAI, USDT, WETH], - [Dai, Usdt, Weth], - 3, - _data, - _instaData, - ) - }) - it('Should be able to take flashLoan of multiple tokens together from AAVE(MakerDAO)', async function () { - await receiver.flashBorrow( - [DAI, USDT, WETH], - [Dai, Usdt, Weth], - 4, - _data, - _instaData, - ) - }) - it('Should be able to take flashLoan of multiple sorted tokens together from Balancer', async function () { - await receiver.flashBorrow( - [DAI, USDT, WETH], - [Dai, Usdt, Weth], - 5, - _data, - _instaData, - ) - }) - it('Should be able to take flashLoan of multiple unsorted tokens together from Balancer', async function () { - await receiver.flashBorrow( - [USDT, DAI, WETH], - [Usdt, Dai, Weth], - 5, - _data, - _instaData, - ) - }) - it('Should be able to take flashLoan of multiple tokens together from Compound(Balancer)', async function () { - await receiver.flashBorrow( - [DAI, USDT, WETH], - [Dai, Usdt, Weth], - 6, - _data, - _instaData, - ) - }) - it('Should be able to take flashLoan of multiple tokens together from AAVE(Balancer)', async function () { - await receiver.flashBorrow( - [DAI, USDT, WETH], - [Dai, Usdt, Weth], - 7, - _data, - _instaData, - ) - }) - }) - }) - \ No newline at end of file diff --git a/test/polygon/flashloan.ts b/test/polygon/flashloan.ts index fb675053..64be98e5 100644 --- a/test/polygon/flashloan.ts +++ b/test/polygon/flashloan.ts @@ -48,14 +48,19 @@ describe('FlashLoan', function () { Aggregator = new InstaFlashAggregatorPolygon__factory(signer) aggregator = await Aggregator.deploy() await aggregator.deployed() + console.log("aggregator deployed at: ", aggregator.address); + Proxy = new InstaFlashAggregatorProxy__factory(signer) proxy = await Proxy.deploy(aggregator.address, master, data) await proxy.deployed() + console.log("proxy deployed at: ", proxy.address); + Receiver = new InstaFlashReceiver__factory(signer) receiver = await Receiver.deploy(proxy.address) await receiver.deployed() + console.log("receiver deployed at: ", receiver.address); const token_dai = new ethers.Contract( DAI,