From a43317b69bf7e73dcc5658cf5fd992be97e145ca Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sat, 4 Jun 2022 09:13:19 +0530 Subject: [PATCH] swap-connector-polygon --- contracts/polygon/common/interfaces.sol | 4 + contracts/polygon/connectors/swap/events.sol | 14 +++ contracts/polygon/connectors/swap/helpers.sol | 94 +++++++++++++++++++ contracts/polygon/connectors/swap/main.sol | 82 ++++++++++++++++ 4 files changed, 194 insertions(+) create mode 100644 contracts/polygon/connectors/swap/events.sol create mode 100644 contracts/polygon/connectors/swap/helpers.sol create mode 100644 contracts/polygon/connectors/swap/main.sol diff --git a/contracts/polygon/common/interfaces.sol b/contracts/polygon/common/interfaces.sol index f843d5fb..e395b83c 100644 --- a/contracts/polygon/common/interfaces.sol +++ b/contracts/polygon/common/interfaces.sol @@ -26,3 +26,7 @@ interface AccountInterface { function disable(address) external; function isAuth(address) external view returns (bool); } + +interface InstaConnectors { + function connectors(string memory) external returns (address); +} diff --git a/contracts/polygon/connectors/swap/events.sol b/contracts/polygon/connectors/swap/events.sol new file mode 100644 index 00000000..0440abf0 --- /dev/null +++ b/contracts/polygon/connectors/swap/events.sol @@ -0,0 +1,14 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +contract Events { + event LogSwap( + string _connector, + address indexed buyToken, + address indexed sellToken, + uint256 buyAmt, + uint256 sellAmt, + uint256 getId, + uint256 setId + ); +} diff --git a/contracts/polygon/connectors/swap/helpers.sol b/contracts/polygon/connectors/swap/helpers.sol new file mode 100644 index 00000000..d5493866 --- /dev/null +++ b/contracts/polygon/connectors/swap/helpers.sol @@ -0,0 +1,94 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; +pragma abicoder v2; + +import { InstaConnectors } from "../../common/interfaces.sol"; + +abstract contract Helper { + /** + * @dev Instadapp Connectors Registry + */ + InstaConnectors internal constant instaConnectors = + InstaConnectors(0x2A00684bFAb9717C21271E0751BCcb7d2D763c88); + + struct InputData { + address buyAddr; + address sellAddr; + uint256 sellAmt; + uint256[] unitAmts; + bytes[] callDatas; + uint256 setId; + } +} + +contract SwapHelpers is Helper { + /** + *@param _connectors name of the connectors in preference order. + *@param _inputData data for the swap cast. + */ + function _swap(string[] memory _connectors, InputData memory _inputData) + internal + returns ( + bool success, + bytes memory returnData, + string memory _connector + ) + { + require(_connectors.length > 0, "zero-length-not-allowed"); + require( + _inputData.unitAmts.length == _connectors.length, + "unitAmts-length-invalid" + ); + require( + _inputData.callDatas.length == _connectors.length, + "callDatas-length-invalid" + ); + + for (uint256 i = 0; i < _connectors.length; i++) { + string[] memory _target = new string[](1); + bytes[] memory _data = new bytes[](1); + bytes4 swapData = bytes4( + keccak256("swap(address,address,uint256,uint256,bytes,uint256)") + ); + + string memory _1INCH = "1INCH-A"; + if (keccak256(bytes(_connectors[i])) == keccak256(bytes(_1INCH))) { + swapData = bytes4( + keccak256( + "sell(address,address,uint256,uint256,bytes,uint256)" + ) + ); + } + + _target[0] = _connectors[i]; + _data[0] = abi.encodeWithSelector( + swapData, + _inputData.buyAddr, + _inputData.sellAddr, + _inputData.sellAmt, + _inputData.unitAmts[i], + _inputData.callDatas[i], + _inputData.setId + ); + + bytes4 _castData = bytes4( + keccak256("cast(string[],bytes[],address)") + ); + bytes memory castData = abi.encodeWithSelector( + _castData, + _target, + _data, + address(0) + ); + + (success, returnData) = instaConnectors + .connectors(_connectors[i]) + .delegatecall(castData); + + if (success) { + _connector = _connectors[i]; + break; + } + } + } +} diff --git a/contracts/polygon/connectors/swap/main.sol b/contracts/polygon/connectors/swap/main.sol new file mode 100644 index 00000000..8a8561d1 --- /dev/null +++ b/contracts/polygon/connectors/swap/main.sol @@ -0,0 +1,82 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +/** + * @title Swap. + * @dev Swap integration for DEX Aggregators. + */ + +// import files +import { SwapHelpers } from "./helpers.sol"; +import { Events } from "./events.sol"; + +abstract contract Swap is SwapHelpers, Events { + /** + * @dev Swap ETH/ERC20_Token using dex aggregators. + * @notice Swap tokens from exchanges like kyber, 0x etc, with calculation done off-chain. + * @param _connectors The name of the connectors like 1INCH-A, 0x etc, in order of their priority. + * @param buyAddr The address of the token to buy.(For MATIC: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param sellAddr The address of the token to sell.(For MATIC: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param sellAmt The amount of the token to sell. + * @param unitAmts The amount of buyAmt/sellAmt with slippage for respective DEXs. + * @param callDatas Data from APIs for respective DEXs. + * @param setId ID stores the amount of token brought. + */ + function swap( + string[] memory _connectors, + address buyAddr, + address sellAddr, + uint256 sellAmt, + uint256[] memory unitAmts, + bytes[] calldata callDatas, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + InputData memory inputData = InputData({ + buyAddr: buyAddr, + sellAddr: sellAddr, + sellAmt: sellAmt, + unitAmts: unitAmts, + callDatas: callDatas, + setId: setId + }); + + ( + bool success, + bytes memory returnData, + string memory _connector + ) = _swap(_connectors, inputData); + + uint256 _buyAmt; + uint256 _sellAmt; + + if (!success) { + revert("swap-failed"); + } else { + (, _eventParam) = abi.decode(returnData, (string, bytes)); + (, , _buyAmt, _sellAmt, , ) = abi.decode( + _eventParam, + (address, address, uint256, uint256, uint256, uint256) + ); + } + + _eventName = "LogSwap(string,address,address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode( + _connector, + buyAddr, + sellAddr, + _buyAmt, + _sellAmt, + 0, + setId + ); + } +} + +contract ConnectV2Swap is Swap { + string public name = "Swap-v1"; +}