Giter VIP home page Giter VIP logo

smart-contracts's Introduction

Introduction

This repository contains kyber network smart contracts. For more details, please visit our developer portal

API

Public facing interfaces for kyber network (folder: contracts/sol6):

  1. IKyberNetworkProxy.sol - Get rate and trade APIs. Hint handler address.
  2. ISimpleKyberProxy.sol - Simple trade functions.
  3. IKyberHintHandler.sol - Build hints for advanced trade functionality.
  4. IKyberDao - Interact with KyberDao.
  5. Dao/IKyberStaking - interact with KyberStaking.

Setup

  1. Clone this repo
  2. npm ci

Compilation with Buidler

  1. ./cmp.sh to compile contracts for all solidity versions.
  2. ./cmpSol6.sh to compile only sol6 contracts

Testing with Buidler

  1. If contracts have not been compiled, run ./cmp.sh. This step can be skipped subsequently.
  2. Run ./tst.sh
  3. Use -f for running a specific test file.
  4. Use -a to run tests for all solidity versions. Runs only sol6 tests by default.

Example Commands

./tst.sh (Run only sol6 tests) ./tst.sh -f ./test/sol4/kyberReserve.js (Test only kyberReserve.js) ./tst.sh -a (Run sol4, sol5, sol6 tests)

Example

npx buidler test --no-compile ./test/sol6/kyberNetwork.js

Coverage with buidler-coverage

  1. Run ./coverage.sh
  2. Use -f for running a specific test file.

Example Commands

./coverage.sh -f ./test/sol6/kyberNetwork.js (Coverage for only kyberNetwork.js)

smart-contracts's People

Contributors

amitkot avatar anyhowclick avatar ayobuenavista avatar dependabot[bot] avatar dmdque avatar ducquangkstn avatar ductm54 avatar ilandoron avatar loiluu avatar manhlx3006 avatar namnm1991 avatar talbaneth avatar thevrintern avatar tranvictor avatar xcrux avatar yaronvel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

smart-contracts's Issues

Record per reserve volume over period of time

Record a sliding window of volume per token.
Implement sliding window that requires only a single storage update (at the cost of an assumption of the max size of the sliding window).

In the same storage update we also store data on the volume and prices since the beginning of time.

'TransferAdminPending' event is passed with 2 different variables.

Hi, when I read "PermissionGroups.sol", I saw that you defined an event and 2 transfer functions as following:

event TransferAdminPending(address pendingAddress);  
function transferAdmin(address newAdmin) public onlyAdmin
function transferAdminQuickly(address newAdmin) public onlyAdmin

In "transferAdmin" function, you called that event with "pendingAdmin" param, which is address(0). But in "transferAdminQuickly" function, you again called that event with "newAdmin" param.

Please explain why you call that event with 2 different variables. Thanks.

main net deployment script

Main net deployment

Deployment stages

Deploy all contracts - script per contract.
Update operators and alerters for all contracts
Add tokens to rates. Set token params for volume imbalance recorder.
List tokens for network
withdrawl addresses.
Whitelist addresses with cap
Connect contracts

Manual stage

Write down “manual” part
Take ownership with admin
Add tokens to reserve
Set rates - for local local system
Set step functions

input json

Alerters + operators + next admin per contract
Token addresses (mainnet)
Per token
Min resolution, max per block, max total
Withdrawl addresses per token - array per token
White list - list of addresses per category.
Exchanges - adresss per token
Burn fee - 25
Burn wallet address
Sanity price: optional
Saved addresses of contracts
Valid block period

Output json

Similar to currect output - leave out exchang addresses

kyber reserve tests

init tokens - 5

init required contracts.
set all addresses for permissions.

per token set
imbalance values
base price + compact data price. buy and sell.
step functions per QTY and imbalance.

start trading
add trades while executing step functions and comparing prices and imbalances.

Bad Instruction in Smart Contract, Losing 0.26 ETH on Ropsten

I have just tried to exchange 0.26 ETH for 20 OMG on Ropsten using Metamask, but have lost my funds. I feel this could be pretty significant just before the mainnet launch.

Steps:

Result

If possible I'd like this to be considered in the bug bounty program.

It's returned 405 when I send method trade

@yaronvel

It's returned 405 when I send method trade, could you help me?

