Contract Source Code:
File 1 of 1 : Ethex
pragma solidity ^0.4.11;
contract SafeMath {
function safeMul(uint a, uint b) internal returns (uint) {
uint c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function safeSub(uint a, uint b) internal returns (uint) {
assert(b <= a);
return a - b;
}
function safeAdd(uint a, uint b) internal returns (uint) {
uint c = a + b;
assert(c>=a && c>=b);
return c;
}
function assert(bool assertion) internal {
if (!assertion) throw;
}
}
contract Token {
// these functions aren't abstract since the compiler emits automatically generated getter functions as external
function name() public constant returns (string name) { name; }
function symbol() public constant returns (string symbol) { symbol; }
function decimals() public constant returns (uint8 decimals) { decimals; }
function totalSupply() public constant returns (uint256 totalSupply) { totalSupply; }
function balanceOf(address _owner) public constant returns (uint256 balance) { _owner; balance; }
function allowance(address _owner, address _spender) public constant returns (uint256 remaining) { _owner; _spender; remaining; }
function transfer(address _to, uint256 _value) public returns (bool success);
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
function approve(address _spender, uint256 _value) public returns (bool success);
}
contract Ethex is SafeMath {
address public admin; //the admin address
address public feeAccount; //the account that will receive fees
uint public sellFee; //percentage times (1 ether)
uint public buyFee; //percentage times (1 ether)
mapping (bytes32 => uint) public sellOrders; //a hash of available orders holds a number of tokens
mapping (bytes32 => uint) public buyOrders; //a hash of available orders. holds a number of eth
event BuyOrder(bytes32 order, address token, uint amount, uint price, address buyer);
event SellOrder(bytes32 order,address token, uint amount, uint price, address seller);
event CancelBuyOrder(bytes32 order, address token, uint price, address buyer);
event CancelSellOrder(bytes32 order, address token, uint price, address seller);
event Buy(bytes32 order, address token, uint amount, uint price, address buyer, address seller);
event Sell(bytes32 order, address token, uint amount, uint price, address buyer, address seller);
function Ethex(address admin_, address feeAccount_, uint buyFee_, uint sellFee_) {
admin = admin_;
feeAccount = feeAccount_;
buyFee = buyFee_;
sellFee = sellFee_;
}
function() {
throw;
}
function changeAdmin(address admin_) {
if (msg.sender != admin) throw;
admin = admin_;
}
function changeFeeAccount(address feeAccount_) {
if (msg.sender != admin) throw;
feeAccount = feeAccount_;
}
function changeBuyFee(uint buyFee_) {
if (msg.sender != admin) throw;
if (buyFee_ > buyFee) throw;
buyFee = buyFee_;
}
function changeSellFee(uint sellFee_) {
if (msg.sender != admin) throw;
if (sellFee_ > sellFee)
sellFee = sellFee_;
}
function sellOrder(address token, uint tokenAmount, uint price) {
bytes32 h = sha256(token, price, msg.sender);
sellOrders[h] = safeAdd(sellOrders[h],tokenAmount);
SellOrder(h, token, tokenAmount, price, msg.sender);
}
function buyOrder(address token, uint tokenAmount, uint price) payable {
bytes32 h = sha256(token, price, msg.sender);
uint totalCost = tokenAmount*price;
if (totalCost < msg.value) throw;
buyOrders[h] = safeAdd(buyOrders[h],msg.value);
BuyOrder(h, token, tokenAmount, price, msg.sender);
}
function cancelSellOrder(address token, uint price) {
bytes32 h = sha256(token, price, msg.sender);
delete sellOrders[h];
CancelSellOrder(h,token,price,msg.sender);
}
function cancelBuyOrder(address token, uint price) {
bytes32 h = sha256(token, price, msg.sender);
uint remain = buyOrders[h];
delete buyOrders[h];
if (!msg.sender.call.value(remain)()) throw;
CancelBuyOrder(h,token,price,msg.sender);
}
function totalBuyPrice(uint amount, uint price) public constant returns (uint) {
uint totalPriceNoFee = safeMul(amount, price);
uint totalFee = safeMul(totalPriceNoFee, buyFee) / (1 ether);
uint totalPrice = safeAdd(totalPriceNoFee,totalFee);
return totalPrice;
}
function takeBuy(address token, uint amount, uint price, address buyer) payable {
bytes32 h = sha256(token, price, buyer);
uint totalPriceNoFee = safeMul(amount, price);
uint totalFee = safeMul(totalPriceNoFee, buyFee) / (1 ether);
uint totalPrice = safeAdd(totalPriceNoFee,totalFee);
if (buyOrders[h] < amount) throw;
if (totalPrice > msg.value) throw;
if (Token(token).allowance(msg.sender,this) < amount) throw;
if (Token(token).transferFrom(msg.sender,buyer,amount)) throw;
buyOrders[h] = safeSub(buyOrders[h], amount);
if (!feeAccount.send(totalFee)) throw;
uint leftOver = msg.value - totalPrice;
if (leftOver>0)
if (!msg.sender.send(leftOver)) throw;
Buy(h, token, amount, totalPrice, buyer, msg.sender);
}
function totalSellPrice(uint amount, uint price) public constant returns (uint) {
uint totalPriceNoFee = safeMul(amount, price);
uint totalFee = safeMul(totalPriceNoFee, buyFee) / (1 ether);
uint totalPrice = safeSub(totalPriceNoFee,totalFee);
return totalPrice;
}
function takeSell(address token, uint amount,uint price, address seller) payable {
bytes32 h = sha256(token, price, seller);
uint totalPriceNoFee = safeMul(amount, price);
uint totalFee = safeMul(totalPriceNoFee, buyFee) / (1 ether);
uint totalPrice = safeSub(totalPriceNoFee,totalFee);
if (sellOrders[h] < amount) throw;
if (Token(token).allowance(seller,this) < amount) throw;
if (!Token(token).transferFrom(seller,msg.sender,amount)) throw;
sellOrders[h] = safeSub(sellOrders[h],amount);
if (!seller.send(totalPrice)) throw;
if (!feeAccount.send(totalFee)) throw;
Sell(h, token, amount, totalPrice, msg.sender, seller);
}
}