ETH Price: $2,170.24 (+0.23%)

Transaction Decoder

Block:
10302255 at Jun-20-2020 11:02:38 AM +UTC
Transaction Fee:
0.0073416 ETH $15.93
Gas Used:
229,425 Gas / 32 Gwei

Emitted Events:

164 Token.Transfer( from=[Receiver] 0x5513ff35b8cc25f126bfbccc8d2bf91fcc023522, to=0x80eD0Ee097C7B6dC8E293a6682134DB9A4852277, value=17420014200 )
165 Token.Transfer( from=[Receiver] 0x5513ff35b8cc25f126bfbccc8d2bf91fcc023522, to=0x860F231DE21A6e614950F3bbbc1D172CAfFC717A, value=200423964045313 )
166 Token.Transfer( from=[Receiver] 0x5513ff35b8cc25f126bfbccc8d2bf91fcc023522, to=0x29cd45E5F1EeEE413f208C67304D6872ec614636, value=19127000000 )
167 Token.Transfer( from=[Receiver] 0x5513ff35b8cc25f126bfbccc8d2bf91fcc023522, to=0x76e275fbb8bC233d4EFb9C20B6e2DDB408402ACe, value=2390875000 )
168 Token.Transfer( from=[Receiver] 0x5513ff35b8cc25f126bfbccc8d2bf91fcc023522, to=0x509347488209F80dC1d97076591DB92A023556ef, value=16518079687 )
169 0x5513ff35b8cc25f126bfbccc8d2bf91fcc023522.0x7acbcd6278cc39b736e5516c8ca327715768f5f5830e3f6961a7b268a9c671fe( 0x7acbcd6278cc39b736e5516c8ca327715768f5f5830e3f6961a7b268a9c671fe, 0xe123c51f8ca3bd659428dcea9ac3457cf59315b5b75544be5ce6a67c616eeeb1, 0x00000000000000000000000080ed0ee097c7b6dc8e293a6682134db9a4852277, 0x000000000000000000000000d4ffea239cff59790b10f9a982dd289a355d5fb5, 0000000000000000000000005513ff35b8cc25f126bfbccc8d2bf91fcc023522, e123c51f8ca3bd659428dcea9ac3457cf59315b5b75544be5ce6a67c616eeeb1, 00000000000000000000000080ed0ee097c7b6dc8e293a6682134db9a4852277, 0000000000000000000000000000000000000000000000000000006f9fa8de78, 000000000000000000000000d4ffea239cff59790b10f9a982dd289a355d5fb5, 0000000000000000000000000000000000000000000000000000b5e620f48000, 000000000000000000000000b8bcb072c757a1d979cf6aec7bd8c6c592c71f27, 0000000000000000000000006cb510340d8ad359d49e9478cb299c503ac9d618, 39f1d0b695dc5f296f45452e145fe40f96ec59f48e1cde75e96bc412de95b623, 014c164438662f4d6a953c5d0231d99502e9e8aae98ed779459284a3df42be75, 0000000000000000000000000000000000000000000000000000000000000001, 000000000000000000000000860f231de21a6e614950f3bbbc1d172caffc717a, 000000000000000000000000000000000000000000000000000000005eedeb34, e123c51f8ca3bd659428dcea9ac3457cf59315b5b75544be5ce6a67c616eeeb1, 0000000000000000000000000000000000000000000000000000000000000032, 000000000000000000000000000000000000000000000000000000000000002c, 000000000000000000000000000000000000000000000000000000040e505278, 0000000000000000000000000000000000000000000000000000b651b24d0c00, 0000000000000000000000000000000000000000000000000000012309ce5400, a7a683f069c24cd2fc027e90332cacd71e171b224caee041370670d416aa79bb, 5d7be8fe25c2ca8d4675500648c193752c80a695903b9bae175bb50f1f2bf401, 0000000000000000000000000000000000000000000000000000000000000002, 00000000000000000000000000000000000000000000000000000004a817c800, 00000000000000000000000000000000000000000000000000000004a817c800, fffffffffffffffffffffffffffffffffffffffffffffffffffffffb57e83800, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000006, 00000000000000000000000000000000000000000000000f000c000b000c000a, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000ee6b280005, 0000000000000000000000000000000000050104010402010402030104020202, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000009, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000002, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000001, 000000000000000000000000000000000000000000000000000000040e505278, 0000000000000000000000000000000000000000000000000000b648d72e7001, 000000000000000000000000000000000000000000000000000000008e81db78, 00000000000000000000000000000000000000000000000000000004740edbc0, 00000000000000000000000000000000000000000000000000000003d88de4c7, 00000000000000000000000080ed0ee097c7b6dc8e293a6682134db9a4852277, 000000000000000000000000860f231de21a6e614950f3bbbc1d172caffc717a, 00000000000000000000000076e275fbb8bc233d4efb9c20b6e2ddb408402ace, 00000000000000000000000029cd45e5f1eeee413f208c67304d6872ec614636, 000000000000000000000000509347488209f80dc1d97076591db92a023556ef, 0000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000005eedecce, 000000000000000000000000000000000000000000000000000000000000047d, 66b95292e4a97aee0b7d574b59454391b2cea1ce11892c06971cb7e614e1bc2d )