const eos = '0xd3c64BbA75859Eb808ACE6F2A6048ecdb2d70817'; const eth = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; const web3 = new Web3('https://ropsten.infura.io/DtzEYY0Km2BA3YwyJcBG'); // ... contract.methods.trade( eos, new BigNumber(0.001 * Math.pow(10, 18)), eth, web3.eth.defaultAccount, new BigNumber(2).pow(255), 1, 0 ).send({ from: web3.eth.defaultAccount, value: new BigNumber(0.001 * Math.pow(10, 18)) }, function(result) { console.info('Send result: ') console.info(result) }).then(function(send) { console.info('Trade: ') console.info(send); });

How to transfer tokens to ETH by wallet?

I want to develop a wallet APP whitch support this contract to transfer tokens to eth. How can I immplement it and how to support tokens?, can you give me some suggest?
Use web3? Or others?

I can transfer eth to tokens by metamask right now.

Thanks!

deployment script - move to await

use truffle exec or migration
stages:

  1. deploy tokens
  2. mock exchange + mock central bank
  3. reserve, kyberNetwork,
  4. whitelist, cap 10 ether for standard.
  5. getExpectedPrice
    6 update addresses. for all contracts.
    a victor operator - for reserve.
    b ilan - admin - for all contracts.
    c alerter - all people in the reserve.

after deployment execute single trade.

Gas Limit attack on removeAlerter and removeOperator

The functions removeOperator and removeAlerter of the PermissionGroups.sol contract are subject to a Gas Limit attack.

Every action of a smart contract consumes gas. In case gas runs out, the contract will stop processing the transaction and the transaction will fail.

Both functions attempt to loop over the operatorsGroup and alertersGroup respectively without having a way to control the max number of iterations.

In case those arrays are very large the for loop will consume all the gas and the transaction will fail.

Currently, there is no limit on the number of operators or alerters that can be added to the contract.

The impact of this issue is that in case a very big number of alerters or operators are added to the relevant arrays, the functions removeOperator or removeAlerter will become dysfunctional, being able to remove only alerters or operators being at the beginning of the operatorsGroup and alertersGroup arrays or at least before the transaction runs out of gas.

As a solution to this issue, the introduction of a limit to the number of operators or alerters is advised.

Vulnerable snippet

    for (uint i = 0; i < operatorsGroup.length; ++i) {
       if (operatorsGroup[i] == operator) {
                operatorsGroup[i] = operatorsGroup[operatorsGroup.length - 1];
                operatorsGroup.length -= 1;
                OperatorAdded(operator, false);
                break;
            }
        }

        for (uint i = 0; i < alertersGroup.length; ++i) {
            if (alertersGroup[i] == alerter) {
                alertersGroup[i] = alertersGroup[alertersGroup.length - 1];
                alertersGroup.length--;
                AlerterAdded(alerter, false);
                break;
            }
        }

I want to trade 1eth to eos by contract but got 0eth in my wallet.

contract.at(contractAddress).then(function(instance) { instance.trade( '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', new BigNumber(1 * Math.pow(10, 18)), '0xcec7f0df01a3cc5f9d41f08f2655066b80a093f0', web3.eth.defaultAccount, new BigNumber(2).pow(255), 1, 0 ); });

Such as the code before, I want to trade 1eth to eos by contract , when this code running and open my metamask wallet, the amount is 0eth, but not 1eth, is the parameter error?

txID: 0x2fea57790d3e8204ab41e5e65b5006805659bd39faa880d30c7bfe6cb1c626ef
net: kovan test net
src: eth
desc: eos

Transaction Error. Exception thrown in contract code

Hi, @yaronvel

When I call trade method with metamask wallet, metamask told me "Transaction Error. Exception thrown in contract code". But no more tips showed to me.

code:
let contract = TruffleContract({ abi: mainNetKyberAbi, }); contract.setProvider(web3.currentProvider); contract.at(mainNetKyberContractAddress).then(function(instance) { instance.getExpectedRate('0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', '0x86Fa049857E0209aa7D9e616F7eb3b3B78ECfdb0', 0).then(function(a, b) { instance.trade( '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', new BigNumber(1 * Math.pow(10, 18)), '0xcec7f0df01a3cc5f9d41f08f2655066b80a093f0', web3.eth.defaultAccount, new BigNumber(2).pow(255), new BigNumber(65559682300000), 0, { from: web3.eth.defaultAccount, value: new BigNumber(0.001 * Math.pow(10, 18)), } ).then(function(b) { console.info(b) }); }); });

