ETH Price: $2,457.23 (-2.13%)

Transaction Decoder

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 Code
0x8243C202...69873c341
2.892788284171014567 Eth
Nonce: 2033
2.892761828503879167 Eth
Nonce: 2034
0.0000264556671354
(Fee Recipient: 0x9361...1d1)
129.594126029670194724 Eth129.594134587503269524 Eth0.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 )
      File 1 of 3: Token
      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);
          }
      }