Account State Difference:

  Address   Before After State Difference Code
0x5513FF35...fcC023522
0xD4fFEA23...A355d5fb5
8.995087003280889064 Eth
Nonce: 42472
8.987745403280889064 Eth
Nonce: 42473
0.0073416
0xe6a51Bd4...4971d8D4E
(Ethermine)
1,054.047142772739653814 Eth1,054.054484372739653814 Eth0.0073416

Execution Trace

0x5513ff35b8cc25f126bfbccc8d2bf91fcc023522.e841e4ce( )
  • Null: 0x000...001.d423aaff( )
  • Null: 0x000...001.a43dd3b3( )
  • 0xb8bcb072c757a1d979cf6aec7bd8c6c592c71f27.CALL( )
  • 0x87a3d34e694cf061cd98cdf1621ca8945679337d.cd223289( )
  • 0xb8bcb072c757a1d979cf6aec7bd8c6c592c71f27.CALL( )
  • 0xb8bcb072c757a1d979cf6aec7bd8c6c592c71f27.CALL( )
  • 0x74b303dd79bbf44d23d60891bdd0f31df87bc7b8.CALL( )
  • Token.transfer( _to=0x80eD0Ee097C7B6dC8E293a6682134DB9A4852277, _value=17420014200 ) => ( success=True )
    • 0x74b303dd79bbf44d23d60891bdd0f31df87bc7b8.beabacc8( )
      • Ledger.transfer( _from=0x5513FF35B8cC25F126BFBccc8D2bF91fcC023522, _to=0x80eD0Ee097C7B6dC8E293a6682134DB9A4852277, _value=17420014200 ) => ( success=True )
      • Token.transfer( _to=0x860F231DE21A6e614950F3bbbc1D172CAfFC717A, _value=200423964045313 ) => ( success=True )
        • 0x74b303dd79bbf44d23d60891bdd0f31df87bc7b8.beabacc8( )
          • Ledger.transfer( _from=0x5513FF35B8cC25F126BFBccc8D2bF91fcC023522, _to=0x860F231DE21A6e614950F3bbbc1D172CAfFC717A, _value=200423964045313 ) => ( success=True )
          • Token.transfer( _to=0x29cd45E5F1EeEE413f208C67304D6872ec614636, _value=19127000000 ) => ( success=True )
            • 0x74b303dd79bbf44d23d60891bdd0f31df87bc7b8.beabacc8( )
              • Ledger.transfer( _from=0x5513FF35B8cC25F126BFBccc8D2bF91fcC023522, _to=0x29cd45E5F1EeEE413f208C67304D6872ec614636, _value=19127000000 ) => ( success=True )
              • Token.transfer( _to=0x76e275fbb8bC233d4EFb9C20B6e2DDB408402ACe, _value=2390875000 ) => ( success=True )
                • 0x74b303dd79bbf44d23d60891bdd0f31df87bc7b8.beabacc8( )
                  • Ledger.transfer( _from=0x5513FF35B8cC25F126BFBccc8D2bF91fcC023522, _to=0x76e275fbb8bC233d4EFb9C20B6e2DDB408402ACe, _value=2390875000 ) => ( success=True )
                  • Token.transfer( _to=0x509347488209F80dC1d97076591DB92A023556ef, _value=16518079687 ) => ( success=True )
                    • 0x74b303dd79bbf44d23d60891bdd0f31df87bc7b8.beabacc8( )
                      • Ledger.transfer( _from=0x5513FF35B8cC25F126BFBccc8D2bF91fcC023522, _to=0x509347488209F80dC1d97076591DB92A023556ef, _value=16518079687 ) => ( success=True )
                        File 1 of 2: 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 2: 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);
                            }
                        }