ETH Price: $2,421.07 (-0.30%)

Transaction Decoder

Block:
9913000 at Apr-21-2020 01:57:38 AM +UTC
Transaction Fee:
0.00093208 ETH $2.26
Gas Used:
116,510 Gas / 8 Gwei

Emitted Events:

124 0x3d2611440e92ce6be5f59aba7d1abfb5514dd919.0x5d07a477f2cb93b2bf0da9d5cee2e195672cefb8656e7976dc0feec339dcc8e9( 0x5d07a477f2cb93b2bf0da9d5cee2e195672cefb8656e7976dc0feec339dcc8e9, 0000000000000000000000003d2611440e92ce6be5f59aba7d1abfb5514dd919, 0000000000000000000000002b85692cc9265027f202d255d4993908b7f89392, 0000000000000000000000000000000000000000000000000011c37937e08000 )
125 Token.Transfer( from=[Receiver] 0x3d2611440e92ce6be5f59aba7d1abfb5514dd919, to=0x2b85692CC9265027f202D255d4993908b7F89392, value=30000000000 )
126 0x3d2611440e92ce6be5f59aba7d1abfb5514dd919.0xec8a926ea18363663a5a548a7025fce5cbebf4ed0f1ec215a0324f77094d52c5( 0xec8a926ea18363663a5a548a7025fce5cbebf4ed0f1ec215a0324f77094d52c5, 0000000000000000000000003d2611440e92ce6be5f59aba7d1abfb5514dd919, 0000000000000000000000002b85692cc9265027f202d255d4993908b7f89392, 00000000000000000000000000000000000000000000000000000006fc23ac00 )

Account State Difference:

  Address   Before After State Difference Code
0x2b85692C...8b7F89392
0 Eth
Nonce: 0
0.005 Eth
Nonce: 0
0.005From: 0 To: 0
0x3D261144...5514dd919 1.58352486 Eth1.57852486 Eth0.005
(Spark Pool)
75.414088793512497507 Eth75.415020873512497507 Eth0.00093208
0xD4fFEA23...A355d5fb5
4.965917482 Eth
Nonce: 28685
4.964985402 Eth
Nonce: 28686
0.00093208
0xe6a51Bd4...4971d8D4E

Execution Trace

0x3d2611440e92ce6be5f59aba7d1abfb5514dd919.b99be506( )
  • ETH 0.005 0x2b85692cc9265027f202d255d4993908b7f89392.CALL( )
  • Token.balanceOf( a=0x3D2611440E92ce6be5f59aBa7d1ABFB5514dd919 ) => ( 183405200000000 )
    • FUNTokenController.balanceOf( _a=0x3D2611440E92ce6be5f59aBa7d1ABFB5514dd919 ) => ( 183405200000000 )
      • Ledger.balanceOf( 0x3D2611440E92ce6be5f59aBa7d1ABFB5514dd919 ) => ( 183405200000000 )
      • Token.transfer( _to=0x2b85692CC9265027f202D255d4993908b7F89392, _value=30000000000 ) => ( success=True )
        • FUNTokenController.transfer( _from=0x3D2611440E92ce6be5f59aBa7d1ABFB5514dd919, _to=0x2b85692CC9265027f202D255d4993908b7F89392, _value=30000000000 ) => ( success=True )
          • Ledger.transfer( _from=0x3D2611440E92ce6be5f59aBa7d1ABFB5514dd919, _to=0x2b85692CC9265027f202D255d4993908b7F89392, _value=30000000000 ) => ( success=True )
            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);
                }
            }