Transaction Hash:
Block:
22158127 at Mar-30-2025 07:07:11 AM +UTC
Transaction Fee:
0.0000264556671354 ETH
$0.07
Gas Used:
43,234 Gas / 0.6119181 Gwei
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x8243C202...69873c341 |
2.892788284171014567 Eth
Nonce: 2033
|
2.892761828503879167 Eth
Nonce: 2034
| 0.0000264556671354 | ||
0x9361F276...c1E4881d1
Miner
| (Fee Recipient: 0x9361...1d1) | 129.594126029670194724 Eth | 129.594134587503269524 Eth | 0.0000085578330748 |
Execution Trace
Token.transfer( _to=0x061682c42bCdEd4b455Dbd0b3398b3d8DFd9036f, _value=28466800000000 ) => ( success=False )

FUNTokenController.transfer( _from=0x8243C2021fB560F92B027aca8999B5069873c341, _to=0x061682c42bCdEd4b455Dbd0b3398b3d8DFd9036f, _value=28466800000000 ) => ( success=False )
-
Ledger.transfer( _from=0x8243C2021fB560F92B027aca8999B5069873c341, _to=0x061682c42bCdEd4b455Dbd0b3398b3d8DFd9036f, _value=28466800000000 ) => ( success=False )
-
transfer[Token (ln:119)]
transfer[Token (ln:122)]
Transfer[Token (ln:124)]
File 1 of 3: Token
File 2 of 3: FUNTokenController
File 3 of 3: Ledger
pragma solidity >=0.4.4; //from Zeppelin 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 Owned { address public owner; function Owned() { owner = msg.sender; } modifier onlyOwner() { if (msg.sender != owner) throw; _; } address newOwner; function changeOwner(address _newOwner) onlyOwner { newOwner = _newOwner; } function acceptOwnership() { if (msg.sender == newOwner) { owner = newOwner; } } } contract Finalizable is Owned { bool public finalized; function finalize() onlyOwner { finalized = true; } modifier notFinalized() { if (finalized) throw; _; } } contract IToken { function transfer(address _to, uint _value) returns (bool); function balanceOf(address owner) returns(uint); } contract TokenReceivable is Owned { event logTokenTransfer(address token, address to, uint amount); function claimTokens(address _token, address _to) onlyOwner returns (bool) { IToken token = IToken(_token); uint balance = token.balanceOf(this); if (token.transfer(_to, balance)) { logTokenTransfer(_token, _to, balance); return true; } return false; } } contract EventDefinitions { event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } contract Token is Finalizable, TokenReceivable, SafeMath, EventDefinitions { string public name = "FunFair"; uint8 public decimals = 8; string public symbol = "FUN"; Controller controller; address owner; modifier onlyController() { assert(msg.sender == address(controller)); _; } function setController(address _c) onlyOwner notFinalized { controller = Controller(_c); } function balanceOf(address a) constant returns (uint) { return controller.balanceOf(a); } function totalSupply() constant returns (uint) { return controller.totalSupply(); } function allowance(address _owner, address _spender) constant returns (uint) { return controller.allowance(_owner, _spender); } function transfer(address _to, uint _value) onlyPayloadSize(2) returns (bool success) { success = controller.transfer(msg.sender, _to, _value); if (success) { Transfer(msg.sender, _to, _value); } } function transferFrom(address _from, address _to, uint _value) onlyPayloadSize(3) returns (bool success) { success = controller.transferFrom(msg.sender, _from, _to, _value); if (success) { Transfer(_from, _to, _value); } } function approve(address _spender, uint _value) onlyPayloadSize(2) returns (bool success) { //promote safe user behavior if (controller.allowance(msg.sender, _spender) > 0) throw; success = controller.approve(msg.sender, _spender, _value); if (success) { Approval(msg.sender, _spender, _value); } } function increaseApproval (address _spender, uint _addedValue) onlyPayloadSize(2) returns (bool success) { success = controller.increaseApproval(msg.sender, _spender, _addedValue); if (success) { uint newval = controller.allowance(msg.sender, _spender); Approval(msg.sender, _spender, newval); } } function decreaseApproval (address _spender, uint _subtractedValue) onlyPayloadSize(2) returns (bool success) { success = controller.decreaseApproval(msg.sender, _spender, _subtractedValue); if (success) { uint newval = controller.allowance(msg.sender, _spender); Approval(msg.sender, _spender, newval); } } modifier onlyPayloadSize(uint numwords) { assert(msg.data.length >= numwords * 32 + 4); _; } function burn(uint _amount) { controller.burn(msg.sender, _amount); Transfer(msg.sender, 0x0, _amount); } function controllerTransfer(address _from, address _to, uint _value) onlyController { Transfer(_from, _to, _value); } function controllerApprove(address _owner, address _spender, uint _value) onlyController { Approval(_owner, _spender, _value); } // multi-approve, multi-transfer bool public multilocked; modifier notMultilocked { assert(!multilocked); _; } //do we want lock permanent? I think so. function lockMultis() onlyOwner { multilocked = true; } // multi functions just issue events, to fix initial event history function multiTransfer(uint[] bits) onlyOwner notMultilocked { if (bits.length % 3 != 0) throw; for (uint i=0; i<bits.length; i += 3) { address from = address(bits[i]); address to = address(bits[i+1]); uint amount = bits[i+2]; Transfer(from, to, amount); } } function multiApprove(uint[] bits) onlyOwner notMultilocked { if (bits.length % 3 != 0) throw; for (uint i=0; i<bits.length; i += 3) { address owner = address(bits[i]); address spender = address(bits[i+1]); uint amount = bits[i+2]; Approval(owner, spender, amount); } } string public motd; event Motd(string message); function setMotd(string _m) onlyOwner { motd = _m; Motd(_m); } } contract Controller is Owned, Finalizable { Ledger public ledger; address public token; function setToken(address _token) onlyOwner { token = _token; } function setLedger(address _ledger) onlyOwner { ledger = Ledger(_ledger); } modifier onlyToken() { if (msg.sender != token) throw; _; } function totalSupply() constant returns (uint) { return ledger.totalSupply(); } function balanceOf(address _a) onlyToken constant returns (uint) { return Ledger(ledger).balanceOf(_a); } function allowance(address _owner, address _spender) onlyToken constant returns (uint) { return ledger.allowance(_owner, _spender); } function transfer(address _from, address _to, uint _value) onlyToken returns (bool success) { return ledger.transfer(_from, _to, _value); } function transferFrom(address _spender, address _from, address _to, uint _value) onlyToken returns (bool success) { return ledger.transferFrom(_spender, _from, _to, _value); } function approve(address _owner, address _spender, uint _value) onlyToken returns (bool success) { return ledger.approve(_owner, _spender, _value); } function increaseApproval (address _owner, address _spender, uint _addedValue) onlyToken returns (bool success) { return ledger.increaseApproval(_owner, _spender, _addedValue); } function decreaseApproval (address _owner, address _spender, uint _subtractedValue) onlyToken returns (bool success) { return ledger.decreaseApproval(_owner, _spender, _subtractedValue); } function burn(address _owner, uint _amount) onlyToken { ledger.burn(_owner, _amount); } } contract Ledger is Owned, SafeMath, Finalizable { address public controller; mapping(address => uint) public balanceOf; mapping (address => mapping (address => uint)) public allowance; uint public totalSupply; function setController(address _controller) onlyOwner notFinalized { controller = _controller; } modifier onlyController() { if (msg.sender != controller) throw; _; } function transfer(address _from, address _to, uint _value) onlyController returns (bool success) { if (balanceOf[_from] < _value) return false; balanceOf[_from] = safeSub(balanceOf[_from], _value); balanceOf[_to] = safeAdd(balanceOf[_to], _value); return true; } function transferFrom(address _spender, address _from, address _to, uint _value) onlyController returns (bool success) { if (balanceOf[_from] < _value) return false; var allowed = allowance[_from][_spender]; if (allowed < _value) return false; balanceOf[_to] = safeAdd(balanceOf[_to], _value); balanceOf[_from] = safeSub(balanceOf[_from], _value); allowance[_from][_spender] = safeSub(allowed, _value); return true; } function approve(address _owner, address _spender, uint _value) onlyController returns (bool success) { //require user to set to zero before resetting to nonzero if ((_value != 0) && (allowance[_owner][_spender] != 0)) { return false; } allowance[_owner][_spender] = _value; return true; } function increaseApproval (address _owner, address _spender, uint _addedValue) onlyController returns (bool success) { uint oldValue = allowance[_owner][_spender]; allowance[_owner][_spender] = safeAdd(oldValue, _addedValue); return true; } function decreaseApproval (address _owner, address _spender, uint _subtractedValue) onlyController returns (bool success) { uint oldValue = allowance[_owner][_spender]; if (_subtractedValue > oldValue) { allowance[_owner][_spender] = 0; } else { allowance[_owner][_spender] = safeSub(oldValue, _subtractedValue); } return true; } event LogMint(address indexed owner, uint amount); event LogMintingStopped(); function mint(address _a, uint _amount) onlyOwner mintingActive { balanceOf[_a] += _amount; totalSupply += _amount; LogMint(_a, _amount); } bool public mintingStopped; function stopMinting() onlyOwner { mintingStopped = true; LogMintingStopped(); } modifier mintingActive() { if (mintingStopped) throw; _; } function burn(address _owner, uint _amount) onlyController { balanceOf[_owner] = safeSub(balanceOf[_owner], _amount); totalSupply = safeSub(totalSupply, _amount); } }
File 2 of 3: FUNTokenController
{"FUNTokenController.sol":{"content":"pragma solidity ^0.4.23;\r\n\r\n//************************************************************************************************\r\n// FUN Token Controller\r\n//************************************************************************************************\r\n\r\n//************************************************************************************************\r\n// v1.00.00 - Off we go!\r\n// v1.01.00 - Added minting stuff for debug\r\n// v1.01.01 - Minting Events, and don\u0027t auto mint\r\n// v1.02.00 - Added delegation\r\n// v1.03.00 - Removed Minting\r\n// v1.04.00 - Added FateChannel Contract Whitelisting\r\n// v1.05.00 - Whitelabel Shared bankroll and allowing house to open fate channel\r\n//************************************************************************************************\r\n\r\n// import \"./BaseFUNTokenContracts.sol\";\r\nimport \"./TokenContractsFromNA.sol\";\r\nimport \"./IFateChannel.sol\";\r\n\r\n//************************************************************************************************\r\n// named\r\n//************************************************************************************************\r\ncontract Named {\r\n string name;\r\n\r\n function Named() public {\r\n\t}\r\n\r\n function getName() public constant returns (string) {\r\n return name;\r\n }\r\n}\r\n\r\n//************************************************************************************************\r\n// FUN Token Controller\r\n//************************************************************************************************\r\n\r\ncontract FUNTokenController is Controller, Named {\r\n\t//*******************************************************\r\n\t// Initialisation\r\n\tfunction FUNTokenController() public {\r\n name = \"FUN Token Controller - v1.05.00\";\r\n\t}\r\n\r\n\t//************************************************************************************************\r\n\t//** Persistent storage\r\n\r\n\t// Existing Fate Channel IDs\r\n\tmapping (bytes32 =\u003e bool) existingFateChannelIDs;\r\n\r\n\t// Delegation\r\n\tmapping (address =\u003e mapping(address =\u003e bool)) public delegation;\r\n\r\n\t// Fate Channel Contract Whitelisting\r\n\tmapping (address =\u003e bool) public permittedFateChannelContracts;\r\n\r\n\t//************************************************************************************************\r\n\t//** Events\r\n\tevent FateChannelOpened(bytes32 fateChannelID, address fateChannelAddress);\r\n\r\n\t//************************************************************************************************\r\n\t//** constant functions\r\n\tfunction isFateChannelIDInUse(bytes32 iD) public constant returns (bool) {\r\n\t\treturn existingFateChannelIDs[iD];\r\n\t}\r\n\r\n\tfunction getTokenAddress() public constant returns (address) {\r\n\t\treturn address(token);\r\n\t}\r\n\r\n\t//************************************************************************************************\r\n\t//** indexes for the open channel data array\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ADDRESS = 0;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ID = 1;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_PLAYER_ADDRESS = 2;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_PLAYER_STAKE = 3;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_HOUSE_ADDRESS = 4;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_HOUSE_STAKE = 5;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_GAME_CONTRACT_ADDRESS = 6;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_PLAYER_SIGNING_ADDRESS = 7;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_PLAYER_LAST_SEED = 8;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_HOUSE_LAST_SEED = 9;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_NETWORK = 10;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_HOUSE_TOKEN_ADDRESS = 11;\r\n\tuint256 constant OPEN_CHANNEL_DATA_INDEX_TIMESTAMP = 12;\r\n\r\n\t//************************************************************************************************\r\n\t//** Internal transfer function\r\n function transferInternal(address _from, address _to, uint _value) internal returns (bool success) {\r\n if (ledger.transfer(_from, _to, _value)) {\r\n Token(token).controllerTransfer(_from, _to, _value);\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n\t//************************************************************************************************\r\n\t//** House Address Delegation\r\n\tfunction setDelegation(address delegate, bool delegationAllowed) public {\r\n\t\t// you are not allowed to delegate yourself - this defeats the point!\r\n\t\trequire(delegate != msg.sender);\r\n\r\n\t\tdelegation[msg.sender][delegate] = delegationAllowed;\r\n\t}\r\n\r\n\t//************************************************************************************************\r\n\t//** Fate Channel Contract Whitelisting\r\n\tfunction setFateChannelContractPermission(address fateChannelContract, bool permission) public onlyOwner {\r\n\t\tpermittedFateChannelContracts[fateChannelContract] = permission;\r\n\t}\r\n\r\n\t//************************************************************************************************\r\n\t//** Open fate channel and move tokens\r\n\r\n\t//************************************************************************************************\r\n\t//** Open fate channel and move tokens\r\n\tfunction openFateChannel(bytes32[13] inputData, uint8 counterpartySigV, bytes32 counterpartySigR, bytes32 counterpartySigS) public payable {\r\n\t\t//************************************************************************************************\r\n\t\t// check the Fate Channel ID is unused\r\n\t\trequire(existingFateChannelIDs[inputData[OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ID]] == false, \"Fate Channel already used\");\r\n\r\n\t\t//************************************************************************************************\r\n\t\t// flag the Fate Channel ID as Existing - also prevents reentrancy of any subsequent code\r\n\t\texistingFateChannelIDs[inputData[OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ID]] = true;\r\n\r\n\t\t//************************************************************************************************\r\n\t\t// is the fate channel contract whitelisted\r\n\t\trequire(permittedFateChannelContracts[address(inputData[OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ADDRESS])], \"Fate Channel contract not permitted\");\r\n\r\n\t\t//************************************************************************************************\r\n\t\t// is the the account sending us this message one of the participants?\r\n\t\trequire((address(inputData[OPEN_CHANNEL_DATA_INDEX_PLAYER_ADDRESS]) == msg.sender) ||\r\n\t\t (address(inputData[OPEN_CHANNEL_DATA_INDEX_HOUSE_ADDRESS]) == msg.sender), \"Message not sent by a participant\");\r\n\r\n\t\t//************************************************************************************************\r\n\t\t//! Some invalid RSV combinations return 0...\r\n\t\trequire(address(inputData[OPEN_CHANNEL_DATA_INDEX_PLAYER_ADDRESS]) != 0, \"Invalid Player Address\");\r\n\t\trequire(address(inputData[OPEN_CHANNEL_DATA_INDEX_HOUSE_ADDRESS]) != 0, \"Invalid House Address\");\r\n\r\n\t\t//************************************************************************************************\r\n\t\t// check the counterparty signature\r\n\t\tbytes32 dataHash = keccak256(inputData);\r\n\r\n \tif (msg.sender == address(inputData[OPEN_CHANNEL_DATA_INDEX_PLAYER_ADDRESS])) {\r\n require(ecrecover(dataHash, counterpartySigV, counterpartySigR, counterpartySigS) == address(inputData[OPEN_CHANNEL_DATA_INDEX_HOUSE_ADDRESS]), \"House signature not valid\");\r\n } else {\r\n if (msg.sender == address(inputData[OPEN_CHANNEL_DATA_INDEX_HOUSE_ADDRESS])) {\r\n require(ecrecover(dataHash, counterpartySigV, counterpartySigR, counterpartySigS) == address(inputData[OPEN_CHANNEL_DATA_INDEX_PLAYER_ADDRESS]), \"Player signature not valid\");\r\n } else {\r\n // Not strictly necessary as checked above. But left in just in case some future refactoring moves things around\r\n require(false, \"Message not sent by a participant\"); // transaction must be sent by one of the parties\r\n }\r\n }\r\n\r\n\t\t//************************************************************************************************\r\n\t\t// Validate House token delegation\r\n require(delegation[address(inputData[OPEN_CHANNEL_DATA_INDEX_HOUSE_TOKEN_ADDRESS])][address(inputData[OPEN_CHANNEL_DATA_INDEX_HOUSE_ADDRESS])]);\r\n\r\n\t\t//************************************************************************************************\r\n\t\t//move the tokens\r\n \trequire(transferInternal(address(inputData[OPEN_CHANNEL_DATA_INDEX_PLAYER_ADDRESS]), address(inputData[OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ADDRESS]), uint256(inputData[OPEN_CHANNEL_DATA_INDEX_PLAYER_STAKE])), \"Player token transfer failed\");\r\n require(transferInternal(address(inputData[OPEN_CHANNEL_DATA_INDEX_HOUSE_TOKEN_ADDRESS]), address(inputData[OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ADDRESS]), uint256(inputData[OPEN_CHANNEL_DATA_INDEX_HOUSE_STAKE])), \"House token transfer failed\");\r\n\r\n\t\t// //************************************************************************************************\r\n\t\t// // and call the Fate Channel Contract to let it set things up\r\n IFateChannel fc = IFateChannel(address(inputData[OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ADDRESS]));\r\n require(fc.startFateChannel(inputData), \"Fate Channel failed to open\");\r\n\r\n\t\t//************************************************************************************************\r\n // Allow the House to send ETH to the Player as part of the channel open\r\n\r\n if (msg.value != 0) {\r\n require(msg.sender == address(inputData[OPEN_CHANNEL_DATA_INDEX_HOUSE_ADDRESS]), \"Sending ETH not allowed\");\r\n\r\n // send the ETH\r\n // reentrancy protection is handled above\r\n require(address(inputData[OPEN_CHANNEL_DATA_INDEX_PLAYER_ADDRESS]).call.value(msg.value)(\"\"), \"ETH transfer failed\");\r\n }\r\n\r\n\t\t//************************************************************************************************\r\n\t\t// Post a successful opening event\r\n\t\temit FateChannelOpened(inputData[OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ID], address(inputData[OPEN_CHANNEL_DATA_INDEX_FATE_CHANNEL_ADDRESS]));\r\n\t}\r\n}\r\n"},"IFateChannel.sol":{"content":"pragma solidity ^0.4.8;\r\n\r\n//************************************************************************************************\r\n// Fate Channel Interface\r\n//\r\n// v1.00.00 - Off we go!\r\n//************************************************************************************************\r\n\r\ncontract IFateChannel {\r\n\tfunction startFateChannel(bytes32[13] openChannelData) public returns (bool);\r\n}"},"TokenContractsFromNA.sol":{"content":"pragma solidity \u003e=0.4.4;\r\n\r\n//from Zeppelin\r\ncontract SafeMath {\r\n function safeMul(uint a, uint b) internal returns (uint) {\r\n uint c = a * b;\r\n assert(a == 0 || c / a == b);\r\n return c;\r\n }\r\n\r\n function safeSub(uint a, uint b) internal returns (uint) {\r\n assert(b \u003c= a);\r\n return a - b;\r\n }\r\n\r\n function safeAdd(uint a, uint b) internal returns (uint) {\r\n uint c = a + b;\r\n assert(c\u003e=a \u0026\u0026 c\u003e=b);\r\n return c;\r\n }\r\n\r\n function assert(bool assertion) internal {\r\n if (!assertion) throw;\r\n }\r\n}\r\n\r\ncontract Owned {\r\n address public owner;\r\n\r\n function Owned() {\r\n owner = msg.sender;\r\n }\r\n \r\n modifier onlyOwner() {\r\n if (msg.sender != owner) throw;\r\n _;\r\n }\r\n\r\n address newOwner;\r\n\r\n function changeOwner(address _newOwner) onlyOwner {\r\n newOwner = _newOwner;\r\n }\r\n\r\n function acceptOwnership() {\r\n if (msg.sender == newOwner) {\r\n owner = newOwner;\r\n }\r\n } \r\n}\r\n\r\ncontract Finalizable is Owned {\r\n bool public finalized;\r\n\r\n function finalize() onlyOwner {\r\n finalized = true;\r\n }\r\n\r\n modifier notFinalized() {\r\n if (finalized) throw;\r\n _;\r\n }\r\n}\r\n\r\ncontract IToken {\r\n function transfer(address _to, uint _value) returns (bool);\r\n function balanceOf(address owner) returns(uint);\r\n}\r\n\r\ncontract TokenReceivable is Owned {\r\n event logTokenTransfer(address token, address to, uint amount);\r\n\r\n function claimTokens(address _token, address _to) onlyOwner returns (bool) {\r\n IToken token = IToken(_token);\r\n uint balance = token.balanceOf(this);\r\n if (token.transfer(_to, balance)) {\r\n logTokenTransfer(_token, _to, balance);\r\n return true;\r\n }\r\n return false;\r\n }\r\n}\r\n\r\ncontract EventDefinitions {\r\n event Transfer(address indexed from, address indexed to, uint value);\r\n event Approval(address indexed owner, address indexed spender, uint value);\r\n}\r\n\r\ncontract Token is Finalizable, TokenReceivable, SafeMath, EventDefinitions {\r\n\r\n\r\n string public name = \"Test Fun Token\";\r\n uint8 public decimals = 8; \r\n string public symbol = \"TESTFUN\";\r\n\r\n Controller controller;\r\n address owner;\r\n\r\n modifier onlyController() {\r\n assert(msg.sender == address(controller));\r\n _;\r\n }\r\n\r\n function setController(address _c) onlyOwner notFinalized {\r\n controller = Controller(_c);\r\n }\r\n\r\n function balanceOf(address a) constant returns (uint) {\r\n return controller.balanceOf(a);\r\n }\r\n\r\n function totalSupply() constant returns (uint) {\r\n return controller.totalSupply();\r\n }\r\n\r\n function allowance(address _owner, address _spender) constant returns (uint) {\r\n return controller.allowance(_owner, _spender);\r\n }\r\n \r\n function transfer(address _to, uint _value) \r\n onlyPayloadSize(2)\r\n returns (bool success) {\r\n success = controller.transfer(msg.sender, _to, _value);\r\n if (success) {\r\n Transfer(msg.sender, _to, _value);\r\n }\r\n }\r\n\r\n function transferFrom(address _from, address _to, uint _value) \r\n onlyPayloadSize(3)\r\n returns (bool success) {\r\n success = controller.transferFrom(msg.sender, _from, _to, _value);\r\n if (success) {\r\n Transfer(_from, _to, _value);\r\n }\r\n }\r\n\r\n function approve(address _spender, uint _value) \r\n onlyPayloadSize(2)\r\n returns (bool success) {\r\n //promote safe user behavior\r\n if (controller.allowance(msg.sender, _spender) \u003e 0) throw;\r\n\r\n success = controller.approve(msg.sender, _spender, _value);\r\n if (success) {\r\n Approval(msg.sender, _spender, _value);\r\n }\r\n }\r\n\r\n function increaseApproval (address _spender, uint _addedValue) \r\n onlyPayloadSize(2)\r\n returns (bool success) {\r\n success = controller.increaseApproval(msg.sender, _spender, _addedValue);\r\n if (success) {\r\n uint newval = controller.allowance(msg.sender, _spender);\r\n Approval(msg.sender, _spender, newval);\r\n }\r\n }\r\n\r\n function decreaseApproval (address _spender, uint _subtractedValue) \r\n onlyPayloadSize(2)\r\n returns (bool success) {\r\n success = controller.decreaseApproval(msg.sender, _spender, _subtractedValue);\r\n if (success) {\r\n uint newval = controller.allowance(msg.sender, _spender);\r\n Approval(msg.sender, _spender, newval);\r\n }\r\n }\r\n \r\n modifier onlyPayloadSize(uint numwords) {\r\n assert(msg.data.length \u003e= numwords * 32 + 4);\r\n _;\r\n } \r\n\r\n function burn(uint _amount) {\r\n controller.burn(msg.sender, _amount);\r\n Transfer(msg.sender, 0x0, _amount);\r\n }\r\n\r\n function controllerTransfer(address _from, address _to, uint _value) \r\n onlyController {\r\n Transfer(_from, _to, _value);\r\n }\r\n\r\n function controllerApprove(address _owner, address _spender, uint _value) \r\n onlyController {\r\n Approval(_owner, _spender, _value);\r\n }\r\n\r\n //multi-approve, multi-transfer\r\n\r\n bool public multilocked;\r\n\r\n modifier notMultilocked {\r\n assert(!multilocked);\r\n _;\r\n }\r\n\r\n //do we want lock permanent? I think so.\r\n function lockMultis() onlyOwner {\r\n multilocked = true;\r\n }\r\n\r\n //multi functions just issue events, to fix initial event history\r\n\r\n function multiTransfer(uint[] bits) onlyOwner notMultilocked {\r\n if (bits.length % 3 != 0) throw;\r\n for (uint i=0; i\u003cbits.length; i += 3) {\r\n address from = address(bits[i]);\r\n address to = address(bits[i+1]);\r\n uint amount = bits[i+2];\r\n Transfer(from, to, amount);\r\n }\r\n }\r\n\r\n function multiApprove(uint[] bits) onlyOwner notMultilocked {\r\n if (bits.length % 3 != 0) throw;\r\n for (uint i=0; i\u003cbits.length; i += 3) {\r\n address owner = address(bits[i]);\r\n address spender = address(bits[i+1]);\r\n uint amount = bits[i+2];\r\n Approval(owner, spender, amount);\r\n }\r\n }\r\n\r\n string public motd;\r\n event Motd(string message);\r\n function setMotd(string _m) onlyOwner {\r\n motd = _m;\r\n Motd(_m);\r\n }\r\n}\r\n\r\ncontract Controller is Owned, Finalizable {\r\n Ledger public ledger;\r\n Token public token;\r\n address public oldToken;\r\n address public EtherDelta;\r\n\r\n function setEtherDelta(address _addr) onlyOwner {\r\n EtherDelta = _addr;\r\n }\r\n\r\n function setOldToken(address _token) onlyOwner {\r\n oldToken = _token;\r\n }\r\n\r\n function setToken(address _token) onlyOwner {\r\n token = Token(_token);\r\n }\r\n\r\n function setLedger(address _ledger) onlyOwner {\r\n ledger = Ledger(_ledger);\r\n }\r\n \r\n modifier onlyToken() {\r\n if (msg.sender != address(token) \u0026\u0026 msg.sender != oldToken) throw;\r\n _;\r\n }\r\n\r\n modifier onlyNewToken() {\r\n if (msg.sender != address(token)) throw;\r\n\t_;\r\n }\r\n\r\n function totalSupply() constant returns (uint) {\r\n return ledger.totalSupply();\r\n }\r\n\r\n function balanceOf(address _a) onlyToken constant returns (uint) {\r\n return Ledger(ledger).balanceOf(_a);\r\n }\r\n\r\n function allowance(address _owner, address _spender) \r\n onlyToken constant returns (uint) {\r\n return ledger.allowance(_owner, _spender);\r\n }\r\n\r\n function transfer(address _from, address _to, uint _value) \r\n onlyToken\r\n returns (bool success) {\r\n assert(msg.sender != oldToken || _from == EtherDelta);\r\n bool ok = ledger.transfer(_from, _to, _value);\r\n\tif (ok \u0026\u0026 msg.sender == oldToken)\r\n\t token.controllerTransfer(_from, _to, _value);\r\n\treturn ok;\r\n }\r\n\r\n function transferFrom(address _spender, address _from, address _to, uint _value) \r\n onlyToken\r\n returns (bool success) {\r\n assert(msg.sender != oldToken || _from == EtherDelta);\r\n bool ok = ledger.transferFrom(_spender, _from, _to, _value);\r\n\tif (ok \u0026\u0026 msg.sender == oldToken)\r\n\t token.controllerTransfer(_from, _to, _value);\r\n\treturn ok;\r\n }\r\n\r\n function approve(address _owner, address _spender, uint _value) \r\n onlyNewToken\r\n returns (bool success) {\r\n return ledger.approve(_owner, _spender, _value);\r\n }\r\n\r\n function increaseApproval (address _owner, address _spender, uint _addedValue) \r\n onlyNewToken\r\n returns (bool success) {\r\n return ledger.increaseApproval(_owner, _spender, _addedValue);\r\n }\r\n\r\n function decreaseApproval (address _owner, address _spender, uint _subtractedValue) \r\n onlyNewToken\r\n returns (bool success) {\r\n return ledger.decreaseApproval(_owner, _spender, _subtractedValue);\r\n }\r\n\r\n function burn(address _owner, uint _amount) onlyNewToken {\r\n ledger.burn(_owner, _amount);\r\n }\r\n}\r\n\r\ncontract Ledger is Owned, SafeMath, Finalizable {\r\n address public controller;\r\n mapping(address =\u003e uint) public balanceOf;\r\n mapping (address =\u003e mapping (address =\u003e uint)) public allowance;\r\n uint public totalSupply;\r\n\r\n function setController(address _controller) onlyOwner notFinalized {\r\n controller = _controller;\r\n }\r\n \r\n modifier onlyController() {\r\n if (msg.sender != controller) throw;\r\n _;\r\n }\r\n \r\n function transfer(address _from, address _to, uint _value) \r\n onlyController\r\n returns (bool success) {\r\n if (balanceOf[_from] \u003c _value) return false;\r\n\r\n balanceOf[_from] = safeSub(balanceOf[_from], _value);\r\n balanceOf[_to] = safeAdd(balanceOf[_to], _value);\r\n return true;\r\n }\r\n\r\n function transferFrom(address _spender, address _from, address _to, uint _value) \r\n onlyController\r\n returns (bool success) {\r\n if (balanceOf[_from] \u003c _value) return false; \r\n\r\n var allowed = allowance[_from][_spender];\r\n if (allowed \u003c _value) return false;\r\n\r\n balanceOf[_to] = safeAdd(balanceOf[_to], _value);\r\n balanceOf[_from] = safeSub(balanceOf[_from], _value);\r\n allowance[_from][_spender] = safeSub(allowed, _value);\r\n return true;\r\n }\r\n\r\n function approve(address _owner, address _spender, uint _value) \r\n onlyController\r\n returns (bool success) {\r\n //require user to set to zero before resetting to nonzero\r\n if ((_value != 0) \u0026\u0026 (allowance[_owner][_spender] != 0)) {\r\n return false;\r\n }\r\n \r\n allowance[_owner][_spender] = _value;\r\n return true;\r\n }\r\n\r\n function increaseApproval (address _owner, address _spender, uint _addedValue) \r\n onlyController\r\n returns (bool success) {\r\n uint oldValue = allowance[_owner][_spender];\r\n allowance[_owner][_spender] = safeAdd(oldValue, _addedValue);\r\n return true;\r\n }\r\n\r\n function decreaseApproval (address _owner, address _spender, uint _subtractedValue) \r\n onlyController\r\n returns (bool success) {\r\n uint oldValue = allowance[_owner][_spender];\r\n if (_subtractedValue \u003e oldValue) {\r\n allowance[_owner][_spender] = 0;\r\n } else {\r\n allowance[_owner][_spender] = safeSub(oldValue, _subtractedValue);\r\n }\r\n return true;\r\n }\r\n\r\n event LogMint(address indexed owner, uint amount);\r\n event LogMintingStopped();\r\n\r\n function mint(address _a, uint _amount) onlyOwner mintingActive {\r\n balanceOf[_a] += _amount;\r\n totalSupply += _amount;\r\n LogMint(_a, _amount);\r\n }\r\n\r\n /*\r\n function multiMint(uint[] bits) onlyOwner mintingActive {\r\n for (uint i=0; i\u003cbits.length; i++) {\r\n\t address a = address(bits[i]\u003e\u003e96);\r\n\t uint amount = bits[i]\u0026((1\u003c\u003c96) - 1);\r\n\t mint(a, amount);\r\n }\r\n }\r\n */\r\n\r\n bool public mintingStopped;\r\n\r\n function stopMinting() onlyOwner {\r\n mintingStopped = true;\r\n LogMintingStopped();\r\n }\r\n\r\n modifier mintingActive() {\r\n if (mintingStopped) throw;\r\n _;\r\n }\r\n\r\n function burn(address _owner, uint _amount) onlyController {\r\n balanceOf[_owner] = safeSub(balanceOf[_owner], _amount);\r\n totalSupply = safeSub(totalSupply, _amount);\r\n }\r\n}\r\n\r\n"}}
File 3 of 3: Ledger
pragma solidity >=0.4.4; //from Zeppelin 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 Owned { address public owner; function Owned() { owner = msg.sender; } modifier onlyOwner() { if (msg.sender != owner) throw; _; } address newOwner; function changeOwner(address _newOwner) onlyOwner { newOwner = _newOwner; } function acceptOwnership() { if (msg.sender == newOwner) { owner = newOwner; } } } contract Finalizable is Owned { bool public finalized; function finalize() onlyOwner { finalized = true; } modifier notFinalized() { if (finalized) throw; _; } } contract IToken { function transfer(address _to, uint _value) returns (bool); function balanceOf(address owner) returns(uint); } contract TokenReceivable is Owned { event logTokenTransfer(address token, address to, uint amount); function claimTokens(address _token, address _to) onlyOwner returns (bool) { IToken token = IToken(_token); uint balance = token.balanceOf(this); if (token.transfer(_to, balance)) { logTokenTransfer(_token, _to, balance); return true; } return false; } } contract EventDefinitions { event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } contract Token is Finalizable, TokenReceivable, SafeMath, EventDefinitions { string public name = "FunFair"; uint8 public decimals = 8; string public symbol = "FUN"; Controller controller; address owner; function setController(address _c) onlyOwner notFinalized { controller = Controller(_c); } function balanceOf(address a) constant returns (uint) { return controller.balanceOf(a); } function totalSupply() constant returns (uint) { return controller.totalSupply(); } function allowance(address _owner, address _spender) constant returns (uint) { return controller.allowance(_owner, _spender); } function transfer(address _to, uint _value) onlyPayloadSize(2) returns (bool success) { success = controller.transfer(msg.sender, _to, _value); if (success) { Transfer(msg.sender, _to, _value); } } function transferFrom(address _from, address _to, uint _value) onlyPayloadSize(3) returns (bool success) { success = controller.transferFrom(msg.sender, _from, _to, _value); if (success) { Transfer(_from, _to, _value); } } function approve(address _spender, uint _value) onlyPayloadSize(2) returns (bool success) { //promote safe user behavior if (controller.allowance(msg.sender, _spender) > 0) throw; success = controller.approve(msg.sender, _spender, _value); if (success) { Approval(msg.sender, _spender, _value); } } function increaseApproval (address _spender, uint _addedValue) onlyPayloadSize(2) returns (bool success) { success = controller.increaseApproval(msg.sender, _spender, _addedValue); if (success) { uint newval = controller.allowance(msg.sender, _spender); Approval(msg.sender, _spender, newval); } } function decreaseApproval (address _spender, uint _subtractedValue) onlyPayloadSize(2) returns (bool success) { success = controller.decreaseApproval(msg.sender, _spender, _subtractedValue); if (success) { uint newval = controller.allowance(msg.sender, _spender); Approval(msg.sender, _spender, newval); } } modifier onlyPayloadSize(uint numwords) { assert(msg.data.length == numwords * 32 + 4); _; } function burn(uint _amount) { controller.burn(msg.sender, _amount); Transfer(msg.sender, 0x0, _amount); } } contract Controller is Owned, Finalizable { Ledger public ledger; address public token; function setToken(address _token) onlyOwner { token = _token; } function setLedger(address _ledger) onlyOwner { ledger = Ledger(_ledger); } modifier onlyToken() { if (msg.sender != token) throw; _; } function totalSupply() constant returns (uint) { return ledger.totalSupply(); } function balanceOf(address _a) onlyToken constant returns (uint) { return Ledger(ledger).balanceOf(_a); } function allowance(address _owner, address _spender) onlyToken constant returns (uint) { return ledger.allowance(_owner, _spender); } function transfer(address _from, address _to, uint _value) onlyToken returns (bool success) { return ledger.transfer(_from, _to, _value); } function transferFrom(address _spender, address _from, address _to, uint _value) onlyToken returns (bool success) { return ledger.transferFrom(_spender, _from, _to, _value); } function approve(address _owner, address _spender, uint _value) onlyToken returns (bool success) { return ledger.approve(_owner, _spender, _value); } function increaseApproval (address _owner, address _spender, uint _addedValue) onlyToken returns (bool success) { return ledger.increaseApproval(_owner, _spender, _addedValue); } function decreaseApproval (address _owner, address _spender, uint _subtractedValue) onlyToken returns (bool success) { return ledger.decreaseApproval(_owner, _spender, _subtractedValue); } function burn(address _owner, uint _amount) onlyToken { ledger.burn(_owner, _amount); } } contract Ledger is Owned, SafeMath, Finalizable { address public controller; mapping(address => uint) public balanceOf; mapping (address => mapping (address => uint)) public allowance; uint public totalSupply; function setController(address _controller) onlyOwner notFinalized { controller = _controller; } modifier onlyController() { if (msg.sender != controller) throw; _; } function transfer(address _from, address _to, uint _value) onlyController returns (bool success) { if (balanceOf[_from] < _value) return false; balanceOf[_from] = safeSub(balanceOf[_from], _value); balanceOf[_to] = safeAdd(balanceOf[_to], _value); return true; } function transferFrom(address _spender, address _from, address _to, uint _value) onlyController returns (bool success) { if (balanceOf[_from] < _value) return false; var allowed = allowance[_from][_spender]; if (allowed < _value) return false; balanceOf[_to] = safeAdd(balanceOf[_to], _value); balanceOf[_from] = safeSub(balanceOf[_from], _value); allowance[_from][_spender] = safeSub(allowed, _value); return true; } function approve(address _owner, address _spender, uint _value) onlyController returns (bool success) { //require user to set to zero before resetting to nonzero if ((_value != 0) && (allowance[_owner][_spender] != 0)) { return false; } allowance[_owner][_spender] = _value; return true; } function increaseApproval (address _owner, address _spender, uint _addedValue) onlyController returns (bool success) { uint oldValue = allowance[_owner][_spender]; allowance[_owner][_spender] = safeAdd(oldValue, _addedValue); return true; } function decreaseApproval (address _owner, address _spender, uint _subtractedValue) onlyController returns (bool success) { uint oldValue = allowance[_owner][_spender]; if (_subtractedValue > oldValue) { allowance[_owner][_spender] = 0; } else { allowance[_owner][_spender] = safeSub(oldValue, _subtractedValue); } return true; } event LogMint(address indexed owner, uint amount); event LogMintingStopped(); function mint(address _a, uint _amount) onlyOwner mintingActive { balanceOf[_a] += _amount; totalSupply += _amount; LogMint(_a, _amount); } function multiMint(uint[] bits) onlyOwner mintingActive { for (uint i=0; i<bits.length; i++) { address a = address(bits[i]>>96); uint amount = bits[i]&((1<<96) - 1); mint(a, amount); } } bool public mintingStopped; function stopMinting() onlyOwner { mintingStopped = true; LogMintingStopped(); } modifier mintingActive() { if (mintingStopped) throw; _; } function burn(address _owner, uint _amount) onlyController { balanceOf[_owner] = safeSub(balanceOf[_owner], _amount); totalSupply = safeSub(totalSupply, _amount); } }