-
Notifications
You must be signed in to change notification settings - Fork 68
File split and removing solc warnings #12
Changes from all commits
4e494fa
b0e9609
d92f6e4
5d136e7
41d9239
6b8f429
e6e46e9
3f2684e
08068fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
## | ||
# Project-specific | ||
new_tokens.csv | ||
|
||
## | ||
# Pythonic | ||
|
||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
env/ | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
.hypothesis/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# celery beat schedule file | ||
celerybeat-schedule | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# dotenv | ||
.env | ||
|
||
# virtualenv | ||
.venv | ||
venv/ | ||
ENV/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ | ||
|
||
#misc | ||
.pydevproject | ||
.project |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,12 @@ | ||
pragma solidity ^0.4.20; | ||
pragma solidity ^0.4.21; | ||
|
||
contract SafeMath { | ||
function safeMul(uint a, uint b) pure internal returns (uint) { | ||
uint c = a * b; | ||
assert(a == 0 || c / a == b); | ||
return c; | ||
} | ||
|
||
function safeSub(uint a, uint b) pure internal returns (uint) { | ||
assert(b <= a); | ||
return a - b; | ||
} | ||
|
||
function safeAdd(uint a, uint b) pure internal returns (uint) { | ||
uint c = a + b; | ||
assert(c>=a && c>=b); | ||
return c; | ||
} | ||
} | ||
|
||
contract Token { | ||
/// @return total amount of tokens | ||
function totalSupply() public constant returns (uint256 supply) {} | ||
|
||
/// @param _owner The address from which the balance will be retrieved | ||
/// @return The balance | ||
function balanceOf(address _owner) public constant returns (uint256 balance) {} | ||
|
||
/// @notice send `_value` token to `_to` from `msg.sender` | ||
/// @param _to The address of the recipient | ||
/// @param _value The amount of token to be transferred | ||
/// @return Whether the transfer was successful or not | ||
function transfer(address _to, uint256 _value) public returns (bool success) {} | ||
|
||
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from` | ||
/// @param _from The address of the sender | ||
/// @param _to The address of the recipient | ||
/// @param _value The amount of token to be transferred | ||
/// @return Whether the transfer was successful or not | ||
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {} | ||
|
||
/// @notice `msg.sender` approves `_addr` to spend `_value` tokens | ||
/// @param _spender The address of the account able to transfer the tokens | ||
/// @param _value The amount of wei to be approved for transfer | ||
/// @return Whether the approval was successful or not | ||
function approve(address _spender, uint256 _value) public returns (bool success) {} | ||
import "./Token.sol"; | ||
import "./SafeMath.sol"; | ||
|
||
/// @param _owner The address of the account owning tokens | ||
/// @param _spender The address of the account able to transfer the tokens | ||
/// @return Amount of remaining tokens allowed to spent | ||
function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {} | ||
|
||
event Transfer(address indexed _from, address indexed _to, uint256 _value); | ||
event Approval(address indexed _owner, address indexed _spender, uint256 _value); | ||
|
||
uint public decimals; | ||
string public name; | ||
} | ||
contract ForkDelta { | ||
|
||
using SafeMath for uint; | ||
|
||
contract ForkDelta is SafeMath { | ||
address public admin; //the admin address | ||
address public feeAccount; //the account that will receive fees | ||
uint public feeMake; //percentage times (1 ether) | ||
|
@@ -75,7 +23,6 @@ contract ForkDelta is SafeMath { | |
event Deposit(address token, address user, uint amount, uint balance); | ||
event Withdraw(address token, address user, uint amount, uint balance); | ||
|
||
|
||
modifier isAdmin() { | ||
require(msg.sender == admin); | ||
_; | ||
|
@@ -117,15 +64,15 @@ contract ForkDelta is SafeMath { | |
} | ||
|
||
function deposit() public payable { | ||
tokens[0][msg.sender] = safeAdd(tokens[0][msg.sender], msg.value); | ||
Deposit(0, msg.sender, msg.value, tokens[0][msg.sender]); | ||
tokens[0][msg.sender] = tokens[0][msg.sender].add(msg.value); | ||
emit Deposit(0, msg.sender, msg.value, tokens[0][msg.sender]); | ||
} | ||
|
||
function withdraw(uint amount) public { | ||
require(tokens[0][msg.sender] >= amount); | ||
tokens[0][msg.sender] = safeSub(tokens[0][msg.sender], amount); | ||
require(msg.sender.call.value(amount)()); | ||
Withdraw(0, msg.sender, amount, tokens[0][msg.sender]); | ||
tokens[0][msg.sender] = tokens[0][msg.sender].sub(amount); | ||
msg.sender.transfer(amount); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did we remove the require here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously: require throws when function returns false, e.g. when not enough eth. You could also say that transfer is safer to use, because you don't have to check the result. Reason for the change: Safety against reentrancy as explained in: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Beautiful. |
||
emit Withdraw(0, msg.sender, amount, tokens[0][msg.sender]); | ||
} | ||
|
||
function depositToken(address token, uint amount) public { | ||
|
@@ -134,9 +81,9 @@ contract ForkDelta is SafeMath { | |
depositingTokenFlag = true; | ||
require(Token(token).transferFrom(msg.sender, this, amount)); | ||
depositingTokenFlag = false; | ||
tokens[token][msg.sender] = safeAdd(tokens[token][msg.sender], amount); | ||
Deposit(token, msg.sender, amount, tokens[token][msg.sender]); | ||
} | ||
tokens[token][msg.sender] = tokens[token][msg.sender].add(amount); | ||
emit Deposit(token, msg.sender, amount, tokens[token][msg.sender]); | ||
} | ||
|
||
// Support ERC223 Token.transfer() | ||
function tokenFallback( address sender, uint amount, bytes data) public returns (bool ok) { | ||
|
@@ -149,14 +96,13 @@ contract ForkDelta is SafeMath { | |
revert(); | ||
} | ||
} | ||
|
||
|
||
function withdrawToken(address token, uint amount) public { | ||
require(token!=0); | ||
require(tokens[token][msg.sender] >= amount); | ||
tokens[token][msg.sender] = safeSub(tokens[token][msg.sender], amount); | ||
tokens[token][msg.sender] = tokens[token][msg.sender].sub(amount); | ||
require(Token(token).transfer(msg.sender, amount)); | ||
Withdraw(token, msg.sender, amount, tokens[token][msg.sender]); | ||
emit Withdraw(token, msg.sender, amount, tokens[token][msg.sender]); | ||
} | ||
|
||
function balanceOf(address token, address user) public constant returns (uint) { | ||
|
@@ -166,7 +112,7 @@ contract ForkDelta is SafeMath { | |
function order(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce) public { | ||
bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce); | ||
orders[msg.sender][hash] = true; | ||
Order(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, msg.sender); | ||
emit Order(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, msg.sender); | ||
} | ||
|
||
function trade(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s, uint amount) public { | ||
|
@@ -175,48 +121,56 @@ contract ForkDelta is SafeMath { | |
require(( | ||
(orders[user][hash] || ecrecover(keccak256("\x19Ethereum Signed Message:\n32", hash),v,r,s) == user) && | ||
block.number <= expires && | ||
safeAdd(orderFills[user][hash], amount) <= amountGet | ||
orderFills[user][hash].add(amount) <= amountGet | ||
)); | ||
tradeBalances(tokenGet, amountGet, tokenGive, amountGive, user, amount); | ||
orderFills[user][hash] = safeAdd(orderFills[user][hash], amount); | ||
Trade(tokenGet, amount, tokenGive, amountGive * amount / amountGet, user, msg.sender); | ||
orderFills[user][hash] = orderFills[user][hash].add(amount); | ||
emit Trade(tokenGet, amount, tokenGive, amountGive.mul(amount).div(amountGet), user, msg.sender); | ||
} | ||
|
||
function tradeBalances(address tokenGet, uint amountGet, address tokenGive, uint amountGive, address user, uint amount) private { | ||
|
||
//trades are free until this date in UNIX timestamp | ||
uint feeMakeXfer = 0; | ||
uint feeTakeXfer = 0; | ||
if (now >= freeUntilDate) { | ||
feeMakeXfer = safeMul(amount, feeMake) / (1 ether); | ||
feeTakeXfer = safeMul(amount, feeTake) / (1 ether); | ||
feeMakeXfer = amount.mul(feeMake).div(1 ether); | ||
feeTakeXfer = amount.mul(feeTake).div(1 ether); | ||
} | ||
|
||
tokens[tokenGet][msg.sender] = safeSub(tokens[tokenGet][msg.sender], safeAdd(amount, feeTakeXfer)); | ||
tokens[tokenGet][user] = safeAdd(tokens[tokenGet][user], safeSub(amount, feeMakeXfer)); | ||
tokens[tokenGet][feeAccount] = safeAdd(tokens[tokenGet][feeAccount], safeAdd(feeMakeXfer, feeTakeXfer)); | ||
tokens[tokenGive][user] = safeSub(tokens[tokenGive][user], safeMul(amountGive, amount) / amountGet); | ||
tokens[tokenGive][msg.sender] = safeAdd(tokens[tokenGive][msg.sender], safeMul(amountGive, amount) / amountGet); | ||
tokens[tokenGet][msg.sender] = tokens[tokenGet][msg.sender].sub(amount.add(feeTakeXfer)); | ||
tokens[tokenGet][user] = tokens[tokenGet][user].add(amount.sub(feeMakeXfer)); | ||
tokens[tokenGet][feeAccount] = tokens[tokenGet][feeAccount].add(feeMakeXfer.add(feeTakeXfer)); | ||
tokens[tokenGive][user] = tokens[tokenGive][user].sub(amountGive.mul(amount).div(amountGet); | ||
tokens[tokenGive][msg.sender] = tokens[tokenGive][msg.sender].add(amountGive.mul(amount).div(amountGet)); | ||
} | ||
|
||
function testTrade(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s, uint amount, address sender) public constant returns(bool) { | ||
if (!( | ||
tokens[tokenGet][sender] >= amount && | ||
availableVolume(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, user, v, r, s) >= amount | ||
)) return false; | ||
return true; | ||
)) { | ||
return false; | ||
} else { | ||
return true; | ||
} | ||
} | ||
|
||
function availableVolume(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s) public constant returns(uint) { | ||
bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce); | ||
if (!( | ||
(orders[user][hash] || ecrecover(keccak256("\x19Ethereum Signed Message:\n32", hash),v,r,s) == user) && | ||
block.number <= expires | ||
)) return 0; | ||
uint available1 = safeSub(amountGet, orderFills[user][hash]); | ||
uint available2 = safeMul(tokens[tokenGive][user], amountGet) / amountGive; | ||
if (available1<available2) return available1; | ||
return available2; | ||
)) { | ||
return 0; | ||
} | ||
uint[2] memory available; | ||
available[0] = amountGet.sub(orderFills[user][hash]); | ||
available[1] = tokens[tokenGive][user].mul(amountGet).div(amountGive); | ||
if (available[0] < available[1]) { | ||
return available[0]; | ||
} else { | ||
return available[1]; | ||
} | ||
} | ||
|
||
function amountFilled(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s) public constant returns(uint) { | ||
|
@@ -228,6 +182,6 @@ contract ForkDelta is SafeMath { | |
bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce); | ||
require ((orders[msg.sender][hash] || ecrecover(keccak256("\x19Ethereum Signed Message:\n32", hash),v,r,s) == msg.sender)); | ||
orderFills[msg.sender][hash] = amountGet; | ||
Cancel(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, msg.sender, v, r, s); | ||
emit Cancel(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, msg.sender, v, r, s); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
pragma solidity ^0.4.21; | ||
|
||
/** | ||
* @title SafeMath | ||
* @dev Math operations with safety checks that throw on error | ||
*/ | ||
library SafeMath { | ||
|
||
/** | ||
* @dev Multiplies two numbers, throws on overflow. | ||
*/ | ||
function mul(uint256 a, uint256 b) internal pure returns (uint256) { | ||
if (a == 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the logic be if a == 0 OR b == 0 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SafeMath.sol is from https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol They kind of know what they are doing, at least much better than I do. Regarding your comment, no, for the check that follows it's only vital that a is not 0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, if either A or B is 0, the function will return 0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but if a is 0 the function would in fact throw an division by zero exception. In contrast to b = 0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess that's true. |
||
return 0; | ||
} | ||
uint256 c = a * b; | ||
require(c / a == b); | ||
return c; | ||
} | ||
|
||
/** | ||
* @dev Integer division of two numbers, truncating the quotient. | ||
*/ | ||
function div(uint256 a, uint256 b) internal pure returns (uint256) { | ||
require(b > 0); // Solidity automatically throws when dividing by 0 | ||
uint256 c = a / b; | ||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold | ||
return c; | ||
} | ||
|
||
/** | ||
* @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). | ||
*/ | ||
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | ||
require(b <= a); | ||
return a - b; | ||
} | ||
|
||
/** | ||
* @dev Adds two numbers, throws on overflow. | ||
*/ | ||
function add(uint256 a, uint256 b) internal pure returns (uint256) { | ||
uint256 c = a + b; | ||
require(c >= a); | ||
return c; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So much more syntactically pleasing. Good addition.