Transaction Hash:
Block:
5257311 at Mar-15-2018 02:52:31 AM +UTC
Transaction Fee:
0.00029195 ETH
$0.74
Gas Used:
58,390 Gas / 5 Gwei
Emitted Events:
4 |
CrypteriumToken.Transfer( from=[Sender] 0x4a74ff6e227c42da379057b1227f00b5bd300eaa, to=[Receiver] Exchange, value=700000000000000000000 )
|
5 |
Exchange.Deposit( token=CrypteriumToken, user=[Sender] 0x4a74ff6e227c42da379057b1227f00b5bd300eaa, amount=700000000000000000000, balance=700000000000000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x2a0c0DBE...44050c208 | (IDEX) | ||||
0x4A74ff6E...5bD300eaA |
0.00935762 Eth
Nonce: 16
|
0.00906567 Eth
Nonce: 17
| 0.00029195 | ||
0x80A7E048...6fA3baE7f | |||||
0x829BD824...93333A830
Miner
| (F2Pool Old) | 5,322.510796203269113641 Eth | 5,322.511088153269113641 Eth | 0.00029195 |
Execution Trace
Exchange.depositToken( token=0x80A7E048F37A50500351C204Cb407766fA3baE7f, amount=700000000000000000000 )

-
CrypteriumToken.transferFrom( _from=0x4A74ff6E227c42da379057b1227f00B5bD300eaA, _to=0x2a0c0DBEcC7E4D658f48E01e3fA353F44050c208, _value=700000000000000000000 ) => ( True )
depositToken[Exchange (ln:97)]
safeAdd[Exchange (ln:98)]
transferFrom[Exchange (ln:100)]
Deposit[Exchange (ln:101)]
File 1 of 2: Exchange
File 2 of 2: CrypteriumToken
pragma solidity ^0.4.16; contract Token { bytes32 public standard; bytes32 public name; bytes32 public symbol; uint256 public totalSupply; uint8 public decimals; bool public allowTransactions; mapping (address => uint256) public balanceOf; mapping (address => mapping (address => uint256)) public allowance; function transfer(address _to, uint256 _value) returns (bool success); function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success); function approve(address _spender, uint256 _value) returns (bool success); function transferFrom(address _from, address _to, uint256 _value) returns (bool success); } contract Exchange { function assert(bool assertion) { if (!assertion) throw; } function safeMul(uint a, uint b) returns (uint) { uint c = a * b; assert(a == 0 || c / a == b); return c; } function safeSub(uint a, uint b) returns (uint) { assert(b <= a); return a - b; } function safeAdd(uint a, uint b) returns (uint) { uint c = a + b; assert(c>=a && c>=b); return c; } address public owner; mapping (address => uint256) public invalidOrder; event SetOwner(address indexed previousOwner, address indexed newOwner); modifier onlyOwner { assert(msg.sender == owner); _; } function setOwner(address newOwner) onlyOwner { SetOwner(owner, newOwner); owner = newOwner; } function getOwner() returns (address out) { return owner; } function invalidateOrdersBefore(address user, uint256 nonce) onlyAdmin { if (nonce < invalidOrder[user]) throw; invalidOrder[user] = nonce; } mapping (address => mapping (address => uint256)) public tokens; //mapping of token addresses to mapping of account balances mapping (address => bool) public admins; mapping (address => uint256) public lastActiveTransaction; mapping (bytes32 => uint256) public orderFills; address public feeAccount; uint256 public inactivityReleasePeriod; mapping (bytes32 => bool) public traded; mapping (bytes32 => bool) public withdrawn; event Order(address tokenBuy, uint256 amountBuy, address tokenSell, uint256 amountSell, uint256 expires, uint256 nonce, address user, uint8 v, bytes32 r, bytes32 s); event Cancel(address tokenBuy, uint256 amountBuy, address tokenSell, uint256 amountSell, uint256 expires, uint256 nonce, address user, uint8 v, bytes32 r, bytes32 s); event Trade(address tokenBuy, uint256 amountBuy, address tokenSell, uint256 amountSell, address get, address give); event Deposit(address token, address user, uint256 amount, uint256 balance); event Withdraw(address token, address user, uint256 amount, uint256 balance); function setInactivityReleasePeriod(uint256 expiry) onlyAdmin returns (bool success) { if (expiry > 1000000) throw; inactivityReleasePeriod = expiry; return true; } function Exchange(address feeAccount_) { owner = msg.sender; feeAccount = feeAccount_; inactivityReleasePeriod = 100000; } function setAdmin(address admin, bool isAdmin) onlyOwner { admins[admin] = isAdmin; } modifier onlyAdmin { if (msg.sender != owner && !admins[msg.sender]) throw; _; } function() external { throw; } function depositToken(address token, uint256 amount) { tokens[token][msg.sender] = safeAdd(tokens[token][msg.sender], amount); lastActiveTransaction[msg.sender] = block.number; if (!Token(token).transferFrom(msg.sender, this, amount)) throw; Deposit(token, msg.sender, amount, tokens[token][msg.sender]); } function deposit() payable { tokens[address(0)][msg.sender] = safeAdd(tokens[address(0)][msg.sender], msg.value); lastActiveTransaction[msg.sender] = block.number; Deposit(address(0), msg.sender, msg.value, tokens[address(0)][msg.sender]); } function withdraw(address token, uint256 amount) returns (bool success) { if (safeSub(block.number, lastActiveTransaction[msg.sender]) < inactivityReleasePeriod) throw; if (tokens[token][msg.sender] < amount) throw; tokens[token][msg.sender] = safeSub(tokens[token][msg.sender], amount); if (token == address(0)) { if (!msg.sender.send(amount)) throw; } else { if (!Token(token).transfer(msg.sender, amount)) throw; } Withdraw(token, msg.sender, amount, tokens[token][msg.sender]); } function adminWithdraw(address token, uint256 amount, address user, uint256 nonce, uint8 v, bytes32 r, bytes32 s, uint256 feeWithdrawal) onlyAdmin returns (bool success) { bytes32 hash = keccak256(this, token, amount, user, nonce); if (withdrawn[hash]) throw; withdrawn[hash] = true; if (ecrecover(keccak256("\x19Ethereum Signed Message:\n32", hash), v, r, s) != user) throw; if (feeWithdrawal > 50 finney) feeWithdrawal = 50 finney; if (tokens[token][user] < amount) throw; tokens[token][user] = safeSub(tokens[token][user], amount); tokens[token][feeAccount] = safeAdd(tokens[token][feeAccount], safeMul(feeWithdrawal, amount) / 1 ether); amount = safeMul((1 ether - feeWithdrawal), amount) / 1 ether; if (token == address(0)) { if (!user.send(amount)) throw; } else { if (!Token(token).transfer(user, amount)) throw; } lastActiveTransaction[user] = block.number; Withdraw(token, user, amount, tokens[token][user]); } function balanceOf(address token, address user) constant returns (uint256) { return tokens[token][user]; } function trade(uint256[8] tradeValues, address[4] tradeAddresses, uint8[2] v, bytes32[4] rs) onlyAdmin returns (bool success) { /* amount is in amountBuy terms */ /* tradeValues [0] amountBuy [1] amountSell [2] expires [3] nonce [4] amount [5] tradeNonce [6] feeMake [7] feeTake tradeAddressses [0] tokenBuy [1] tokenSell [2] maker [3] taker */ if (invalidOrder[tradeAddresses[2]] > tradeValues[3]) throw; bytes32 orderHash = keccak256(this, tradeAddresses[0], tradeValues[0], tradeAddresses[1], tradeValues[1], tradeValues[2], tradeValues[3], tradeAddresses[2]); if (ecrecover(keccak256("\x19Ethereum Signed Message:\n32", orderHash), v[0], rs[0], rs[1]) != tradeAddresses[2]) throw; bytes32 tradeHash = keccak256(orderHash, tradeValues[4], tradeAddresses[3], tradeValues[5]); if (ecrecover(keccak256("\x19Ethereum Signed Message:\n32", tradeHash), v[1], rs[2], rs[3]) != tradeAddresses[3]) throw; if (traded[tradeHash]) throw; traded[tradeHash] = true; if (tradeValues[6] > 100 finney) tradeValues[6] = 100 finney; if (tradeValues[7] > 100 finney) tradeValues[7] = 100 finney; if (safeAdd(orderFills[orderHash], tradeValues[4]) > tradeValues[0]) throw; if (tokens[tradeAddresses[0]][tradeAddresses[3]] < tradeValues[4]) throw; if (tokens[tradeAddresses[1]][tradeAddresses[2]] < (safeMul(tradeValues[1], tradeValues[4]) / tradeValues[0])) throw; tokens[tradeAddresses[0]][tradeAddresses[3]] = safeSub(tokens[tradeAddresses[0]][tradeAddresses[3]], tradeValues[4]); tokens[tradeAddresses[0]][tradeAddresses[2]] = safeAdd(tokens[tradeAddresses[0]][tradeAddresses[2]], safeMul(tradeValues[4], ((1 ether) - tradeValues[6])) / (1 ether)); tokens[tradeAddresses[0]][feeAccount] = safeAdd(tokens[tradeAddresses[0]][feeAccount], safeMul(tradeValues[4], tradeValues[6]) / (1 ether)); tokens[tradeAddresses[1]][tradeAddresses[2]] = safeSub(tokens[tradeAddresses[1]][tradeAddresses[2]], safeMul(tradeValues[1], tradeValues[4]) / tradeValues[0]); tokens[tradeAddresses[1]][tradeAddresses[3]] = safeAdd(tokens[tradeAddresses[1]][tradeAddresses[3]], safeMul(safeMul(((1 ether) - tradeValues[7]), tradeValues[1]), tradeValues[4]) / tradeValues[0] / (1 ether)); tokens[tradeAddresses[1]][feeAccount] = safeAdd(tokens[tradeAddresses[1]][feeAccount], safeMul(safeMul(tradeValues[7], tradeValues[1]), tradeValues[4]) / tradeValues[0] / (1 ether)); orderFills[orderHash] = safeAdd(orderFills[orderHash], tradeValues[4]); lastActiveTransaction[tradeAddresses[2]] = block.number; lastActiveTransaction[tradeAddresses[3]] = block.number; } }
File 2 of 2: CrypteriumToken
pragma solidity ^0.4.16; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address public owner; /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ function Ownable() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) onlyOwner public { require(newOwner != address(0)); owner = newOwner; } } contract CrypteriumToken is Ownable { uint256 public totalSupply; mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowed; string public constant name = "CrypteriumToken"; string public constant symbol = "CRPT"; uint32 public constant decimals = 18; uint constant restrictedPercent = 30; //should never be set above 100 address constant restricted = 0x1d907C982B0B093b5173574FAbe7965181522c7B; uint constant start = 1509458400; uint constant period = 87; uint256 public constant hardcap = 300000000 * 1 ether; bool public transferAllowed = false; bool public mintingFinished = false; modifier whenTransferAllowed() { if(msg.sender != owner){ require(transferAllowed); } _; } modifier saleIsOn() { require(now > start && now < start + period * 1 days); _; } modifier canMint() { require(!mintingFinished); _; } function transfer(address _to, uint256 _value) whenTransferAllowed public returns (bool) { require(_to != address(0)); require(_value <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender] - _value; balances[_to] = balances[_to] + _value; //assert(balances[_to] >= _value); no need to check, since mint has limited hardcap Transfer(msg.sender, _to, _value); return true; } function balanceOf(address _owner) constant public returns (uint256 balance) { return balances[_owner]; } function transferFrom(address _from, address _to, uint256 _value) whenTransferAllowed public returns (bool) { require(_to != address(0)); require(_value <= balances[_from]); require(_value <= allowed[_from][msg.sender]); balances[_from] = balances[_from] - _value; balances[_to] = balances[_to] + _value; //assert(balances[_to] >= _value); no need to check, since mint has limited hardcap allowed[_from][msg.sender] = allowed[_from][msg.sender] - _value; Transfer(_from, _to, _value); return true; } function approve(address _spender, uint256 _value) public returns (bool) { //NOTE: To prevent attack vectors like the one discussed here: //https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729, //clients SHOULD make sure to create user interfaces in such a way //that they set the allowance first to 0 before setting it to another value for the same spender. allowed[msg.sender][_spender] = _value; Approval(msg.sender, _spender, _value); return true; } function allowance(address _owner, address _spender) public constant returns (uint256 remaining) { return allowed[_owner][_spender]; } function allowTransfer() onlyOwner public { transferAllowed = true; } function mint(address _to, uint256 _value) onlyOwner saleIsOn canMint public returns (bool) { require(_to != address(0)); uint restrictedTokens = _value * restrictedPercent / (100 - restrictedPercent); uint _amount = _value + restrictedTokens; assert(_amount >= _value); if(_amount + totalSupply <= hardcap){ totalSupply = totalSupply + _amount; assert(totalSupply >= _amount); balances[msg.sender] = balances[msg.sender] + _amount; assert(balances[msg.sender] >= _amount); Mint(msg.sender, _amount); transfer(_to, _value); transfer(restricted, restrictedTokens); } return true; } function finishMinting() onlyOwner public returns (bool) { mintingFinished = true; MintFinished(); return true; } /** * @dev Burns a specific amount of tokens. * @param _value The amount of token to be burned. */ function burn(uint256 _value) public returns (bool) { require(_value <= balances[msg.sender]); // no need to require value <= totalSupply, since that would imply the // sender's balance is greater than the totalSupply, which *should* be an assertion failure balances[msg.sender] = balances[msg.sender] - _value; totalSupply = totalSupply - _value; Burn(msg.sender, _value); return true; } function burnFrom(address _from, uint256 _value) public returns (bool success) { require(_value <= balances[_from]); require(_value <= allowed[_from][msg.sender]); balances[_from] = balances[_from] - _value; allowed[_from][msg.sender] = allowed[_from][msg.sender] - _value; totalSupply = totalSupply - _value; Burn(_from, _value); return true; } event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); event Mint(address indexed to, uint256 amount); event MintFinished(); event Burn(address indexed burner, uint256 value); }