txid:0x2c0ac368f5e9d5215f62fa6d877114479413cf5e89ff958f8da8702df5aa0f50

Permission base contract

Three levels of permissions:

  1. Admin - can give permissions to others. Only 1 admin.
  2. Operator - for example, set prices in reserve manager. Can have multiple operators.
  3. Alerter - for example, stop trade in token if he thinks something is wrong. Can have multiple alerter.

Requirements:

  1. Admin is transferable. With acceptOwnership function.
  2. Modifier for onlyAdmin, onlyOperator and onlyAlerter.
  3. getOperators and getAlerters functions. Implement with naive array.

Withdrawable base contract

Withdrawable inherent from permission.
Only admin can call it.
Should be able to withdraw both ether and token.
Something similar to this and this.

Prevent Price Manipulation

How about using a threshold variable that is set by a each Reserve? It would be transparent to all the contributors and they would only contribute on agreement. During SetRate, if the new rate is lower than the old rate multiplied by the threshold variable (0 < thresholdVariable < 1), it results in failure or can call DynamicPriceCheck function which refers to other Reserves for price. This function can be designed like:

      uint matchingBalance = 0;       
      for( uint i = 0 ; i < numReserves ; i++ ) {
        var (rate,expBlock,balance) = reserves[i].getPairInfo(source,dest); 
        /// isClose is a math function that checks if the rates are close to each other       
        if( (expBlock >= block.number) && (balance > 0) && (isClose(rate, newRate) ) ) {
             matchingBalance +=  balance;
        }
      }
      if( ! reserveBalance <= matchingBalance ) { return false; }

Why DynamicPriceCheck Works

matchingBalance is basically the total balance of the given pair in all reserves whose rate is similar to the newRate the ReserveManager is trying to set. It basically checks if matchingBalance is higher the balance of the ReserveManager's Reserve which means that there are other Reserves greater of equal in combined value who have already set a similar rate.

In a very unlikely scenario, It is still possible to manipulate if the ReserveManager sets up another decoy Reserve with balance greater than the original Reserve and sets an unreasonable rate for it before setting rate for the original one. With a high gas price, the ReserveManager can probably peform all three transactions (Setting rate of two reserve and purchase of the assets himself) before someone else capitalises on the unreasonably low exchange rate. This is obviously impractical for high volume exchange pairs but still a valid concern for the low volume ones. So, further enhancements are required.

If the Reserve Manager is the first to set rate after a legitimate drastic rate drop, this wouldn't work and other mechanisms should be used. But it would avoid all smaller reserves having the same pair having to go through the same cumbersome mechanism.

coverage tests

add tests for new code:

volume imbalance recorder

(over flow checks)

converstionRates

new getters

Upgradable white list contract

  1. Have the interface maxTradeSize( ERC20 inputToken, address user) view returns(uint).
  2. KyberNetwork contract has a pointer to white list contract. Pointer is controlled by admin.
  3. Implement white list contract.

Kyber network fees

  1. configurable (by admin) fees in KyberNetwork contract:
    a. per reserve
    b. per wallet provider.
    c. total_fees = tx_size * per_reserve_%, wallet get wallet_fees = total_fees * per_wallet_%. The rest, total_fees - wallet_fees is burned.

  2. configurable ETH to KNC rate in kyberNetwork (by operator)

  3. In KyberReserve contract in trade function:
    a. burn fees
    b. send fees to wallet.

open questions:

  1. where reserve get fee amount and wallet address.
  2. who actually send it to the wallet
  3. how exactly different reserve fee incorporate with different wallet fee?

Get money from reserve and send to user

  1. KyberNetwork approves infinite amount of tokens to all reserves. - add to list reserve.
  2. KyberNetwork holds 1 twei from every token type (to avoid new storage changes).

Flow (ETH=>TOKEN):

  1. user send to kyber network.
  2. kyber network call reserve trade
  3. reserve trade transfer (without approve and transferFrom scheme) token to kyber network.
  4. kyber network send tokens to user.

