raiden-network / raiden-token Goto Github PK
View Code? Open in Web Editor NEWRaiden Token and Issuance Contracts
License: BSD 3-Clause "New" or "Revised" License
Raiden Token and Issuance Contracts
License: BSD 3-Clause "New" or "Revised" License
Replace
raiden-token/contracts/token.sol
Line 132 in 17d7b26
require(allowed[_from][msg.sender] >= _value);
and
raiden-token/contracts/token.sol
Line 137 in 17d7b26
allowed[_from][msg.sender] -= _value;
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.
raiden-token/contracts/auction.sol
Line 264 in 4336502
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?
expand and then reduce
raiden-token/contracts/auction.sol
Line 204 in 115fb3d
final_price = multiplier * this.balance / tokens_auctioned;
#39 (reviwer advice)
raiden-token/contracts/auction.sol
Line 308 in 4a17d89
to:
assert(token.balanceOf(receiver) >= num);
Mint tests fail for calculating sale cost and number of tokens issuable for a certain value.
raiden-token/tests/test_mint.py
Line 62 in cb9db3e
raiden-token/tests/test_mint.py
Line 63 in cb9db3e
Have a separate contract class with the test code from claimTokens
:
raiden-token/contracts/auction.sol
Line 262 in 32d5f3a
Support for tokenFallback
: ethereum/EIPs#223
Do not allow to transfer tokens to the same token contract:
add:
require(_to != address(this));
Auditor recommendation (#39)
External script to watch and sample events
logs.json
Instead of giving a --claims
argument, calculate the number from the gas cost estimation.
Know gas cost for:
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.
raiden-token/contracts/auction.sol
Line 275 in 32d5f3a
See how the WebUI holds up.
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
Suggested in the audit #39
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.
We want to see these events in Etherscan, so we will also add a Transfer
event to 0x0
.
As per auditor's recommendations #39.
Tokens are not transferred to the bidders, even though the rest of the logic is performed (calculations, events) and the transaction does not fail.
There is an ETH funding target
Q:
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)
finalizeAuction
public and callable by the ownerfinalizeAuction
)msg.value > missing_funds
final_price
from balance
and tokens_auctioned
, not from the timestamp--
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)
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..
(fixed in #58)
raiden-token/contracts/auction.sol
Line 204 in 115fb3d
final_price = multiplier * this.balance / tokens_auctioned;
(fixed in #60)
Mock class that inherits the testing class in DutchAuction, so we don't remove the code and find out it's a problem.
raiden-token/contracts/auction.sol
Line 262 in 32d5f3a
Update comments to match code:
raiden-token/contracts/auction.sol
Line 275 in 32d5f3a
(fixed in #68)
Do not allow to transfer tokens to the same token contract:
add:
require(_to != address(this));
(fixed in #69)
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)
The standard does not say it, but it’s more logical (and more traceable in etherscan) that the Burn
event be replaced by a Transfer
event to 0x0
(fixed: #73)
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)
Do not buy tokens in the name of the token contract. Otherwise, transferring them in the claimTokens phase will be an issue.
(fixed: #90)
(LK) Use interface
contract type for Token
-> replace totalSupply
with total_supply
+ function
(will not modify at this point)
(LC) Accounts with preallocated tokens can bid but cannot claim their tokens:
raiden-token/contracts/auction.sol
Line 308 in 115fb3d
assert(token.balanceOf(receiver) >= num);
? Fixed in #50
(LC) Token.approve(address _spender, uint256 _value)
raiden-token/contracts/token.sol
Line 149 in 115fb3d
require(this.balanceOf(msg.sender) >= _value)
needed?transferFrom
.
Changes:
This is not enough:
raiden-token/contracts/token.sol
Line 265 in 17d7b26
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
Possible changes needed:
raiden-token/contracts/token.sol
Line 79 in 01869c2
raiden-token/contracts/auction.sol
Line 282 in 01869c2
assert(token.transfer(receiver, num))
To think about:
raiden-token/contracts/token.sol
Line 211 in 01869c2
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.
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.
received_ether
updated in auction contractRemove check:
raiden-token/contracts/auction.sol
Line 146 in 708de0f
Because we already have:
raiden-token/contracts/token.sol
Line 228 in ac8eb30
This check is put in place so we don't forget that the initial supply of tokens should be given in token fractions Tei = TKN * multiplier
and not in TKN
raiden-token/tests/test_token.py
Line 317 in f03a10c
The issue is (probably) that Transfer
is triggered from an internal transaction. ERC223 transfer
calls the ERC20 transfer
.
When the bidder sends more than the auction needs in order to finalize, the bidder should receive the difference back. We don't have a test for this currently.
raiden-token/tests/test_auction.py
Line 72 in cb9db3e
Easy deployment script for testnets.
We added an auction fallback function, calling bid(msg.sender)
. Check if this can be used safely to bid. Bidder sends a normal transaction with ETH to the auction contract. Fallback calls bid(msg.sender)
.
Test it.
Old price decay function had a very low decay rate and did not meet our expectations.
raiden-token/contracts/auction.sol
Line 308 in 4a17d89
This might be redundant. Transfer is handled in
raiden-token/contracts/auction.sol
Line 282 in 4a17d89
Token.transfer()
itself should take care of any overflows / transfer issues.Tokens might be sent by mistake to the contract address in other ERC20 token contracts.
Implement an escape hatch for releasing these tokens to their original owners in case this happens.
As per auditor's recommendations #39
raiden-token/contracts/auction.sol
Line 180 in 708de0f
Replace with require
Script for simulating an auction with multiple bidders and bids;
Distributed
event is not necessary and expensive.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.Add more tests to check calculations, handle rounding errors.
i.e. assert(blalance[x]== old_balance + v)
might trigger an sload if we don't use the optimizer ?
If there's an issue, check places where we use this pattern
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)
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.