Transaction Hash:
Block:
7504802 at Apr-05-2019 12:08:36 AM +UTC
Transaction Fee:
0.000433013333290032 ETH
$1.22
Gas Used:
48,714 Gas / 8.888888888 Gwei
Emitted Events:
35 |
Ethex.MakeBuyOrder( orderHash=196A9B3D5F150DFB30C9F50950C69A67C6BD1E86AFE46B63E379591CD88A0AE5, token=0xB8c77482...C631bDD52, tokenAmount=4500000000000000000, weiAmount=85500000000000000, buyer=[Sender] 0x343a3c7f789335c9ea60932d34be258f643678d9 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x343a3C7F...F643678d9 |
0.08795108661 Eth
Nonce: 92
|
0.002018073276709968 Eth
Nonce: 93
| 0.085933013333290032 | ||
0x5A0b54D5...D3E029c4c
Miner
| (Spark Pool) | 6,501.882025188607048526 Eth | 6,501.882458201940338558 Eth | 0.000433013333290032 | |
0xb746Aed4...F1A0a60ae | 0.153420986027658894 Eth | 0.238920986027658894 Eth | 0.0855 |
Execution Trace
ETH 0.0855
Ethex.makeBuyOrder( token=0xB8c77482e45F1F44dE1745F52C74426C631bDD52, tokenAmount=4500000000000000000 )
-
Null: 0x000...002.b8c77482( )
makeBuyOrder[Ethex (ln:208)]
feeFromTotalCost[Ethex (ln:212)]
safeMul[Ethex (ln:152)]
safeAdd[Ethex (ln:152)]
safeMul[Ethex (ln:155)]
safeAdd[Ethex (ln:155)]
safeAdd[Ethex (ln:157)]
safeSub[Ethex (ln:160)]
safeSub[Ethex (ln:213)]
sha256[Ethex (ln:214)]
safeAdd[Ethex (ln:217)]
MakeBuyOrder[Ethex (ln:220)]
pragma solidity ^0.4.19; contract SafeMath { function safeMul(uint256 a, uint256 b) internal returns (uint256) { uint c = a * b; assert(a == 0 || c / a == b); return c; } function safeSub(uint256 a, uint256 b) internal returns (uint256) { assert(b <= a); return a - b; } function safeAdd(uint256 a, uint256 b) internal returns (uint256) { uint c = a + b; assert(c >= a && c >= b); return c; } // function assert(bool assertion) internal { // if (!assertion) throw; // } } // ERC Token Standard #20 Interface // https://github.com/ethereum/EIPs/issues/20 contract ERC20Interface { // Get the total token supply function totalSupply() public constant returns (uint256 totalSupply); // Get the account balance of another account with address _owner function balanceOf(address _owner) public constant returns (uint256 balance); // Send _value amount of tokens to address _to function transfer(address _to, uint256 _value) public returns (bool success); // Send _value amount of tokens from address _from to address _to function transferFrom(address _from, address _to, uint256 _value) public returns (bool success); // Allow _spender to withdraw from your account, multiple times, up to the _value amount. // If this function is called again it overwrites the current allowance with _value. // this function is required for some DEX functionality function approve(address _spender, uint256 _value) public returns (bool success); // Returns the amount which _spender is still allowed to withdraw from _owner function allowance(address _owner, address _spender) public constant returns (uint256 remaining); // Triggered when tokens are transferred. event Transfer(address indexed _from, address indexed _to, uint256 _value); // Triggered whenever approve(address _spender, uint256 _value) is called. event Approval(address indexed _owner, address indexed _spender, uint256 _value); } contract Etx is ERC20Interface { uint256 public expirationBlock; function isActive(address _owner) public returns (bool activated); } contract Ethex is SafeMath { address public admin; //the admin address address public feeAccount; //the account that will receive fees address public etxAddress; uint256 public makeFee; //percentage times (1 ether) uint256 public takeFee; //percentage times (1 ether) uint256 public lastFreeBlock; mapping (bytes32 => uint256) public sellOrderBalances; //a hash of available order balances holds a number of tokens mapping (bytes32 => uint256) public buyOrderBalances; //a hash of available order balances. holds a number of eth event MakeBuyOrder(bytes32 orderHash, address indexed token, uint256 tokenAmount, uint256 weiAmount, address indexed buyer); event MakeSellOrder(bytes32 orderHash, address indexed token, uint256 tokenAmount, uint256 weiAmount, address indexed seller); event CancelBuyOrder(bytes32 orderHash, address indexed token, uint256 tokenAmount, uint256 weiAmount, address indexed buyer); event CancelSellOrder(bytes32 orderHash, address indexed token, uint256 tokenAmount, uint256 weiAmount, address indexed seller); event TakeBuyOrder(bytes32 orderHash, address indexed token, uint256 tokenAmount, uint256 weiAmount, uint256 totalTransactionTokens, address indexed buyer, address indexed seller); event TakeSellOrder(bytes32 orderHash, address indexed token, uint256 tokenAmount, uint256 weiAmount, uint256 totalTransactionWei, address indexed buyer, address indexed seller); function Ethex(address admin_, address feeAccount_, uint256 makeFee_, uint256 takeFee_, address etxAddress_, uint256 _lastFreeBlock) public { admin = admin_; feeAccount = feeAccount_; makeFee = makeFee_; takeFee = takeFee_; etxAddress = etxAddress_; lastFreeBlock = _lastFreeBlock; } function() public { revert(); } function changeAdmin(address admin_) public { require(msg.sender == admin); admin = admin_; } function changeETXAddress(address etxAddress_) public { require(msg.sender == admin); require(block.number > Etx(etxAddress).expirationBlock()); etxAddress = etxAddress_; } function changeLastFreeBlock(uint256 _lastFreeBlock) public { require(msg.sender == admin); require(_lastFreeBlock > block.number + 100); //announce at least 100 blocks ahead lastFreeBlock = _lastFreeBlock; } function changeFeeAccount(address feeAccount_) public { require(msg.sender == admin); feeAccount = feeAccount_; } function changeMakeFee(uint256 makeFee_) public { require(msg.sender == admin); require(makeFee_ < makeFee); makeFee = makeFee_; } function changeTakeFee(uint256 takeFee_) public { require(msg.sender == admin); require(takeFee_ < takeFee); takeFee = takeFee_; } function feeFromTotalCostForAccount(uint256 totalCost, uint256 feeAmount, address account) public constant returns (uint256) { if (Etx(etxAddress).isActive(account)) { // No fee for active addr. return 0; } if (block.number <= lastFreeBlock) { return 0; } return feeFromTotalCost(totalCost, feeAmount); } function feeFromTotalCost(uint256 totalCost, uint256 feeAmount) public constant returns (uint256) { uint256 cost = safeMul(totalCost, (1 ether)) / safeAdd((1 ether), feeAmount); // Calculate ceil(cost). uint256 remainder = safeMul(totalCost, (1 ether)) % safeAdd((1 ether), feeAmount); if (remainder != 0) { cost = safeAdd(cost, 1); } uint256 fee = safeSub(totalCost, cost); return fee; } function calculateFeeForAccount(uint256 cost, uint256 feeAmount, address account) public constant returns (uint256) { if (Etx(etxAddress).isActive(account)) { // No fee for vested addr. return 0; } if (block.number <= lastFreeBlock) { return 0; } return calculateFee(cost, feeAmount); } function calculateFee(uint256 cost, uint256 feeAmount) public constant returns (uint256) { uint256 fee = safeMul(cost, feeAmount) / (1 ether); return fee; } // Makes an offer to trade tokenAmount of ERC20 token, token, for weiAmount of wei. function makeSellOrder(address token, uint256 tokenAmount, uint256 weiAmount) public { require(tokenAmount != 0); require(weiAmount != 0); bytes32 h = sha256(token, tokenAmount, weiAmount, msg.sender); // Update balance. sellOrderBalances[h] = safeAdd(sellOrderBalances[h], tokenAmount); // Check allowance. -- Done after updating balance bc it makes a call to an untrusted contract. require(tokenAmount <= ERC20Interface(token).allowance(msg.sender, this)); // Grab the token. if (!ERC20Interface(token).transferFrom(msg.sender, this, tokenAmount)) { revert(); } MakeSellOrder(h, token, tokenAmount, weiAmount, msg.sender); } // Makes an offer to trade msg.value wei for tokenAmount of token (an ERC20 token). function makeBuyOrder(address token, uint256 tokenAmount) public payable { require(tokenAmount != 0); require(msg.value != 0); uint256 fee = feeFromTotalCost(msg.value, makeFee); uint256 valueNoFee = safeSub(msg.value, fee); bytes32 h = sha256(token, tokenAmount, valueNoFee, msg.sender); //put ether in the buyOrderBalances map buyOrderBalances[h] = safeAdd(buyOrderBalances[h], msg.value); // Notify all clients. MakeBuyOrder(h, token, tokenAmount, valueNoFee, msg.sender); } // Cancels all previous offers by msg.sender to trade tokenAmount of tokens for weiAmount of wei. function cancelAllSellOrders(address token, uint256 tokenAmount, uint256 weiAmount) public { bytes32 h = sha256(token, tokenAmount, weiAmount, msg.sender); uint256 remain = sellOrderBalances[h]; delete sellOrderBalances[h]; ERC20Interface(token).transfer(msg.sender, remain); CancelSellOrder(h, token, tokenAmount, weiAmount, msg.sender); } // Cancels any previous offers to trade weiAmount of wei for tokenAmount of tokens. Refunds the wei to sender. function cancelAllBuyOrders(address token, uint256 tokenAmount, uint256 weiAmount) public { bytes32 h = sha256(token, tokenAmount, weiAmount, msg.sender); uint256 remain = buyOrderBalances[h]; delete buyOrderBalances[h]; if (!msg.sender.send(remain)) { revert(); } CancelBuyOrder(h, token, tokenAmount, weiAmount, msg.sender); } // Take some (or all) of the ether (minus fees) in the buyOrderBalances hash in exchange for totalTokens tokens. function takeBuyOrder(address token, uint256 tokenAmount, uint256 weiAmount, uint256 totalTokens, address buyer) public { require(tokenAmount != 0); require(weiAmount != 0); require(totalTokens != 0); bytes32 h = sha256(token, tokenAmount, weiAmount, buyer); // How many wei for the amount of tokens being sold? uint256 transactionWeiAmountNoFee = safeMul(totalTokens, weiAmount) / tokenAmount; // Does the buyer (maker) have enough money in the contract? uint256 unvestedMakeFee = calculateFee(transactionWeiAmountNoFee, makeFee); uint256 totalTransactionWeiAmount = safeAdd(transactionWeiAmountNoFee, unvestedMakeFee); require(buyOrderBalances[h] >= totalTransactionWeiAmount); // Calculate the actual vested fees. uint256 currentTakeFee = calculateFeeForAccount(transactionWeiAmountNoFee, takeFee, msg.sender); uint256 currentMakeFee = calculateFeeForAccount(transactionWeiAmountNoFee, makeFee, buyer); // Proceed with transferring balances. // Update our internal accounting. buyOrderBalances[h] = safeSub(buyOrderBalances[h], totalTransactionWeiAmount); // Did the seller send enough tokens? -- This check is here bc it calls to an untrusted contract. require(ERC20Interface(token).allowance(msg.sender, this) >= totalTokens); // Send buyer their tokens and any fee refund. if (currentMakeFee < unvestedMakeFee) {// the buyer got a fee discount. Send the refund. uint256 refundAmount = safeSub(unvestedMakeFee, currentMakeFee); if (!buyer.send(refundAmount)) { revert(); } } if (!ERC20Interface(token).transferFrom(msg.sender, buyer, totalTokens)) { revert(); } // Grab our fee. if (safeAdd(currentTakeFee, currentMakeFee) > 0) { if (!feeAccount.send(safeAdd(currentTakeFee, currentMakeFee))) { revert(); } } // Send seller the proceeds. if (!msg.sender.send(safeSub(transactionWeiAmountNoFee, currentTakeFee))) { revert(); } TakeBuyOrder(h, token, tokenAmount, weiAmount, totalTokens, buyer, msg.sender); } function takeSellOrder(address token, uint256 tokenAmount, uint256 weiAmount, address seller) public payable { require(tokenAmount != 0); require(weiAmount != 0); bytes32 h = sha256(token, tokenAmount, weiAmount, seller); // Check that the contract has enough token to satisfy this order. uint256 currentTakeFee = feeFromTotalCostForAccount(msg.value, takeFee, msg.sender); uint256 transactionWeiAmountNoFee = safeSub(msg.value, currentTakeFee); uint256 totalTokens = safeMul(transactionWeiAmountNoFee, tokenAmount) / weiAmount; require(sellOrderBalances[h] >= totalTokens); // Calculate total vested fee. uint256 currentMakeFee = calculateFeeForAccount(transactionWeiAmountNoFee, makeFee, seller); uint256 totalFee = safeAdd(currentMakeFee, currentTakeFee); uint256 makerProceedsAfterFee = safeSub(transactionWeiAmountNoFee, currentMakeFee); // Transfer. // Update internal accounting. sellOrderBalances[h] = safeSub(sellOrderBalances[h], totalTokens); // Send buyer the tokens. if (!ERC20Interface(token).transfer(msg.sender, totalTokens)) { revert(); } // Take our fee. if (totalFee > 0) { if (!feeAccount.send(totalFee)) { revert(); } } // Send seller the proceeds. if (!seller.send(makerProceedsAfterFee)) { revert(); } TakeSellOrder(h, token, tokenAmount, weiAmount, transactionWeiAmountNoFee, msg.sender, seller); } }