Flow (TOKEN=>ETH):

  1. user approves token to kyber network.
  2. user calls kyber network trade
  3. kyber network calls transferFrom user to kyber network.
  4. reserve calls transfer from (already has infinite allowence).
  5. reserve sends ether to kyber network
  6. kyber network sends ether to user.

step function volume weighted rates

A user gets the step-adjusted rate determined by y
y is determined by x.
If the first non=0 step starts at x:
user for quantity (x-1) takes base rate
user for quantity(x) takes step-adjusted base rate
If would be better in the above example the step-adjusted base rate used quantity as weight
((base*(x-1)) + (step-adjusted-base*1))/(x)

Predefined withdrawal addresses for reserve

Admin can set addresses to which operator can move tokens and ether.
A mapping between token type and address to boolean + description string.
Conceptually exchange deposit addresses per token.

Store all of them in an array.

enable query of wallets getting fees - from fee burner

currently wallets we give fees to are saved with a mapping
mapping(address=>uint) public walletFeesInBps;
so for keeping track. only events will work.

better add an array of all wallet addresses.
will enable to query which wallets get fees and what is the fee.

trade return 0x

When I call trade method, it's return error message as response below

HTML:
<body> <script type="text/javascript" src="js/bignumber.js" ></script> <script src="js/web3.js"></script> <script src="json/abi.js"></script> <script src="test/web3Mainnet.js"></script> </body>

Request:

let web3 = new Web3('wss://mainnet.infura.io/ws'); let privateKey = '*****************'; web3.eth.defaultAccount = web3.eth.accounts.privateKeyToAccount(privateKey).address; let contract = new web3.eth.Contract(mainNetKyberAbi, mainNetKyberContractAddress); contract.methods.trade( '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', web3.eth.abi.encodeParameter('uint', new BigNumber(1 * Math.pow(10, 18))), '0xcec7f0df01a3cc5f9d41f08f2655066b80a093f0', web3.eth.defaultAccount, web3.eth.abi.encodeParameter('uint', new BigNumber(2).pow(255)), 1, 0).call();

Response:
{"jsonrpc":"2.0","id":1,"result":"0x"}

However, it's worked on metamask with the code below:

let contract = TruffleContract({ abi:mainNetKyberAbi, }); contract.setProvider(web3.currentProvider); contract.at(mainNetKyberContractAddress).then(function(instance) { let b = instance.trade( '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', new BigNumber(1 * Math.pow(10, 18)), '0xcec7f0df01a3cc5f9d41f08f2655066b80a093f0', web3.eth.defaultAccount, new BigNumber(2).pow(255), 1, 0 ); console.info(b) });

tests

Test basic contracts first
expectedRate.
FeeBurner
Whitelist.
volume imbalance recorder

Determine best reserve for the trade

  1. Chose only 1 reserve.
  2. If price is similar decide randomly according to sha3(timestamp).
  3. Implement similar price mechanism.
    a. configurable epsilon - changes smaller than epsilon are negligable
    b. go over all reserves and find cheapest price, and store it on array.
    c. find all reserves with eplison from cheapest and store in an array
    d. pick a reserve at random.

Tier pricing support in reserve

Per volume and qty pricing.

Price will depend only qty and recent volume.
Recent volume is a per token sliding window.

Reserve manager updates prices in two modes

Frequent update

The frequent update updates the base price, which is the price for the lowest qty.
This might be updated, e.g., once a minute.

Less frequent update of step function

A step function says how much to increase the price per qty unit.
This function might be changed only once a day or even less.
It is likely that initially it will be very naive function.

step function able to simulate curve or being linear

For now y values at steps are fixed within the step range.
The ability to set a y range within the step which would be either determined linearly or by a quadratic depending on the x value of the step would make the steps be more granular.

Propper documentation?

Can you show a clear example on how to do the trade? I want to integrate Kyber into SocialX but it seems I'm having difficulties doing a simple trade.

README is inaccurate. No getRate function

The README is inaccurate. There is no getRate function anymore. This may be a remnant of old code. There is getExpectedRate and findBestRate in KyberNetwork contract. ConversionRates contract has a getRate.

remaining tests in conversionRate

permissions
each function allowed only by permission.

imbalance values.
work with negative values.

set compact data togather with base price and make sure its working...

add contract for define values

name: KyberConstants
all contracts who use this constants will inherit
includes:
ETH_TOKEN_ADDRESS
CONVERSION_RATE_PRECISION

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.