GithubHelp home page GithubHelp logo

raiden-network / raiden-token Goto Github PK

View Code? Open in Web Editor NEW
45.0 45.0 31.0 467 KB

Raiden Token and Issuance Contracts

License: BSD 3-Clause "New" or "Revised" License

Python 74.50% HTML 0.05% JavaScript 25.19% CSS 0.26%

raiden-token's People

Contributors

andrevmatos avatar czepluch avatar heikoheiko avatar lefterisjp avatar loredanacirstea avatar pcppcp avatar pepae avatar ulope 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

Watchers

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

raiden-token's Issues

Support graceful batch claiming

We might run into a coordination problem with claimTokens as anyone can call it. Currently the batch fails if one of the addresses claimed the tokens in between.

Suggestion: return false, if tokens for an address have been claimed already, so that the script can continue to run.

require(bids[receiver_address] > 0);

Post-claimTokens orphan tokens (rounding errors)

After all bidders have claimed their tokens, there might be some unclaimed tokens due to rounding errors.
Current tests confirm this. The auction runs as intended, but these tokens remain assigned to the auction address.

Should we assign them to the owner after the last claimTokens is called?

Use gas cost estimation for claiming tokens automatically

Instead of giving a --claims argument, calculate the number from the gas cost estimation.

Know gas cost for:

  • standard claim
  • transferReserve claim

Ex:
claimTokens - approx. 30K. so this would mean, that we can claim approx. 100 accounts per call. if there are 10k participants, we need to trigger ~100 transactions.

Move the transfer of preallocated addresses after the sale is over

At the moment we transfer tokens to preallocated addressses from the very deployment of the token contract.

This is rather bad and can shine a very negative light on us. If we are to go with any preallocated addresses their balances should be kept in an array/mapping and transfers should happen only at the end of the token auction. All people should get their tokens at the same time.

Fix Distributor script

Tokens are not transferred to the bidders, even though the rest of the logic is performed (calculations, events) and the transaction does not fail.

Check Gas Cost

  • gas_used for a standard bid, as well as for a finalizeBid
  • gas_cost for a standard claim as well as for a transferReserve claim

Implement funding_target

There is an ETH funding target

  • min(this.value, funding_target) is sent (or can be claimed) by owner of the auction
  • the excess funds max(0, this.value-funding_target) are used to create the reserve of the token

Q:

  1. "seigniorage credited to the xxxxx account" - is this handled in the preallocation, as a fixed number of tokens and an address?
  2. Token and Auction - do they still have the same owner a.k.a. msg.sender?

How I see this:

We have a fixed initial_supply of tokens. We keep preallocations of tokens.
Auction has a funding_target of ETH.

Auction ends -> tokens are claimed / distributed using an external contract ->
-> transferFundingToOwner(min(this.balance, funding_target))
-> transferReserveToToken(excess funds)

# constructors are:

ReserveToken(
	address auction, 
	uint initial_supply, 
	address[] owners, // prealocations
	uint[] tokens)

DutchAuction(
	uint _price_factor,
        uint _price_const,
	uint funding_target)

Change finalizeAuction

  • make finalizeAuction public and callable by the owner
  • reduce gas cost for last bid (not refunding, not calling finalizeAuction)
  • do not accept bids with msg.value > missing_funds
  • calculate final_price from balance and tokens_auctioned, not from the timestamp

Contracts issues @audit time

Auditor: Jordi Baylina

Unresolved

--

Proposed, but not implemented

  1. In general it is a good idea in the owner token to have a escape hatch function that allows an owner to remove Ether and other tokens from this contract in case of accident. The escape hatch is also good for the Auction contract.
    (cannot implement)

  2. In some cases, it’s useful to be able to stop the transfers. (Specially if a bug is fund). This may not be seen as good by the token holders because of the possible manipulations.
    One good solution is:

function pause() onlyOwner {
        if (pausingMechanismLocked) throw;
        paused = true;
    }

   function unpause() onlyOwner {
        if (pausingMechanismLocked) throw;
        paused = false;
    }

   function neverPauseAgain() onlyOwner {
        pausingMechanismLocked = true;
    }

This way, you can be able to pause it, and at some point just disable this functionality.
Again, this is optional and it depends of the usage of the token..

Resolved

  1. In general is much better idea to send the ETH to a multisig in each bid call. The contract holds always 0 ETH and if there is any problem, you are sure that no ETH is lost.
  • a regular account (owner) + multisig (for ETH).
  • If not, the owner has too much control

