mirror of https://github.com/dap-ps/discover.git
feat: kyber integration
This commit is contained in:
parent
52f6fb16e5
commit
bdda80aeaf
|
@ -33,15 +33,12 @@ module.exports = {
|
|||
'https://ropsten.infura.io/v3/8675214b97b44e96b70d05326c61fd6a',
|
||||
],
|
||||
deploy: {
|
||||
MiniMeTokenFactory: {
|
||||
deploy: false,
|
||||
},
|
||||
MiniMeToken: {
|
||||
address: '0xc55cf4b03948d7ebc8b9e8bad92643703811d162',
|
||||
},
|
||||
Discover: {
|
||||
address: '0xC8d48B421eAFdD75d5144E8f06882Cb5F0746Bd2',
|
||||
args:["0xbF5d8683b9BE6C43fcA607eb2a6f2626A18837a6"]
|
||||
},
|
||||
DiscoverKyberSwap: {
|
||||
args: ["$Discover", "0x818E6FECD516Ecc3849DAf6845e3EC868087B755", "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "0xbF5d8683b9BE6C43fcA607eb2a6f2626A18837a6", "0x0000000000000000000000000000000000000000", 20]
|
||||
}
|
||||
},
|
||||
tracking: 'shared.testnet.chains.json',
|
||||
},
|
||||
|
@ -61,6 +58,9 @@ module.exports = {
|
|||
Discover: {
|
||||
address: '0x5bCF2767F86f14eDd82053bfBfd5069F68C2C5F8',
|
||||
},
|
||||
DiscoverKyberSwap: {
|
||||
args: ["$Discover", "0x818E6FECD516Ecc3849DAf6845e3EC868087B755", "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "0x744d70fdbe2ba4cf95131626614a1763df805b9e", "0x0000000000000000000000000000000000000000", 20]
|
||||
}
|
||||
},
|
||||
tracking: 'shared.mainnet.chains.json',
|
||||
},
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
pragma solidity ^0.5.2;
|
||||
|
||||
import "./kyber/KyberNetworkProxy.sol";
|
||||
import "./Discover.sol";
|
||||
import "./token/ERC20Token.sol";
|
||||
|
||||
contract DiscoverKyberSwap is Controlled {
|
||||
address public SNT;
|
||||
address public ETH;
|
||||
KyberNetworkProxy public kyberProxy;
|
||||
Discover public discover;
|
||||
address public walletId;
|
||||
uint public maxSlippage;
|
||||
|
||||
|
||||
/**
|
||||
* @param _discover Discover contract address
|
||||
* @param _kyberProxy Kyber Network Proxy address
|
||||
* @param _ETH Kyber ETH address
|
||||
* @param _SNT Kyber SNT address
|
||||
* @param _walletId Wallet for Kyber network fees
|
||||
* @param _maxSlippage Max slippage rate
|
||||
*/
|
||||
constructor(address _discover, address _kyberProxy, address _ETH, address _SNT, address _walletId, uint _maxSlippage) public {
|
||||
require(_maxSlippage < 100);
|
||||
|
||||
discover = Discover(_discover);
|
||||
kyberProxy = KyberNetworkProxy(_kyberProxy);
|
||||
ETH = _ETH;
|
||||
SNT = _SNT;
|
||||
walletId = _walletId;
|
||||
maxSlippage = _maxSlippage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Gets the conversion rate for the destToken given the srcQty.
|
||||
* @param srcToken source token contract address
|
||||
* @param srcQty amount of source tokens
|
||||
* @return exchange rate
|
||||
*/
|
||||
function getConversionRates(address srcToken, uint srcQty) public view returns (uint expectedRate, uint slippageRate)
|
||||
{
|
||||
if(srcToken == address(0)){
|
||||
srcToken = ETH;
|
||||
}
|
||||
|
||||
|
||||
(expectedRate, slippageRate) = kyberProxy.getExpectedRate(srcToken, SNT, srcQty);
|
||||
require(expectedRate > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Upvote in discover
|
||||
* @dev Requires a msg.value if using ETH
|
||||
* @param _id Id to upvote
|
||||
* @param _token Token to convert to SNT (see https://developer.kyber.network/docs/Environments-Intro/). Address 0 can be used for ETH too
|
||||
* @param _amount Amount of tokens/eth to convert
|
||||
*/
|
||||
function upvote(bytes32 _id, address _token, uint _amount) public payable {
|
||||
uint sntAmount = _tradeTokens(_token, _amount);
|
||||
discover.upvote(_id, sntAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Downvote in discover
|
||||
* @dev Requires a msg.value if using ETH
|
||||
* @param _id Id to upvote
|
||||
* @param _token Token to convert to SNT (see https://developer.kyber.network/docs/Environments-Intro/). Address 0 can be used for ETH too
|
||||
* @param _amount Amount of tokens/eth to convert
|
||||
*/
|
||||
function downvote(bytes32 _id, address _token, uint _amount) public payable {
|
||||
uint sntAmount = _tradeTokens(_token, _amount);
|
||||
discover.downvote(_id, sntAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Trades tokens/ETH to SNT using Kyber
|
||||
* @param _token Token to convert to SNT (see https://developer.kyber.network/docs/Environments-Intro/). Address 0 can be used for ETH too
|
||||
* @param _amount Amount of tokens/eth to convert
|
||||
* @return Amount of SNT received from the conversion
|
||||
*/
|
||||
function _tradeTokens(address _token, uint _amount) internal returns(uint sntAmount) {
|
||||
uint minConversionRate;
|
||||
uint slippageRate;
|
||||
uint slippagePercent;
|
||||
|
||||
ERC20Token sntToken = ERC20Token(SNT);
|
||||
|
||||
if (_token == address(0) || _token == ETH) {
|
||||
require(msg.value == _amount, "Not enough ETH");
|
||||
(minConversionRate, slippageRate) = getConversionRates(ETH, _amount);
|
||||
slippagePercent = 100 - ((slippageRate * 100) / minConversionRate);
|
||||
require(slippagePercent <= maxSlippage);
|
||||
sntAmount = kyberProxy.trade.value(_amount)(ETH, _amount, SNT, address(this), 0 - uint256(1), minConversionRate, walletId);
|
||||
} else {
|
||||
ERC20Token t = ERC20Token(_token);
|
||||
|
||||
// Initially transfer the tokens from the user to this contract
|
||||
require(t.transferFrom(msg.sender, address(this), _amount));
|
||||
|
||||
if (_token != SNT) {
|
||||
// Mitigate ERC20 Approve front-running attack, by initially setting allowance to 0
|
||||
require(t.approve(address(kyberProxy), 0), "Could not reset token approval");
|
||||
// Set the spender's token allowance to tokenQty
|
||||
require(t.approve(address(kyberProxy), _amount), "Could not approve token amount");
|
||||
|
||||
(minConversionRate, slippageRate) = getConversionRates(_token, _amount);
|
||||
slippagePercent = 100 - ((slippageRate * 100) / minConversionRate);
|
||||
require(slippagePercent <= maxSlippage);
|
||||
|
||||
sntAmount = kyberProxy.trade(_token, _amount, SNT, address(this), 0 - uint256(1), minConversionRate, walletId);
|
||||
} else {
|
||||
sntAmount = _amount;
|
||||
}
|
||||
}
|
||||
|
||||
require(sntAmount != 0, "Not enough SNT for vote");
|
||||
require(sntToken.approve(address(discover), 0), "Could not reset SNT approval");
|
||||
require(sntToken.approve(address(discover), sntAmount), "Could not approve SNT amount");
|
||||
}
|
||||
|
||||
event WalletIdChanged(address sender, address prevWalletId, address newWalletId);
|
||||
|
||||
/**
|
||||
* @dev Changes the walletId address (for the fee sharing program)
|
||||
* @param _walletId New walletId address
|
||||
*/
|
||||
function setWalletId(address _walletId) external onlyController {
|
||||
emit WalletIdChanged(msg.sender, walletId, _walletId);
|
||||
walletId = _walletId;
|
||||
}
|
||||
|
||||
event SlippageUpdated(uint maxSlippage);
|
||||
|
||||
/**
|
||||
* @param _maxSlippage most slippage as a percentage
|
||||
*/
|
||||
function setSlippage(uint _maxSlippage) public onlyController {
|
||||
require(_maxSlippage < 100);
|
||||
maxSlippage = _maxSlippage;
|
||||
emit SlippageUpdated(_maxSlippage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
pragma solidity >=0.5.0 <0.6.0;
|
||||
/**
|
||||
* @title KyberNetworkProxy
|
||||
* @dev Mock of the KyberNetworkProxy. Only used in development
|
||||
*/
|
||||
contract KyberNetworkProxy {
|
||||
|
||||
constructor() public {
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Get a mocked up rate for the trade
|
||||
*/
|
||||
function getExpectedRate(
|
||||
address /* src */,
|
||||
address /* dest */,
|
||||
uint /* srcQty */
|
||||
)
|
||||
public pure
|
||||
returns(uint expectedRate, uint slippageRate)
|
||||
{
|
||||
return (32749000000000000000, 31766530000000000000);
|
||||
}
|
||||
|
||||
/// @notice use token address ETH_TOKEN_ADDRESS for ether
|
||||
/// @dev makes a trade between src and dest token and send dest token to destAddress
|
||||
/// @param maxDestAmount A limit on the amount of dest tokens
|
||||
/// @return amount of actual dest tokens
|
||||
function trade(
|
||||
address /* src */,
|
||||
uint /* srcAmount */,
|
||||
address /* dest */,
|
||||
address /* destAddress */,
|
||||
uint maxDestAmount,
|
||||
uint /* minConversionRate */,
|
||||
address /* walletId */
|
||||
)
|
||||
public
|
||||
payable
|
||||
returns(uint)
|
||||
{
|
||||
return maxDestAmount;
|
||||
}
|
||||
|
||||
/// @dev makes a trade between src and dest token and send dest tokens to msg sender
|
||||
/// @return amount of actual dest tokens
|
||||
function swapTokenToToken(
|
||||
address /* src */,
|
||||
uint /* srcAmount */,
|
||||
address /* dest */,
|
||||
uint /* minConversionRate */
|
||||
)
|
||||
public pure
|
||||
returns(uint)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
/// @dev makes a trade from Ether to token. Sends token to msg sender
|
||||
/// @return amount of actual dest tokens
|
||||
function swapEtherToToken(
|
||||
address /* token */,
|
||||
uint /* minConversionRate */
|
||||
) public payable returns(uint) {
|
||||
return 200;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue