From 2c8bad40fb9e05799ca45d043213ce7727caa351 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Fri, 31 Jul 2020 20:03:21 +0530 Subject: [PATCH 1/9] Stack too deep when compiling inline assembly Error --- contracts/common/math.sol | 2 +- contracts/connectors/1inch.sol | 2 +- contracts/tests/MockInstaMapping.sol | 4 +- contracts/tests/mockOneProto.sol | 20 +++++ package-lock.json | 52 ++++------- package.json | 2 +- test/abi/1proto.json | 1 + test/oneProto.js | 127 +++++++++++++++++++++++++++ 8 files changed, 169 insertions(+), 41 deletions(-) create mode 100644 contracts/tests/mockOneProto.sol create mode 100644 test/abi/1proto.json create mode 100644 test/oneProto.js diff --git a/contracts/common/math.sol b/contracts/common/math.sol index 63b5880..1ff023c 100644 --- a/contracts/common/math.sol +++ b/contracts/common/math.sol @@ -10,7 +10,7 @@ contract DSMath { z = SafeMath.add(x, y); } - function sub(uint x, uint y) internal pure returns (uint z) { + function sub(uint x, uint y) internal virtual pure returns (uint z) { z = SafeMath.sub(x, y); } diff --git a/contracts/connectors/1inch.sol b/contracts/connectors/1inch.sol index 6fbba60..a3a00b3 100644 --- a/contracts/connectors/1inch.sol +++ b/contracts/connectors/1inch.sol @@ -318,6 +318,6 @@ contract OneInchResolver is OneInchResolverHelpers { } } -contract ConnectOne is OneInchResolver { +contract ConnectOneInch is OneInchResolver { string public name = "1Inch-v1"; } \ No newline at end of file diff --git a/contracts/tests/MockInstaMapping.sol b/contracts/tests/MockInstaMapping.sol index 9f508aa..818a40e 100644 --- a/contracts/tests/MockInstaMapping.sol +++ b/contracts/tests/MockInstaMapping.sol @@ -1,7 +1,7 @@ pragma solidity ^0.6.0; -import { InstaMapping } from "../mapping/staking.sol"; +import { InstaStakingMapping } from "../mapping/staking.sol"; -contract MockInstaMapping is InstaMapping { +contract MockInstaMapping is InstaStakingMapping { modifier isChief override {_;} } diff --git a/contracts/tests/mockOneProto.sol b/contracts/tests/mockOneProto.sol new file mode 100644 index 0000000..18bccac --- /dev/null +++ b/contracts/tests/mockOneProto.sol @@ -0,0 +1,20 @@ +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import { ConnectOne } from "../connectors/1proto.sol"; + +contract MockConnectOne is ConnectOne { + address public oneProtoAddr; + + constructor(address _oneProtoAddr) public { + oneProtoAddr = _oneProtoAddr; + } + + function emitEvent(bytes32 eventCode, bytes memory eventData) override internal {} + + function setUint(uint setId, uint val) override internal {} + + function sub(uint x, uint y) internal override pure returns (uint z) { + z = 100000; + } +} diff --git a/package-lock.json b/package-lock.json index 8f7ac23..10ff3aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1427,7 +1427,7 @@ "eth-lib": "0.2.7", "ethereumjs-common": "^1.3.2", "ethereumjs-tx": "^2.1.1", - "scrypt-shim": "github:web3-js/scrypt-shim", + "scrypt-shim": "github:web3-js/scrypt-shim#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb", "underscore": "1.9.1", "uuid": "3.3.2", "web3-core": "1.2.2", @@ -1532,7 +1532,7 @@ "requires": { "underscore": "1.9.1", "web3-core-helpers": "1.2.2", - "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis" + "websocket": "github:web3-js/WebSocket-Node#ef5ea2f41daf4a2113b80c9223df884b4d56c400" } }, "web3-shh": { @@ -4958,8 +4958,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -4980,14 +4979,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5002,20 +4999,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5132,8 +5126,7 @@ "inherits": { "version": "2.0.4", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5145,7 +5138,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5160,7 +5152,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5168,14 +5159,12 @@ "minimist": { "version": "1.2.5", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.9.0", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5194,7 +5183,6 @@ "version": "0.5.3", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "^1.2.5" } @@ -5256,8 +5244,7 @@ "npm-normalize-package-bin": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "npm-packlist": { "version": "1.4.8", @@ -5285,8 +5272,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5298,7 +5284,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5376,8 +5361,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -5413,7 +5397,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5433,7 +5416,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5477,14 +5459,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -11678,7 +11658,7 @@ "requires": { "underscore": "1.9.1", "web3-core-helpers": "1.2.1", - "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis" + "websocket": "github:web3-js/WebSocket-Node#905deb4812572b344f5801f8c9ce8bb02799d82e" }, "dependencies": { "debug": { @@ -11695,7 +11675,7 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "websocket": { - "version": "github:web3-js/WebSocket-Node#ef5ea2f41daf4a2113b80c9223df884b4d56c400", + "version": "github:web3-js/WebSocket-Node#905deb4812572b344f5801f8c9ce8bb02799d82e", "from": "github:web3-js/WebSocket-Node#polyfill/globalThis", "requires": { "debug": "^2.2.0", diff --git a/package.json b/package.json index 51e1cae..9069e84 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "coverage": "./node_modules/.bin/solidity-coverage", "solium": "solium -d contracts/", "build-contracts": "sol-merger \"./contracts/connectors/mock.sol\" ./contracts/build", - "ganache": "ganache-cli --deterministic --unlock 0xfcd22438ad6ed564a1c26151df73f6b33b817b56 -f https://mainnet.infura.io/v3/" + "ganache": "ganache-cli" }, "repository": { "type": "git", diff --git a/test/abi/1proto.json b/test/abi/1proto.json new file mode 100644 index 0000000..445cfec --- /dev/null +++ b/test/abi/1proto.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"contract IOneSplitMulti","name":"impl","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newImpl","type":"address"}],"name":"ImplementationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"fromToken","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"destToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"destTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minReturn","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"distribution","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"referral","type":"address"},{"indexed":false,"internalType":"uint256","name":"feePercent","type":"uint256"}],"name":"Swapped","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"chi","outputs":[{"internalType":"contract IFreeFromUpTo","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"claimAsset","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"fromToken","type":"address"},{"internalType":"contract IERC20","name":"destToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"parts","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"name":"getExpectedReturn","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"fromToken","type":"address"},{"internalType":"contract IERC20","name":"destToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"parts","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"},{"internalType":"uint256","name":"destTokenEthPriceTimesGasPrice","type":"uint256"}],"name":"getExpectedReturnWithGas","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"},{"internalType":"uint256","name":"estimateGasAmount","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256[]","name":"parts","type":"uint256[]"},{"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"internalType":"uint256[]","name":"destTokenEthPriceTimesGasPrices","type":"uint256[]"}],"name":"getExpectedReturnWithGasMulti","outputs":[{"internalType":"uint256[]","name":"returnAmounts","type":"uint256[]"},{"internalType":"uint256","name":"estimateGasAmount","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oneSplitImpl","outputs":[{"internalType":"contract IOneSplitMulti","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IOneSplitMulti","name":"impl","type":"address"}],"name":"setNewImpl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"fromToken","type":"address"},{"internalType":"contract IERC20","name":"destToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"},{"internalType":"uint256","name":"flags","type":"uint256"}],"name":"swap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"},{"internalType":"uint256[]","name":"flags","type":"uint256[]"}],"name":"swapMulti","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"fromToken","type":"address"},{"internalType":"contract IERC20","name":"destToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"},{"internalType":"uint256","name":"flags","type":"uint256"},{"internalType":"address","name":"referral","type":"address"},{"internalType":"uint256","name":"feePercent","type":"uint256"}],"name":"swapWithReferral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"},{"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"internalType":"address","name":"referral","type":"address"},{"internalType":"uint256","name":"feePercent","type":"uint256"}],"name":"swapWithReferralMulti","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/test/oneProto.js b/test/oneProto.js new file mode 100644 index 0000000..1283c61 --- /dev/null +++ b/test/oneProto.js @@ -0,0 +1,127 @@ +const { + BN, // Big Number support + expectEvent, // Assertions for emitted events + expectRevert, // Assertions for transactions that should fail + balance, + ether + } = require('@openzeppelin/test-helpers'); + + const MockContract = artifacts.require("MockContract"); + const MockConnectOne = artifacts.require('MockConnectOne'); + const erc20ABI = require("./abi/erc20.js"); + const oneProto = require("./abi/1proto.json"); + + contract('ConnectOneProto', async accounts => { + const [sender, receiver] = accounts; + let mock, mockConnectOneProto, oneProtoContract, sellToken, buyToken, sellAmt; + + before(async function () { + mock = await MockContract.new(); + mockConnectOneProto = await MockConnectOne.new(mock.address); + oneProtoContract = new web3.eth.Contract(oneProto, mock.address); + sellToken = new web3.eth.Contract(erc20ABI, mock.address); + buyToken = new web3.eth.Contract(erc20ABI, mock.address); + sellAmt = String(20 * 10 ** 18); + + + // mocking balanceOf + let balanceOf = await sellToken.methods.balanceOf(mockConnectOneProto.address).encodeABI(); + await mock.givenMethodReturnUint(balanceOf, sellAmt); + + // mocking balanceOf + let decimals = await sellToken.methods.decimals().encodeABI(); + await mock.givenMethodReturnUint(decimals, 18); + + // mocking balanceOf + let decimalsBuy = await buyToken.methods.decimals().encodeABI(); + await mock.givenMethodReturnUint(decimalsBuy, 18); + + // mocking approve + let approve = await sellToken.methods.approve(mockConnectOneProto.address, sellAmt).encodeABI(); + await mock.givenMethodReturnBool(approve, "true"); + + }) + + it('can sell DAI <> USDC', async function() { + let getExpectedReturn = await oneProtoContract.methods.getExpectedReturn( + mock.address, + mock.address, + sellAmt, + 5, + 0 + ).encodeABI(); + await mock.givenMethodReturnUint(getExpectedReturn, String(sellAmt)); + // mocking stake + let swapWithReferral = await oneProtoContract.methods.swapWithReferral( + mock.address, + mock.address, + sellAmt, + 1, + [0,1,0], + 0, + mock.address, + 0 + ).encodeABI(); + await mock.givenMethodReturnBool(swapWithReferral, "true"); + + const tx = await mockConnectOneProto.sell( + mock.address, + mock.address, + sellAmt, + String(99 * 10 ** 16), + 0, + 0 + ) + let obj = { + buyAmt: 100000 + }; + expectEvent(tx, "LogSell", obj); + }); + + // it('can withdraw', async function() { + // // mocking withdraw + // let withdraw = await stakingContract.methods.withdraw(10000000).encodeABI(); + // await mock.givenMethodReturnBool(withdraw, "true"); + // // mocking getReward + // let reward = await stakingContract.methods.getReward().encodeABI(); + // await mock.givenMethodReturnBool(reward, "true"); + + // const tx = await mockSynthetixStaking.withdraw( + // "snx", + // 10000000, + // 0, + // 111, + // 112 + // ) + // expectEvent(tx, "LogWithdraw"); + // expectEvent(tx, "LogClaimedReward"); + // }); + + // it('can claim reward', async function() { + // // mocking getReward + // let reward = await stakingContract.methods.getReward().encodeABI(); + // await mock.givenMethodReturnBool(reward, "true"); + // const tx = await mockSynthetixStaking.claimReward( + // "snx", + // 112 + // ) + // expectEvent(tx, "LogClaimedReward"); + // }); + + // it('cannot deposit if pool removed', async function() { + // mockInstaMapping.removeStakingMapping('snx', mock.address); + // // mocking stake + // let stake = await stakingContract.methods.stake(10000000).encodeABI(); + // await mock.givenMethodReturnBool(stake, "true"); + + // const tx = mockSynthetixStaking.deposit( + // "snx", + // 10000000, + // 0, + // 0 + // ) + // expectRevert(tx, "Wrong Staking Name"); + // }); + + }) + \ No newline at end of file From 05a89af757a9a591444168d63af8ec1e2bcd01f5 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sun, 2 Aug 2020 22:26:13 +0530 Subject: [PATCH 2/9] Fixed bugs --- contracts/connectors/1inch.sol | 2 +- contracts/connectors/1proto.sol | 64 +++++++++++++++++---------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/contracts/connectors/1inch.sol b/contracts/connectors/1inch.sol index a3a00b3..b22ac3c 100644 --- a/contracts/connectors/1inch.sol +++ b/contracts/connectors/1inch.sol @@ -300,7 +300,7 @@ contract OneInchResolver is OneInchResolverHelpers { uint feePercent, uint setId ) external payable { - require(feePercent > 0 && feePercent <= 2*10*16, "Fee more than 2%"); + require(feePercent > 0 && feePercent <= 2 * 10 ** 16, "Fee more than 2%"); require(feeCollector != address(0), "feeCollector is not vaild address"); OneInchData memory oneInchData = OneInchData({ diff --git a/contracts/connectors/1proto.sol b/contracts/connectors/1proto.sol index b9e3166..3ae88c4 100644 --- a/contracts/connectors/1proto.sol +++ b/contracts/connectors/1proto.sol @@ -1,4 +1,6 @@ pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + // import files from common directory import { TokenInterface , MemoryInterface, EventInterface} from "../common/interfaces.sol"; @@ -53,7 +55,7 @@ contract OneHelpers is Stores, DSMath { /** * @dev Return 1proto Address */ - function getOneProtoAddress() internal pure returns (address payable) { + function getOneProtoAddress() internal virtual view returns (address payable) { return 0x50FDA034C0Ce7a8f7EFDAebDA7Aa7cA21CC1267e; } @@ -112,10 +114,11 @@ contract OneHelpers is Stores, DSMath { if (feeCollector != address(0)) { feeAmount = wmul(amount, feePercent); leftAmt = sub(amount, feeAmount); - uint feeCollectorAmt = wmul(feeAmount, 3 * 10 ** 17); - uint restAmt = sub(feeAmount, feeCollectorAmt); - _transfer(payable(feeCollector), IERC20(token), feeCollectorAmt); - _transfer(payable(getReferralAddr()), IERC20(token), restAmt); + uint feeCollectorAmt = wmul(feeAmount, 7 * 10 ** 17); // 70% to feeCollector + uint restAmt = sub(feeAmount, feeCollectorAmt); // rest 30% + IERC20 tokenContract = IERC20(token); + _transfer(payable(feeCollector), tokenContract, feeCollectorAmt); + _transfer(payable(getReferralAddr()), tokenContract, restAmt); } else { leftAmt = amount; } @@ -153,8 +156,8 @@ contract Resolver is OneHelpers { _sellAddr.approve(address(oneProtoContract), _sellAmt); } - uint initalBal = getTokenBal(_buyAddr); + uint initalBal = getTokenBal(_buyAddr); oneProtoContract.swapWithReferral.value(ethAmt)( _sellAddr, _buyAddr, @@ -165,8 +168,8 @@ contract Resolver is OneHelpers { getReferralAddr(), 0 ); - uint finalBal = getTokenBal(_buyAddr); + buyAmt = sub(finalBal, initalBal); require(_slippageAmt <= buyAmt, "Too much slippage"); @@ -232,8 +235,8 @@ contract OneProtoEventResolver is Resolver { address indexed sellToken, uint256 buyAmt, uint256 sellAmt, - address indexed collector, - uint256 fee, + address indexed feeCollector, + uint256 feeAmount, uint256 getId, uint256 setId ); @@ -274,7 +277,7 @@ contract OneProtoEventResolver is Resolver { getId, setId ); - _eventCode = keccak256("LogSellFee(address,address,uint256,uint256,uint256,uint256)"); + _eventCode = keccak256("LogSellFee(address,address,uint256,uint256,address,uint256,uint256,uint256)"); _eventParam = abi.encode( address(oneProtoData.buyToken), address(oneProtoData.sellToken), @@ -303,8 +306,8 @@ contract OneProtoEventResolver is Resolver { address indexed sellToken, uint256 buyAmt, uint256 sellAmt, - address indexed collector, - uint256 fee, + address indexed feeCollector, + uint256 feeAmount, uint256 getId, uint256 setId ); @@ -345,7 +348,7 @@ contract OneProtoEventResolver is Resolver { getId, setId ); - _eventCode = keccak256("LogSellFeeTwo(address,address,uint256,uint256,uint256,uint256)"); + _eventCode = keccak256("LogSellFeeTwo(address,address,uint256,uint256,address,uint256,uint256,uint256)"); _eventParam = abi.encode( address(oneProtoData.buyToken), address(oneProtoData.sellToken), @@ -376,8 +379,8 @@ contract OneProtoEventResolver is Resolver { address indexed sellToken, uint256 buyAmt, uint256 sellAmt, - address indexed collector, - uint256 fee, + address indexed feeCollector, + uint256 feeAmount, uint256 getId, uint256 setId ); @@ -421,7 +424,7 @@ contract OneProtoEventResolver is Resolver { getId, setId ); - _eventCode = keccak256("LogSellFeeMulti(address[],address,address,uint256,uint256,uint256,uint256)"); + _eventCode = keccak256("LogSellFeeMulti(address[],address,address,uint256,uint256,address,uint256,uint256,uint256)"); _eventParam = abi.encode( oneProtoData.tokens, address(oneProtoData.buyToken), @@ -446,7 +449,6 @@ contract OneProtoResolverHelpers is OneProtoEventResolver { uint256 setId ) internal { uint _sellAmt = getUint(getId, oneProtoData._sellAmt); - oneProtoData._sellAmt = _sellAmt == uint(-1) ? getTokenBal(oneProtoData.sellToken) : _sellAmt; @@ -466,7 +468,7 @@ contract OneProtoResolverHelpers is OneProtoEventResolver { oneProtoData ); - (uint feeAmount, uint leftBuyAmt) = takeFee( + (uint leftBuyAmt, uint feeAmount) = takeFee( address(oneProtoData.buyToken), oneProtoData._buyAmt, oneProtoData.feeCollector, @@ -496,12 +498,13 @@ contract OneProtoResolverHelpers is OneProtoEventResolver { oneProtoData ); - (uint feeAmount, uint leftBuyAmt) = takeFee( + (uint leftBuyAmt, uint feeAmount) = takeFee( address(oneProtoData.buyToken), oneProtoData._buyAmt, oneProtoData.feeCollector, feePercent ); + setUint(setId, leftBuyAmt); oneProtoData.feeAmount = feeAmount; @@ -521,8 +524,9 @@ contract OneProtoResolverHelpers is OneProtoEventResolver { _sellAmt; oneProtoData._buyAmt = oneProtoSwapMulti(oneProtoData); + uint leftBuyAmt; - (oneProtoData.feeAmount, leftBuyAmt) = takeFee( + (leftBuyAmt, oneProtoData.feeAmount) = takeFee( address(oneProtoData.buyToken), oneProtoData._buyAmt, oneProtoData.feeCollector, @@ -555,10 +559,10 @@ contract OneProtoResolver is OneProtoResolverHelpers { OneProtoData memory oneProtoData = OneProtoData({ buyToken: TokenInterface(buyAddr), sellToken: TokenInterface(sellAddr), + _sellAmt: sellAmt, unitAmt: unitAmt, distribution: new uint[](0), feeCollector: address(0), - _sellAmt: sellAmt, _buyAmt: 0, disableDexes: 0, feeAmount: 0 @@ -588,16 +592,16 @@ contract OneProtoResolver is OneProtoResolverHelpers { uint getId, uint setId ) external payable { - require(feePercent > 0 && feePercent <= 2*10*16, "Fee more than 2%"); + require(feePercent > 0 && feePercent <= 2 * 10 ** 16, "Fee more than 2%"); require(feeCollector != address(0), "feeCollector is not vaild address"); OneProtoData memory oneProtoData = OneProtoData({ buyToken: TokenInterface(buyAddr), sellToken: TokenInterface(sellAddr), + _sellAmt: sellAmt, unitAmt: unitAmt, distribution: new uint[](0), feeCollector: feeCollector, - _sellAmt: sellAmt, _buyAmt: 0, disableDexes: 0, feeAmount: 0 @@ -630,10 +634,10 @@ contract OneProtoResolver is OneProtoResolverHelpers { OneProtoData memory oneProtoData = OneProtoData({ buyToken: TokenInterface(buyAddr), sellToken: TokenInterface(sellAddr), + _sellAmt: sellAmt, unitAmt: unitAmt, distribution: distribution, disableDexes: disableDexes, - _sellAmt: sellAmt, feeCollector: address(0), _buyAmt: 0, feeAmount: 0 @@ -668,16 +672,16 @@ contract OneProtoResolver is OneProtoResolverHelpers { uint getId, uint setId ) external payable { - require(feePercent > 0 && feePercent <= 2*10*16, "Fee more than 2%"); + require(feePercent > 0 && feePercent <= 2 * 10 ** 16, "Fee more than 2%"); require(feeCollector != address(0), "feeCollector is not vaild address"); OneProtoData memory oneProtoData = OneProtoData({ buyToken: TokenInterface(buyAddr), sellToken: TokenInterface(sellAddr), + _sellAmt: sellAmt, unitAmt: unitAmt, distribution: distribution, disableDexes: disableDexes, feeCollector: feeCollector, - _sellAmt: sellAmt, _buyAmt: 0, feeAmount: 0 }); @@ -743,18 +747,18 @@ contract OneProtoResolver is OneProtoResolverHelpers { uint getId, uint setId ) external payable { - require(feePercent > 0 && feePercent <= 2*10*16, "Fee more than 2%"); + require(feePercent > 0 && feePercent <= 2 * 10 ** 16, "Fee more than 2%"); require(feeCollector != address(0), "feeCollector is not vaild address"); - TokenInterface buyToken = TokenInterface(address(tokens[tokens.length-1])); + TokenInterface buyToken = TokenInterface(address(tokens[tokens.length - 1])); OneProtoMultiData memory oneProtoData = OneProtoMultiData({ tokens: tokens, buyToken: buyToken, sellToken: TokenInterface(address(tokens[0])), + _sellAmt: sellAmt, unitAmt: unitAmt, distribution: distribution, - feeCollector: feeCollector, disableDexes: disableDexes, - _sellAmt: sellAmt, + feeCollector: feeCollector, _buyAmt: 0, feeAmount: 0 }); From a865f08b4e2cb2926bfdbdbee6063d695a4adc54 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sun, 2 Aug 2020 22:28:37 +0530 Subject: [PATCH 3/9] Minor changes --- contracts/connectors/1inch.sol | 4 ++-- contracts/connectors/1proto.sol | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/connectors/1inch.sol b/contracts/connectors/1inch.sol index b22ac3c..d173faf 100644 --- a/contracts/connectors/1inch.sol +++ b/contracts/connectors/1inch.sol @@ -318,6 +318,6 @@ contract OneInchResolver is OneInchResolverHelpers { } } -contract ConnectOneInch is OneInchResolver { - string public name = "1Inch-v1"; +contract ConnectOneInchOnChain is OneInchResolver { + string public name = "1inch-Onchain-v1"; } \ No newline at end of file diff --git a/contracts/connectors/1proto.sol b/contracts/connectors/1proto.sol index 3ae88c4..480b769 100644 --- a/contracts/connectors/1proto.sol +++ b/contracts/connectors/1proto.sol @@ -767,6 +767,6 @@ contract OneProtoResolver is OneProtoResolverHelpers { } } -contract ConnectOne is OneProtoResolver { - string public name = "1proto-v1"; +contract ConnectOneInchOffChain is OneProtoResolver { + string public name = "1inch-OffChain-v1"; } \ No newline at end of file From e8a7a7715e9115c7f72fdff418fea63a327f25db Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Mon, 3 Aug 2020 11:15:56 +0530 Subject: [PATCH 4/9] fixed minor bug --- contracts/connectors/1inch.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/connectors/1inch.sol b/contracts/connectors/1inch.sol index d173faf..9dc7e01 100644 --- a/contracts/connectors/1inch.sol +++ b/contracts/connectors/1inch.sol @@ -234,7 +234,7 @@ contract OneInchResolverHelpers is OneInchEventResolver { uint buyAmt = oneInchSwap(oneInchData, ethAmt); - (uint feeAmount, uint leftBuyAmt) = takeFee( + (uint leftBuyAmt, uint feeAmount) = takeFee( address(_buyAddr), buyAmt, oneInchData.feeCollector, From b14642548f573b2b62a724b6f3883a93392bb510 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Mon, 3 Aug 2020 12:49:29 +0530 Subject: [PATCH 5/9] test fix --- contracts/tests/mockOneProto.sol | 6 +++++- test/oneProto.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/contracts/tests/mockOneProto.sol b/contracts/tests/mockOneProto.sol index 18bccac..6311279 100644 --- a/contracts/tests/mockOneProto.sol +++ b/contracts/tests/mockOneProto.sol @@ -15,6 +15,10 @@ contract MockConnectOne is ConnectOne { function setUint(uint setId, uint val) override internal {} function sub(uint x, uint y) internal override pure returns (uint z) { - z = 100000; + z = 21 * 10 ** 18; } + + function getOneProtoAddress() internal override view returns (address payable) { + return payable(oneProtoAddr); + } } diff --git a/test/oneProto.js b/test/oneProto.js index 1283c61..83d9fcb 100644 --- a/test/oneProto.js +++ b/test/oneProto.js @@ -50,7 +50,7 @@ const { 5, 0 ).encodeABI(); - await mock.givenMethodReturnUint(getExpectedReturn, String(sellAmt)); + await mock.givenMethodReturn(getExpectedReturn, web3.eth.abi.encodeParameters(["uint256", "uint256[]"], [20000, [0,0,0,1]])); // mocking stake let swapWithReferral = await oneProtoContract.methods.swapWithReferral( mock.address, From 7c6bc47737f5efc2c892532b790d1c6985acaa01 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sun, 9 Aug 2020 21:37:13 +0530 Subject: [PATCH 6/9] Removed fee logics --- contracts/connectors/1inch.sol | 551 ++++++++++++++++++----- contracts/connectors/1proto.sol | 772 -------------------------------- 2 files changed, 437 insertions(+), 886 deletions(-) delete mode 100644 contracts/connectors/1proto.sol diff --git a/contracts/connectors/1inch.sol b/contracts/connectors/1inch.sol index 9dc7e01..9331f74 100644 --- a/contracts/connectors/1inch.sol +++ b/contracts/connectors/1inch.sol @@ -1,13 +1,12 @@ pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + // import files from common directory import { TokenInterface , MemoryInterface, EventInterface} from "../common/interfaces.sol"; import { Stores } from "../common/stores.sol"; import { DSMath } from "../common/math.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - interface OneInchInterace { function swap( TokenInterface fromToken, @@ -26,8 +25,52 @@ interface OneInchInterace { returns (uint256 returnAmount); } +interface OneProtoInterface { + function swapWithReferral( + TokenInterface fromToken, + TokenInterface destToken, + uint256 amount, + uint256 minReturn, + uint256[] calldata distribution, + uint256 flags, // See contants in IOneSplit.sol + address referral, + uint256 feePercent + ) external payable returns(uint256); + + function swapWithReferralMulti( + TokenInterface[] calldata tokens, + uint256 amount, + uint256 minReturn, + uint256[] calldata distribution, + uint256[] calldata flags, + address referral, + uint256 feePercent + ) external payable returns(uint256 returnAmount); + + function getExpectedReturn( + TokenInterface fromToken, + TokenInterface destToken, + uint256 amount, + uint256 parts, + uint256 flags // See constants in IOneSplit.sol + ) + external + view + returns( + uint256 returnAmount, + uint256[] memory distribution + ); +} + + contract OneHelpers is Stores, DSMath { - using SafeERC20 for IERC20; + /** + * @dev Return 1proto Address + */ + function getOneProtoAddress() internal pure returns (address payable) { + return 0x50FDA034C0Ce7a8f7EFDAebDA7Aa7cA21CC1267e; + } + /** * @dev Return 1Inch Address */ @@ -70,33 +113,118 @@ contract OneHelpers is Stores, DSMath { sellDec = address(sellAddr) == getEthAddr() ? 18 : sellAddr.decimals(); } - function _transfer(address payable to, IERC20 token, uint _amt) internal { - address(token) == getEthAddr() ? - to.transfer(_amt) : - token.safeTransfer(to, _amt); + function getSlippageAmt( + TokenInterface _buyAddr, + TokenInterface _sellAddr, + uint _sellAmt, + uint unitAmt + ) internal view returns(uint _slippageAmt) { + (uint _buyDec, uint _sellDec) = getTokensDec(_buyAddr, _sellAddr); + uint _sellAmt18 = convertTo18(_sellDec, _sellAmt); + _slippageAmt = convert18ToDec(_buyDec, wmul(unitAmt, _sellAmt18)); } - function takeFee( - address token, - uint amount, - address feeCollector, - uint feePercent - ) internal returns (uint leftAmt, uint feeAmount){ - if (feeCollector != address(0)) { - feeAmount = wmul(amount, feePercent); - leftAmt = sub(amount, feeAmount); - uint feeCollectorAmt = wmul(feeAmount, 3 * 10 ** 17); - uint restAmt = sub(feeAmount, feeCollectorAmt); - _transfer(payable(feeCollector), IERC20(token), feeCollectorAmt); - _transfer(payable(getReferralAddr()), IERC20(token), restAmt); - } else { - leftAmt = amount; + function convertToTokenInterface(address[] memory tokens) internal pure returns(TokenInterface[] memory) { + TokenInterface[] memory _tokens = new TokenInterface[](tokens.length); + for (uint i = 0; i < tokens.length; i++) { + _tokens[i] = TokenInterface(tokens[i]); } + return _tokens; } } -contract Resolver is OneHelpers { +contract OneProtoResolver is OneHelpers { + struct OneProtoData { + TokenInterface sellToken; + TokenInterface buyToken; + uint _sellAmt; + uint _buyAmt; + uint unitAmt; + uint[] distribution; + uint disableDexes; + } + + function oneProtoSwap( + OneProtoInterface oneProtoContract, + OneProtoData memory oneProtoData + ) internal returns (uint buyAmt) { + TokenInterface _sellAddr = oneProtoData.sellToken; + TokenInterface _buyAddr = oneProtoData.buyToken; + uint _sellAmt = oneProtoData._sellAmt; + + uint _slippageAmt = getSlippageAmt(_buyAddr, _sellAddr, _sellAmt, oneProtoData.unitAmt); + + uint ethAmt; + if (address(_sellAddr) == getEthAddr()) { + ethAmt = _sellAmt; + } else { + _sellAddr.approve(address(oneProtoContract), _sellAmt); + } + + + uint initalBal = getTokenBal(_buyAddr); + oneProtoContract.swapWithReferral.value(ethAmt)( + _sellAddr, + _buyAddr, + _sellAmt, + _slippageAmt, + oneProtoData.distribution, + oneProtoData.disableDexes, + getReferralAddr(), + 0 + ); + uint finalBal = getTokenBal(_buyAddr); + + buyAmt = sub(finalBal, initalBal); + + require(_slippageAmt <= buyAmt, "Too much slippage"); + } + + struct OneProtoMultiData { + address[] tokens; + TokenInterface sellToken; + TokenInterface buyToken; + uint _sellAmt; + uint _buyAmt; + uint unitAmt; + uint[] distribution; + uint[] disableDexes; + } + + function oneProtoSwapMulti(OneProtoMultiData memory oneProtoData) internal returns (uint buyAmt) { + TokenInterface _sellAddr = oneProtoData.sellToken; + TokenInterface _buyAddr = oneProtoData.buyToken; + uint _sellAmt = oneProtoData._sellAmt; + uint _slippageAmt = getSlippageAmt(_buyAddr, _sellAddr, _sellAmt, oneProtoData.unitAmt); + + OneProtoInterface oneSplitContract = OneProtoInterface(getOneProtoAddress()); + uint ethAmt; + if (address(_sellAddr) == getEthAddr()) { + ethAmt = _sellAmt; + } else { + _sellAddr.approve(address(oneSplitContract), _sellAmt); + } + + uint initalBal = getTokenBal(_buyAddr); + oneSplitContract.swapWithReferralMulti.value(ethAmt)( + convertToTokenInterface(oneProtoData.tokens), + _sellAmt, + _slippageAmt, + oneProtoData.distribution, + oneProtoData.disableDexes, + getReferralAddr(), + 0 + ); + uint finalBal = getTokenBal(_buyAddr); + + buyAmt = sub(finalBal, initalBal); + + require(_slippageAmt <= buyAmt, "Too much slippage"); + } +} + +contract OneInchResolver is OneProtoResolver { function checkOneInchSig(bytes memory callData) internal pure returns(bool isOk) { bytes memory _data = callData; bytes4 sig; @@ -114,8 +242,6 @@ contract Resolver is OneHelpers { uint _buyAmt; uint unitAmt; bytes callData; - address feeCollector; - uint256 feeAmount; } function oneInchSwap( @@ -142,7 +268,7 @@ contract Resolver is OneHelpers { } -contract OneInchEventResolver is Resolver { +contract OneProtoEventResolver is OneInchResolver { event LogSell( address indexed buyToken, address indexed sellToken, @@ -152,75 +278,221 @@ contract OneInchEventResolver is Resolver { uint256 setId ); - event LogSellFee( + function emitLogSell( + OneProtoData memory oneProtoData, + uint256 getId, + uint256 setId + ) internal { + bytes32 _eventCode; + bytes memory _eventParam; + emit LogSell( + address(oneProtoData.buyToken), + address(oneProtoData.sellToken), + oneProtoData._buyAmt, + oneProtoData._sellAmt, + getId, + setId + ); + _eventCode = keccak256("LogSell(address,address,uint256,uint256,uint256,uint256)"); + _eventParam = abi.encode( + address(oneProtoData.buyToken), + address(oneProtoData.sellToken), + oneProtoData._buyAmt, + oneProtoData._sellAmt, + getId, + setId + ); + emitEvent(_eventCode, _eventParam); + } + + event LogSellTwo( address indexed buyToken, address indexed sellToken, uint256 buyAmt, uint256 sellAmt, - address indexed collector, - uint256 fee, uint256 getId, uint256 setId ); - function emitLogSell( + function emitLogSellTwo( + OneProtoData memory oneProtoData, + uint256 getId, + uint256 setId + ) internal { + bytes32 _eventCode; + bytes memory _eventParam; + emit LogSellTwo( + address(oneProtoData.buyToken), + address(oneProtoData.sellToken), + oneProtoData._buyAmt, + oneProtoData._sellAmt, + getId, + setId + ); + _eventCode = keccak256("LogSellTwo(address,address,uint256,uint256,uint256,uint256)"); + _eventParam = abi.encode( + address(oneProtoData.buyToken), + address(oneProtoData.sellToken), + oneProtoData._buyAmt, + oneProtoData._sellAmt, + getId, + setId + ); + emitEvent(_eventCode, _eventParam); + } + + event LogSellMulti( + address[] tokens, + address indexed buyToken, + address indexed sellToken, + uint256 buyAmt, + uint256 sellAmt, + uint256 getId, + uint256 setId + ); + + function emitLogSellMulti( + OneProtoMultiData memory oneProtoData, + uint256 getId, + uint256 setId + ) internal { + bytes32 _eventCode; + bytes memory _eventParam; + emit LogSellMulti( + oneProtoData.tokens, + address(oneProtoData.buyToken), + address(oneProtoData.sellToken), + oneProtoData._buyAmt, + oneProtoData._sellAmt, + getId, + setId + ); + _eventCode = keccak256("LogSellMulti(address[],address,address,uint256,uint256,uint256,uint256)"); + _eventParam = abi.encode( + oneProtoData.tokens, + address(oneProtoData.buyToken), + address(oneProtoData.sellToken), + oneProtoData._buyAmt, + oneProtoData._sellAmt, + getId, + setId + ); + emitEvent(_eventCode, _eventParam); + } +} + +contract OneInchEventResolver is OneProtoEventResolver { + event LogSellThree( + address indexed buyToken, + address indexed sellToken, + uint256 buyAmt, + uint256 sellAmt, + uint256 getId, + uint256 setId + ); + + function emitLogSellThree( OneInchData memory oneInchData, uint256 setId ) internal { bytes32 _eventCode; bytes memory _eventParam; - if (oneInchData.feeCollector == address(0)) { - emit LogSell( - address(oneInchData.buyToken), - address(oneInchData.sellToken), - oneInchData._buyAmt, - oneInchData._sellAmt, - 0, - setId - ); - _eventCode = keccak256("LogSell(address,address,uint256,uint256,uint256,uint256)"); - _eventParam = abi.encode( - address(oneInchData.buyToken), - address(oneInchData.sellToken), - oneInchData._buyAmt, - oneInchData._sellAmt, - 0, - setId - ); - } else { - emit LogSellFee( - address(oneInchData.buyToken), - address(oneInchData.sellToken), - oneInchData._buyAmt, - oneInchData._sellAmt, - oneInchData.feeCollector, - oneInchData.feeAmount, - 0, - setId - ); - _eventCode = keccak256("LogSellFee(address,address,uint256,uint256,uint256,uint256)"); - _eventParam = abi.encode( - address(oneInchData.buyToken), - address(oneInchData.sellToken), - oneInchData._buyAmt, - oneInchData._sellAmt, - oneInchData.feeCollector, - oneInchData.feeAmount, - 0, - setId - ); - } + emit LogSellThree( + address(oneInchData.buyToken), + address(oneInchData.sellToken), + oneInchData._buyAmt, + oneInchData._sellAmt, + 0, + setId + ); + _eventCode = keccak256("LogSellThree(address,address,uint256,uint256,uint256,uint256)"); + _eventParam = abi.encode( + address(oneInchData.buyToken), + address(oneInchData.sellToken), + oneInchData._buyAmt, + oneInchData._sellAmt, + 0, + setId + ); emitEvent(_eventCode, _eventParam); } } -contract OneInchResolverHelpers is OneInchEventResolver { - function _sell ( - OneInchData memory oneInchData, - uint feePercent, +contract OneProtoResolverHelpers is OneInchEventResolver { + function _sell( + OneProtoData memory oneProtoData, + uint256 getId, + uint256 setId + ) internal { + uint _sellAmt = getUint(getId, oneProtoData._sellAmt); + + oneProtoData._sellAmt = _sellAmt == uint(-1) ? + getTokenBal(oneProtoData.sellToken) : + _sellAmt; + + OneProtoInterface oneProtoContract = OneProtoInterface(getOneProtoAddress()); + + (, oneProtoData.distribution) = oneProtoContract.getExpectedReturn( + oneProtoData.sellToken, + oneProtoData.buyToken, + oneProtoData._sellAmt, + 5, + 0 + ); + + oneProtoData._buyAmt = oneProtoSwap( + oneProtoContract, + oneProtoData + ); + + setUint(setId, oneProtoData._buyAmt); + + emitLogSell(oneProtoData, getId, setId); + } + + function _sellTwo( + OneProtoData memory oneProtoData, + uint getId, + uint setId + ) internal { + uint _sellAmt = getUint(getId, oneProtoData._sellAmt); + + oneProtoData._sellAmt = _sellAmt == uint(-1) ? + getTokenBal(oneProtoData.sellToken) : + _sellAmt; + + oneProtoData._buyAmt = oneProtoSwap( + OneProtoInterface(getOneProtoAddress()), + oneProtoData + ); + + setUint(setId, oneProtoData._buyAmt); + emitLogSellTwo(oneProtoData, getId, setId); + } + + function _sellMulti( + OneProtoMultiData memory oneProtoData, + uint getId, + uint setId + ) internal { + uint _sellAmt = getUint(getId, oneProtoData._sellAmt); + + oneProtoData._sellAmt = _sellAmt == uint(-1) ? + getTokenBal(oneProtoData.sellToken) : + _sellAmt; + + oneProtoData._buyAmt = oneProtoSwapMulti(oneProtoData); + setUint(setId, oneProtoData._buyAmt); + + emitLogSellMulti(oneProtoData, getId, setId); + } +} + +contract OneInchResolverHelpers is OneProtoResolverHelpers { + function _sellThree( + OneInchData memory oneInchData, uint setId ) internal { - TokenInterface _buyAddr = oneInchData.buyToken; TokenInterface _sellAddr = oneInchData.sellToken; uint ethAmt; @@ -232,29 +504,21 @@ contract OneInchResolverHelpers is OneInchEventResolver { require(checkOneInchSig(oneInchData.callData), "Not-swap-function"); - uint buyAmt = oneInchSwap(oneInchData, ethAmt); + oneInchData._buyAmt = oneInchSwap(oneInchData, ethAmt); + setUint(setId, oneInchData._buyAmt); - (uint leftBuyAmt, uint feeAmount) = takeFee( - address(_buyAddr), - buyAmt, - oneInchData.feeCollector, - feePercent - ); - setUint(setId, leftBuyAmt); - oneInchData.feeAmount = feeAmount; - - emitLogSell(oneInchData, setId); + emitLogSellThree(oneInchData, setId); } } -contract OneInchResolver is OneInchResolverHelpers { +contract OneProto is OneInchResolverHelpers { /** - * @dev Sell ETH/ERC20_Token using 1inch. + * @dev Sell ETH/ERC20_Token using 1proto. * @param buyAddr buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAddr selling token amount.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param sellAddr selling token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) * @param sellAmt selling token amount. * @param unitAmt unit amount of buyAmt/sellAmt with slippage. - * @param callData Data from 1inch API. + * @param getId Get token amount at this ID from `InstaMemory` Contract. * @param setId Set token amount at this ID in `InstaMemory` Contract. */ function sell( @@ -262,23 +526,91 @@ contract OneInchResolver is OneInchResolverHelpers { address sellAddr, uint sellAmt, uint unitAmt, - bytes calldata callData, + uint getId, uint setId ) external payable { - OneInchData memory oneInchData = OneInchData({ + OneProtoData memory oneProtoData = OneProtoData({ buyToken: TokenInterface(buyAddr), sellToken: TokenInterface(sellAddr), - unitAmt: unitAmt, - callData: callData, - feeCollector: address(0), _sellAmt: sellAmt, + unitAmt: unitAmt, + distribution: new uint[](0), _buyAmt: 0, - feeAmount: 0 + disableDexes: 0 }); - _sell(oneInchData, 0, setId); + _sell(oneProtoData, getId, setId); } + /** + * @dev Sell ETH/ERC20_Token using 1proto using off-chain calculation. + * @param buyAddr buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param sellAddr selling token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param sellAmt selling token amount. + * @param unitAmt unit amount of buyAmt/sellAmt with slippage. + * @param distribution distribution of swap across different dex. + * @param disableDexes disable a dex. (To disable none: 0) + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function sellTwo( + address buyAddr, + address sellAddr, + uint sellAmt, + uint unitAmt, + uint[] calldata distribution, + uint disableDexes, + uint getId, + uint setId + ) external payable { + OneProtoData memory oneProtoData = OneProtoData({ + buyToken: TokenInterface(buyAddr), + sellToken: TokenInterface(sellAddr), + _sellAmt: sellAmt, + unitAmt: unitAmt, + distribution: distribution, + disableDexes: disableDexes, + _buyAmt: 0 + }); + + _sellTwo(oneProtoData, getId, setId); + } + + /** + * @dev Sell ETH/ERC20_Token using 1proto using muliple token. + * @param tokens array of tokens. + * @param sellAmt selling token amount. + * @param unitAmt unit amount of buyAmt/sellAmt with slippage. + * @param distribution distribution of swap across different dex. + * @param disableDexes disable a dex. (To disable none: 0) + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function sellMulti( + address[] calldata tokens, + uint sellAmt, + uint unitAmt, + uint[] calldata distribution, + uint[] calldata disableDexes, + uint getId, + uint setId + ) external payable { + OneProtoMultiData memory oneProtoData = OneProtoMultiData({ + tokens: tokens, + buyToken: TokenInterface(address(tokens[tokens.length - 1])), + sellToken: TokenInterface(address(tokens[0])), + unitAmt: unitAmt, + distribution: distribution, + disableDexes: disableDexes, + _sellAmt: sellAmt, + _buyAmt: 0 + }); + + _sellMulti(oneProtoData, getId, setId); + } +} + +contract OneInch is OneProto { /** * @dev Sell ETH/ERC20_Token using 1inch. * @param buyAddr buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) @@ -286,38 +618,29 @@ contract OneInchResolver is OneInchResolverHelpers { * @param sellAmt selling token amount. * @param unitAmt unit amount of buyAmt/sellAmt with slippage. * @param callData Data from 1inch API. - * @param feeCollector Fee amount to transfer. - * @param feePercent Fee percentage on buyAmt. * @param setId Set token amount at this ID in `InstaMemory` Contract. */ - function sellFee( + function sellThree( address buyAddr, address sellAddr, uint sellAmt, uint unitAmt, bytes calldata callData, - address feeCollector, - uint feePercent, uint setId ) external payable { - require(feePercent > 0 && feePercent <= 2 * 10 ** 16, "Fee more than 2%"); - require(feeCollector != address(0), "feeCollector is not vaild address"); - OneInchData memory oneInchData = OneInchData({ buyToken: TokenInterface(buyAddr), sellToken: TokenInterface(sellAddr), - _sellAmt: sellAmt, unitAmt: unitAmt, callData: callData, - feeCollector: feeCollector, - _buyAmt: 0, - feeAmount: 0 + _sellAmt: sellAmt, + _buyAmt: 0 }); - _sell(oneInchData, feePercent, setId); + _sellThree(oneInchData, setId); } } -contract ConnectOneInchOnChain is OneInchResolver { - string public name = "1inch-Onchain-v1"; +contract ConnectOne is OneInch { + string public name = "1inch-1proto-v1"; } \ No newline at end of file diff --git a/contracts/connectors/1proto.sol b/contracts/connectors/1proto.sol deleted file mode 100644 index 480b769..0000000 --- a/contracts/connectors/1proto.sol +++ /dev/null @@ -1,772 +0,0 @@ -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - - -// import files from common directory -import { TokenInterface , MemoryInterface, EventInterface} from "../common/interfaces.sol"; -import { Stores } from "../common/stores.sol"; -import { DSMath } from "../common/math.sol"; - -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - - -interface OneProtoInterface { - function swapWithReferral( - TokenInterface fromToken, - TokenInterface destToken, - uint256 amount, - uint256 minReturn, - uint256[] calldata distribution, - uint256 flags, // See contants in IOneSplit.sol - address referral, - uint256 feePercent - ) external payable returns(uint256); - - function swapWithReferralMulti( - TokenInterface[] calldata tokens, - uint256 amount, - uint256 minReturn, - uint256[] calldata distribution, - uint256[] calldata flags, - address referral, - uint256 feePercent - ) external payable returns(uint256 returnAmount); - - function getExpectedReturn( - TokenInterface fromToken, - TokenInterface destToken, - uint256 amount, - uint256 parts, - uint256 flags // See constants in IOneSplit.sol - ) - external - view - returns( - uint256 returnAmount, - uint256[] memory distribution - ); -} - - -contract OneHelpers is Stores, DSMath { - using SafeERC20 for IERC20; - - /** - * @dev Return 1proto Address - */ - function getOneProtoAddress() internal virtual view returns (address payable) { - return 0x50FDA034C0Ce7a8f7EFDAebDA7Aa7cA21CC1267e; - } - - function getReferralAddr() internal pure returns (address) { - return 0xa7615CD307F323172331865181DC8b80a2834324; // TODO - change address - } - - function convert18ToDec(uint _dec, uint256 _amt) internal pure returns (uint256 amt) { - amt = (_amt / 10 ** (18 - _dec)); - } - - function convertTo18(uint _dec, uint256 _amt) internal pure returns (uint256 amt) { - amt = mul(_amt, 10 ** (18 - _dec)); - } - - function getTokenBal(TokenInterface token) internal view returns(uint _amt) { - _amt = address(token) == getEthAddr() ? address(this).balance : token.balanceOf(address(this)); - } - - function getTokensDec(TokenInterface buyAddr, TokenInterface sellAddr) internal view returns(uint buyDec, uint sellDec) { - buyDec = address(buyAddr) == getEthAddr() ? 18 : buyAddr.decimals(); - sellDec = address(sellAddr) == getEthAddr() ? 18 : sellAddr.decimals(); - } - - function getSlippageAmt( - TokenInterface _buyAddr, - TokenInterface _sellAddr, - uint _sellAmt, - uint unitAmt - ) internal view returns(uint _slippageAmt) { - (uint _buyDec, uint _sellDec) = getTokensDec(_buyAddr, _sellAddr); - uint _sellAmt18 = convertTo18(_sellDec, _sellAmt); - _slippageAmt = convert18ToDec(_buyDec, wmul(unitAmt, _sellAmt18)); - } - - function convertToTokenInterface(address[] memory tokens) internal pure returns(TokenInterface[] memory) { - TokenInterface[] memory _tokens = new TokenInterface[](tokens.length); - for (uint i = 0; i < tokens.length; i++) { - _tokens[i] = TokenInterface(tokens[i]); - } - return _tokens; - } - - function _transfer(address payable to, IERC20 token, uint _amt) internal { - address(token) == getEthAddr() ? - to.transfer(_amt) : - token.safeTransfer(to, _amt); - } - - function takeFee( - address token, - uint amount, - address feeCollector, - uint feePercent - ) internal returns (uint leftAmt, uint feeAmount){ - if (feeCollector != address(0)) { - feeAmount = wmul(amount, feePercent); - leftAmt = sub(amount, feeAmount); - uint feeCollectorAmt = wmul(feeAmount, 7 * 10 ** 17); // 70% to feeCollector - uint restAmt = sub(feeAmount, feeCollectorAmt); // rest 30% - IERC20 tokenContract = IERC20(token); - _transfer(payable(feeCollector), tokenContract, feeCollectorAmt); - _transfer(payable(getReferralAddr()), tokenContract, restAmt); - } else { - leftAmt = amount; - } - } -} - - -contract Resolver is OneHelpers { - struct OneProtoData { - TokenInterface sellToken; - TokenInterface buyToken; - uint _sellAmt; - uint _buyAmt; - uint unitAmt; - address feeCollector; - uint256 feeAmount; - uint[] distribution; - uint disableDexes; - } - - function oneProtoSwap( - OneProtoInterface oneProtoContract, - OneProtoData memory oneProtoData - ) internal returns (uint buyAmt) { - TokenInterface _sellAddr = oneProtoData.sellToken; - TokenInterface _buyAddr = oneProtoData.buyToken; - uint _sellAmt = oneProtoData._sellAmt; - - uint _slippageAmt = getSlippageAmt(_buyAddr, _sellAddr, _sellAmt, oneProtoData.unitAmt); - - uint ethAmt; - if (address(_sellAddr) == getEthAddr()) { - ethAmt = _sellAmt; - } else { - _sellAddr.approve(address(oneProtoContract), _sellAmt); - } - - - uint initalBal = getTokenBal(_buyAddr); - oneProtoContract.swapWithReferral.value(ethAmt)( - _sellAddr, - _buyAddr, - _sellAmt, - _slippageAmt, - oneProtoData.distribution, - oneProtoData.disableDexes, - getReferralAddr(), - 0 - ); - uint finalBal = getTokenBal(_buyAddr); - - buyAmt = sub(finalBal, initalBal); - - require(_slippageAmt <= buyAmt, "Too much slippage"); - } - - struct OneProtoMultiData { - address[] tokens; - TokenInterface sellToken; - TokenInterface buyToken; - uint _sellAmt; - uint _buyAmt; - uint unitAmt; - address feeCollector; - uint256 feeAmount; - uint[] distribution; - uint[] disableDexes; - } - - function oneProtoSwapMulti(OneProtoMultiData memory oneProtoData) internal returns (uint buyAmt) { - TokenInterface _sellAddr = oneProtoData.sellToken; - TokenInterface _buyAddr = oneProtoData.buyToken; - uint _sellAmt = oneProtoData._sellAmt; - uint _slippageAmt = getSlippageAmt(_buyAddr, _sellAddr, _sellAmt, oneProtoData.unitAmt); - - OneProtoInterface oneSplitContract = OneProtoInterface(getOneProtoAddress()); - uint ethAmt; - if (address(_sellAddr) == getEthAddr()) { - ethAmt = _sellAmt; - } else { - _sellAddr.approve(address(oneSplitContract), _sellAmt); - } - - uint initalBal = getTokenBal(_buyAddr); - oneSplitContract.swapWithReferralMulti.value(ethAmt)( - convertToTokenInterface(oneProtoData.tokens), - _sellAmt, - _slippageAmt, - oneProtoData.distribution, - oneProtoData.disableDexes, - getReferralAddr(), - 0 - ); - uint finalBal = getTokenBal(_buyAddr); - - buyAmt = sub(finalBal, initalBal); - - require(_slippageAmt <= buyAmt, "Too much slippage"); - } -} - -contract OneProtoEventResolver is Resolver { - event LogSell( - address indexed buyToken, - address indexed sellToken, - uint256 buyAmt, - uint256 sellAmt, - uint256 getId, - uint256 setId - ); - - event LogSellFee( - address indexed buyToken, - address indexed sellToken, - uint256 buyAmt, - uint256 sellAmt, - address indexed feeCollector, - uint256 feeAmount, - uint256 getId, - uint256 setId - ); - - function emitLogSell( - OneProtoData memory oneProtoData, - uint256 getId, - uint256 setId - ) internal { - bytes32 _eventCode; - bytes memory _eventParam; - if (oneProtoData.feeCollector == address(0)) { - emit LogSell( - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - getId, - setId - ); - _eventCode = keccak256("LogSell(address,address,uint256,uint256,uint256,uint256)"); - _eventParam = abi.encode( - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - getId, - setId - ); - } else { - emit LogSellFee( - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - oneProtoData.feeCollector, - oneProtoData.feeAmount, - getId, - setId - ); - _eventCode = keccak256("LogSellFee(address,address,uint256,uint256,address,uint256,uint256,uint256)"); - _eventParam = abi.encode( - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - oneProtoData.feeCollector, - oneProtoData.feeAmount, - getId, - setId - ); - } - emitEvent(_eventCode, _eventParam); - } - - event LogSellTwo( - address indexed buyToken, - address indexed sellToken, - uint256 buyAmt, - uint256 sellAmt, - uint256 getId, - uint256 setId - ); - - event LogSellFeeTwo( - address indexed buyToken, - address indexed sellToken, - uint256 buyAmt, - uint256 sellAmt, - address indexed feeCollector, - uint256 feeAmount, - uint256 getId, - uint256 setId - ); - - function emitLogSellTwo( - OneProtoData memory oneProtoData, - uint256 getId, - uint256 setId - ) internal { - bytes32 _eventCode; - bytes memory _eventParam; - if (oneProtoData.feeCollector == address(0)) { - emit LogSellTwo( - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - getId, - setId - ); - _eventCode = keccak256("LogSellTwo(address,address,uint256,uint256,uint256,uint256)"); - _eventParam = abi.encode( - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - getId, - setId - ); - } else { - emit LogSellFeeTwo( - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - oneProtoData.feeCollector, - oneProtoData.feeAmount, - getId, - setId - ); - _eventCode = keccak256("LogSellFeeTwo(address,address,uint256,uint256,address,uint256,uint256,uint256)"); - _eventParam = abi.encode( - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - oneProtoData.feeCollector, - oneProtoData.feeAmount, - getId, - setId - ); - } - emitEvent(_eventCode, _eventParam); - } - - event LogSellMulti( - address[] tokens, - address indexed buyToken, - address indexed sellToken, - uint256 buyAmt, - uint256 sellAmt, - uint256 getId, - uint256 setId - ); - - event LogSellFeeMulti( - address[] tokens, - address indexed buyToken, - address indexed sellToken, - uint256 buyAmt, - uint256 sellAmt, - address indexed feeCollector, - uint256 feeAmount, - uint256 getId, - uint256 setId - ); - - function emitLogSellMulti( - OneProtoMultiData memory oneProtoData, - uint256 getId, - uint256 setId - ) internal { - bytes32 _eventCode; - bytes memory _eventParam; - if (oneProtoData.feeCollector == address(0)) { - emit LogSellMulti( - oneProtoData.tokens, - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - getId, - setId - ); - _eventCode = keccak256("LogSellMulti(address[],address,address,uint256,uint256,uint256,uint256)"); - _eventParam = abi.encode( - oneProtoData.tokens, - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - getId, - setId - ); - } else { - emit LogSellFeeMulti( - oneProtoData.tokens, - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - oneProtoData.feeCollector, - oneProtoData.feeAmount, - getId, - setId - ); - _eventCode = keccak256("LogSellFeeMulti(address[],address,address,uint256,uint256,address,uint256,uint256,uint256)"); - _eventParam = abi.encode( - oneProtoData.tokens, - address(oneProtoData.buyToken), - address(oneProtoData.sellToken), - oneProtoData._buyAmt, - oneProtoData._sellAmt, - oneProtoData.feeCollector, - oneProtoData.feeAmount, - getId, - setId - ); - } - emitEvent(_eventCode, _eventParam); - } -} - -contract OneProtoResolverHelpers is OneProtoEventResolver { - function _sell( - OneProtoData memory oneProtoData, - uint256 feePercent, - uint256 getId, - uint256 setId - ) internal { - uint _sellAmt = getUint(getId, oneProtoData._sellAmt); - oneProtoData._sellAmt = _sellAmt == uint(-1) ? - getTokenBal(oneProtoData.sellToken) : - _sellAmt; - - OneProtoInterface oneProtoContract = OneProtoInterface(getOneProtoAddress()); - - (, oneProtoData.distribution) = oneProtoContract.getExpectedReturn( - oneProtoData.sellToken, - oneProtoData.buyToken, - oneProtoData._sellAmt, - 5, - 0 - ); - - oneProtoData._buyAmt = oneProtoSwap( - oneProtoContract, - oneProtoData - ); - - (uint leftBuyAmt, uint feeAmount) = takeFee( - address(oneProtoData.buyToken), - oneProtoData._buyAmt, - oneProtoData.feeCollector, - feePercent - ); - - setUint(setId, leftBuyAmt); - oneProtoData.feeAmount = feeAmount; - - emitLogSell(oneProtoData, getId, setId); - } - - function _sellTwo( - OneProtoData memory oneProtoData, - uint256 feePercent, - uint getId, - uint setId - ) internal { - uint _sellAmt = getUint(getId, oneProtoData._sellAmt); - - oneProtoData._sellAmt = _sellAmt == uint(-1) ? - getTokenBal(oneProtoData.sellToken) : - _sellAmt; - - oneProtoData._buyAmt = oneProtoSwap( - OneProtoInterface(getOneProtoAddress()), - oneProtoData - ); - - (uint leftBuyAmt, uint feeAmount) = takeFee( - address(oneProtoData.buyToken), - oneProtoData._buyAmt, - oneProtoData.feeCollector, - feePercent - ); - - setUint(setId, leftBuyAmt); - oneProtoData.feeAmount = feeAmount; - - emitLogSellTwo(oneProtoData, getId, setId); - } - - function _sellMulti( - OneProtoMultiData memory oneProtoData, - uint256 feePercent, - uint getId, - uint setId - ) internal { - uint _sellAmt = getUint(getId, oneProtoData._sellAmt); - - oneProtoData._sellAmt = _sellAmt == uint(-1) ? - getTokenBal(oneProtoData.sellToken) : - _sellAmt; - - oneProtoData._buyAmt = oneProtoSwapMulti(oneProtoData); - - uint leftBuyAmt; - (leftBuyAmt, oneProtoData.feeAmount) = takeFee( - address(oneProtoData.buyToken), - oneProtoData._buyAmt, - oneProtoData.feeCollector, - feePercent - ); - setUint(setId, leftBuyAmt); - - emitLogSellMulti(oneProtoData, getId, setId); - } -} - -contract OneProtoResolver is OneProtoResolverHelpers { - /** - * @dev Sell ETH/ERC20_Token using 1proto. - * @param buyAddr buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAddr selling token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAmt selling token amount. - * @param unitAmt unit amount of buyAmt/sellAmt with slippage. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - */ - function sell( - address buyAddr, - address sellAddr, - uint sellAmt, - uint unitAmt, - uint getId, - uint setId - ) external payable { - OneProtoData memory oneProtoData = OneProtoData({ - buyToken: TokenInterface(buyAddr), - sellToken: TokenInterface(sellAddr), - _sellAmt: sellAmt, - unitAmt: unitAmt, - distribution: new uint[](0), - feeCollector: address(0), - _buyAmt: 0, - disableDexes: 0, - feeAmount: 0 - }); - - _sell(oneProtoData, 0, getId, setId); - } - - /** - * @dev Sell ETH/ERC20_Token using 1proto on-chain calculation. - * @param buyAddr buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAddr selling token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAmt selling token amount. - * @param unitAmt unit amount of buyAmt/sellAmt with slippage. - * @param feeCollector Fee amount to transfer. - * @param feePercent Fee percentage on buyAmt. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - */ - function sellFee( - address buyAddr, - address sellAddr, - uint sellAmt, - uint unitAmt, - address feeCollector, - uint feePercent, - uint getId, - uint setId - ) external payable { - require(feePercent > 0 && feePercent <= 2 * 10 ** 16, "Fee more than 2%"); - require(feeCollector != address(0), "feeCollector is not vaild address"); - - OneProtoData memory oneProtoData = OneProtoData({ - buyToken: TokenInterface(buyAddr), - sellToken: TokenInterface(sellAddr), - _sellAmt: sellAmt, - unitAmt: unitAmt, - distribution: new uint[](0), - feeCollector: feeCollector, - _buyAmt: 0, - disableDexes: 0, - feeAmount: 0 - }); - - _sell(oneProtoData, feePercent, getId, setId); - } - - /** - * @dev Sell ETH/ERC20_Token using 1proto using off-chain calculation. - * @param buyAddr buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAddr selling token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAmt selling token amount. - * @param unitAmt unit amount of buyAmt/sellAmt with slippage. - * @param distribution distribution of swap across different dex. - * @param disableDexes disable a dex. (To disable none: 0) - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - */ - function sellTwo( - address buyAddr, - address sellAddr, - uint sellAmt, - uint unitAmt, - uint[] calldata distribution, - uint disableDexes, - uint getId, - uint setId - ) external payable { - OneProtoData memory oneProtoData = OneProtoData({ - buyToken: TokenInterface(buyAddr), - sellToken: TokenInterface(sellAddr), - _sellAmt: sellAmt, - unitAmt: unitAmt, - distribution: distribution, - disableDexes: disableDexes, - feeCollector: address(0), - _buyAmt: 0, - feeAmount: 0 - }); - - _sellTwo(oneProtoData, 0, getId, setId); - } - - - /** - * @dev Sell ETH/ERC20_Token using 1proto. - * @param buyAddr buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAddr selling token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAmt selling token amount. - * @param unitAmt unit amount of buyAmt/sellAmt with slippage. - * @param distribution distribution of swap across different dex. - * @param disableDexes disable a dex. (To disable none: 0) - * @param feeCollector Fee amount to transfer. - * @param feePercent Fee percentage on buyAmt. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - */ - function sellFeeTwo( - address buyAddr, - address sellAddr, - uint sellAmt, - uint unitAmt, - uint[] calldata distribution, - uint disableDexes, - address feeCollector, - uint feePercent, - uint getId, - uint setId - ) external payable { - require(feePercent > 0 && feePercent <= 2 * 10 ** 16, "Fee more than 2%"); - require(feeCollector != address(0), "feeCollector is not vaild address"); - OneProtoData memory oneProtoData = OneProtoData({ - buyToken: TokenInterface(buyAddr), - sellToken: TokenInterface(sellAddr), - _sellAmt: sellAmt, - unitAmt: unitAmt, - distribution: distribution, - disableDexes: disableDexes, - feeCollector: feeCollector, - _buyAmt: 0, - feeAmount: 0 - }); - - _sellTwo(oneProtoData, feePercent, getId, setId); - } - - /** - * @dev Sell ETH/ERC20_Token using 1proto using muliple token. - * @param tokens array of tokens. - * @param sellAmt selling token amount. - * @param unitAmt unit amount of buyAmt/sellAmt with slippage. - * @param distribution distribution of swap across different dex. - * @param disableDexes disable a dex. (To disable none: 0) - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - */ - function sellMulti( - address[] calldata tokens, - uint sellAmt, - uint unitAmt, - uint[] calldata distribution, - uint[] calldata disableDexes, - uint getId, - uint setId - ) external payable { - OneProtoMultiData memory oneProtoData = OneProtoMultiData({ - tokens: tokens, - buyToken: TokenInterface(address(tokens[tokens.length - 1])), - sellToken: TokenInterface(address(tokens[0])), - unitAmt: unitAmt, - distribution: distribution, - disableDexes: disableDexes, - _sellAmt: sellAmt, - feeCollector: address(0), - _buyAmt: 0, - feeAmount: 0 - }); - - _sellMulti(oneProtoData, 0, getId, setId); - } - - /** - * @dev Sell ETH/ERC20_Token using 1proto using muliple token. - * @param tokens buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param sellAmt selling token amount. - * @param unitAmt unit amount of buyAmt/sellAmt with slippage. - * @param distribution distribution of swap across different dex. - * @param disableDexes disable a dex. (To disable none: 0) - * @param feeCollector Fee amount to transfer. - * @param feePercent Fee percentage on buyAmt. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - */ - function sellFeeMulti( - address[] calldata tokens, - uint sellAmt, - uint unitAmt, - uint[] calldata distribution, - uint[] calldata disableDexes, - address feeCollector, - uint feePercent, - uint getId, - uint setId - ) external payable { - require(feePercent > 0 && feePercent <= 2 * 10 ** 16, "Fee more than 2%"); - require(feeCollector != address(0), "feeCollector is not vaild address"); - TokenInterface buyToken = TokenInterface(address(tokens[tokens.length - 1])); - OneProtoMultiData memory oneProtoData = OneProtoMultiData({ - tokens: tokens, - buyToken: buyToken, - sellToken: TokenInterface(address(tokens[0])), - _sellAmt: sellAmt, - unitAmt: unitAmt, - distribution: distribution, - disableDexes: disableDexes, - feeCollector: feeCollector, - _buyAmt: 0, - feeAmount: 0 - }); - - _sellMulti(oneProtoData, feePercent, getId, setId); - } -} - -contract ConnectOneInchOffChain is OneProtoResolver { - string public name = "1inch-OffChain-v1"; -} \ No newline at end of file From ad235465e2c0563d5d4682aee11a6ebaaa8ac5e8 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Fri, 14 Aug 2020 02:02:55 +0530 Subject: [PATCH 7/9] Added oneInch Mapping contract --- contracts/mapping/1inch.sol | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 contracts/mapping/1inch.sol diff --git a/contracts/mapping/1inch.sol b/contracts/mapping/1inch.sol new file mode 100644 index 0000000..d01284e --- /dev/null +++ b/contracts/mapping/1inch.sol @@ -0,0 +1,40 @@ +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +interface IndexInterface { + function master() external view returns (address); +} + +interface ConnectorsInterface { + function chief(address) external view returns (bool); +} + +contract Helpers { + + event LogChangeOneProto(address oneProto); + + address public constant connectors = 0xD6A602C01a023B98Ecfb29Df02FBA380d3B21E0c; + address public constant instaIndex = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723; + address public oneProtoAddress; + + modifier isChief virtual { + require( + ConnectorsInterface(connectors).chief(msg.sender) || + IndexInterface(instaIndex).master() == msg.sender, "not-Chief"); + _; + } + + function changeOneProtoAddress(address _oneProtoAddr) external isChief { + require(_oneProtoAddr != address(0), "oneProtoAddress-is-address(0)"); + require(oneProtoAddress != _oneProtoAddr, "Same-oneProtoAddress"); + + oneProtoAddress = _oneProtoAddr; + emit LogChangeOneProto(_oneProtoAddr); + } +} + +contract InstaOneMapping is Helpers { + constructor () public { + oneProtoAddress = 0x6cb2291A3c3794fcA0F5b6E34a8E6eA7933CA667; + } +} From 5eff1d37dc5a26d8b630fe324c0dd7e0039f3c98 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sat, 15 Aug 2020 01:51:26 +0530 Subject: [PATCH 8/9] Minor changes --- contracts/connectors/1inch.sol | 45 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/contracts/connectors/1inch.sol b/contracts/connectors/1inch.sol index 9331f74..de7e1f8 100644 --- a/contracts/connectors/1inch.sol +++ b/contracts/connectors/1inch.sol @@ -1,7 +1,6 @@ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; - // import files from common directory import { TokenInterface , MemoryInterface, EventInterface} from "../common/interfaces.sol"; import { Stores } from "../common/stores.sol"; @@ -26,25 +25,21 @@ interface OneInchInterace { } interface OneProtoInterface { - function swapWithReferral( + function swap( TokenInterface fromToken, TokenInterface destToken, uint256 amount, uint256 minReturn, uint256[] calldata distribution, - uint256 flags, // See contants in IOneSplit.sol - address referral, - uint256 feePercent + uint256 flags // See contants in IOneSplit.sol ) external payable returns(uint256); - function swapWithReferralMulti( + function swapMulti( TokenInterface[] calldata tokens, uint256 amount, uint256 minReturn, uint256[] calldata distribution, - uint256[] calldata flags, - address referral, - uint256 feePercent + uint256[] calldata flags ) external payable returns(uint256 returnAmount); function getExpectedReturn( @@ -62,13 +57,25 @@ interface OneProtoInterface { ); } +interface OneProtoMappingInterface { + function oneProtoAddress() external view returns(address); +} + contract OneHelpers is Stores, DSMath { + + /** + * @dev Return 1proto mapping Address + */ + function getOneProtoMappingAddress() internal pure returns (address payable) { + return 0x8d0287AFa7755BB5f2eFe686AA8d4F0A7BC4AE7F; + } + /** * @dev Return 1proto Address */ - function getOneProtoAddress() internal pure returns (address payable) { - return 0x50FDA034C0Ce7a8f7EFDAebDA7Aa7cA21CC1267e; + function getOneProtoAddress() internal view returns (address payable) { + return payable(OneProtoMappingInterface(getOneProtoMappingAddress()).oneProtoAddress()); } /** @@ -92,10 +99,6 @@ contract OneHelpers is Stores, DSMath { return 0xf88309d7; } - function getReferralAddr() internal pure returns (address) { - return 0xa7615CD307F323172331865181DC8b80a2834324; // TODO - change address - } - function convert18ToDec(uint _dec, uint256 _amt) internal pure returns (uint256 amt) { amt = (_amt / 10 ** (18 - _dec)); } @@ -164,15 +167,13 @@ contract OneProtoResolver is OneHelpers { uint initalBal = getTokenBal(_buyAddr); - oneProtoContract.swapWithReferral.value(ethAmt)( + oneProtoContract.swap.value(ethAmt)( _sellAddr, _buyAddr, _sellAmt, _slippageAmt, oneProtoData.distribution, - oneProtoData.disableDexes, - getReferralAddr(), - 0 + oneProtoData.disableDexes ); uint finalBal = getTokenBal(_buyAddr); @@ -207,14 +208,12 @@ contract OneProtoResolver is OneHelpers { } uint initalBal = getTokenBal(_buyAddr); - oneSplitContract.swapWithReferralMulti.value(ethAmt)( + oneSplitContract.swapMulti.value(ethAmt)( convertToTokenInterface(oneProtoData.tokens), _sellAmt, _slippageAmt, oneProtoData.distribution, - oneProtoData.disableDexes, - getReferralAddr(), - 0 + oneProtoData.disableDexes ); uint finalBal = getTokenBal(_buyAddr); From faaf8fd3a7b7d7b4d3f9a3c1f02123ffda2a24c9 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sat, 15 Aug 2020 01:51:40 +0530 Subject: [PATCH 9/9] MInor change in mapping contract --- contracts/mapping/1inch.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mapping/1inch.sol b/contracts/mapping/1inch.sol index d01284e..0aba6d6 100644 --- a/contracts/mapping/1inch.sol +++ b/contracts/mapping/1inch.sol @@ -17,7 +17,7 @@ contract Helpers { address public constant instaIndex = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723; address public oneProtoAddress; - modifier isChief virtual { + modifier isChief { require( ConnectorsInterface(connectors).chief(msg.sender) || IndexInterface(instaIndex).master() == msg.sender, "not-Chief");