(fixed in #58)

  1. final_price = this.balance / (tokens_auctioned / multiplier);

    rewrite to: final_price = multiplier * this.balance / tokens_auctioned;

(fixed in #60)

  1. Mock class that inherits the testing class in DutchAuction, so we don't remove the code and find out it's a problem.

    /* TODO remove this after testing */

    (removed test code #75)

  2. Update comments to match code:

    // After the last tokens are claimed, we send the auction balance to the owner

(fixed in #68)

  1. Do not allow to transfer tokens to the same token contract:
    add:
    require(_to != address(this));
    (fixed in #69)

  2. Handleapprove race condition, as suggested in https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md#approve and implemented in https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol#L256
    (fixed #77)

  3. The standard does not say it, but it’s more logical (and more traceable in etherscan) that the Burn event be replaced by a Transferevent to 0x0
    (fixed: #73)

  4. There is one possible attack, from Raiden that consists in using the same collected Ether to buy the tokens and force the sale to finish before and have a higher price.
    There are two options for this:
    1.- Say you are not going to do it. (At the end of the day they have to trust you any way when the ETH is in the multisig and you can do whatever).
    2.- Use a very simple intermediate wallet that don’t allow to withdraw the ETH until the sale is over. (i.e. https://github.com/status-im/status-network-token/blob/master/contracts/ContributionWallet.sol)
    He recomends 1.
    (we go with 1)

  5. Do not buy tokens in the name of the token contract. Otherwise, transferring them in the claimTokens phase will be an issue.
    (fixed: #90)

To be discussed (internal):

  1. (LK) Use interface contract type for Token -> replace totalSupply with total_supply + function
    (will not modify at this point)

  2. (LC) Accounts with preallocated tokens can bid but cannot claim their tokens:

    assert(num == token.balanceOf(receiver));

    Should this be changed to assert(token.balanceOf(receiver) >= num); ? Fixed in #50

  3. (LC) Token.approve(address _spender, uint256 _value)

    function approve(address _spender, uint256 _value)

    Is something like require(this.balanceOf(msg.sender) >= _value) needed?
    However, we already check for this in transferFrom.

Prevent overflow for '-' in token constructor

Changes:

This is not enough:

assert(totalSupply == balances[auction_address] + prealloc_tokens);

Should be:

assert(balances[auction_address] > 0);
assert(balances[auction_address] < totalSupply);
assert(totalSupply == balances[auction_address] + prealloc_tokens);

Overflow happens when giving a totalSupply < sum(preallocations)
Example:

totalSupply = 500 * 10**18
preallocations = [ 500 * 10**18, 800 * 10**18]
balances[auction_address] = 115792089237316195423570985008687907853269984665640564036957584007913129639936

Align with EIP 20: ERC-20 Token Standard

https://github.com/ethereum/EIPs/blob/f90864a3d2b2b45c4decf95efd26b3f0c276051a/EIPS/eip-20-token-standard.md

Possible changes needed:

To think about:

Multisig contract as ETH keeper

In general is much better idea to send the ETH to a multisig in each bid call. The contract holds always 0 ETH and if there is any problem, you are sure that no ETH is lost.

  • a regular account (owner)
  • multisig (for ETH).

As mentioned in audit advices #39

All bid ETH will be sent to this contract. So no ETH will be lost / frozen in the auction contract if something goes wrong.

  • keep received_ether updated in auction contract

Auction simulation script

Script for simulating an auction with multiple bidders and bids;

  • input: no_of_bidders, no_of_bids, auction params, token params (cli)

Distributor

  1. The Distributed event is not necessary and expensive.
  2. Should be callable by anyone, not owner only.
  3. What is the gas cost for one call from distribute to claimTokens? Assumption, roughly 20k gas. If so, tokens for approx. 300+ addresses can be claimed per block. Therefore consider to remove the uint8 limit from the address.length iterator.

Contract changes

  • no more reserve: replace with "funds"
  • transfer auction balance to the owner
  • remove terms&conditions signing
  • add fallback function -> call bid or throw if stage is not ok
  • last auction bid - do not refund anymore, only accept an amount <= missing_funds

Add contract for calling claimTokens

Automated way of claiming tokens for bidders after auction ends.
The contract will can be called with a list of addresses through which it will loop and call claimTokens(address).

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.