ETH Price: $2,173.80 (+4.08%)

Transaction Decoder

Block:
5771527 at Jun-11-2018 05:58:13 PM +UTC
Transaction Fee:
0.000816352 ETH $1.77
Gas Used:
102,044 Gas / 8 Gwei

Emitted Events:

53 DSToken.Transfer( src=0x6924a03BB710EaF199AB6AC9F2BB148215AE9B5D, dst=[Sender] 0x9a71f95ec6f4b023d80bd67378726d2036c1332c, wad=10000000000000000000000 )
54 AirSwapExchange.Filled( makerAddress=0x6924a03BB710EaF199AB6AC9F2BB148215AE9B5D, makerAmount=10000000000000000000000, makerToken=DSToken, takerAddress=[Sender] 0x9a71f95ec6f4b023d80bd67378726d2036c1332c, takerAmount=19513137558000000000, takerToken=0x00000000...000000000, expiration=1528740151, nonce=27976841944471439515644433137131840025675238100440659780112490602184786282091 )

Account State Difference:

  Address   Before After State Difference Code
0x6924a03B...215AE9B5D 4.038985054067085432 Eth23.552122612067085432 Eth19.513137558
0x89d24A6b...a23260359
0x8fd31210...880b467b7
(AirSwap: V1 DEX Swap)
0x9a71F95E...036c1332C
20.595150625969797911 Eth
Nonce: 465
1.081196715969797911 Eth
Nonce: 466
19.51395391
(MiningPoolHub: Old Address)
16,302.225894720699087569 Eth16,302.226711072699087569 Eth0.000816352

Execution Trace

ETH 19.513137558 AirSwapExchange.fill( makerAddress=0x6924a03BB710EaF199AB6AC9F2BB148215AE9B5D, makerAmount=10000000000000000000000, makerToken=0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359, takerAddress=0x9a71F95EC6f4B023D80BD67378726d2036c1332C, takerAmount=19513137558000000000, takerToken=0x0000000000000000000000000000000000000000, expiration=1528740151, nonce=27976841944471439515644433137131840025675238100440659780112490602184786282091, v=28, r=D4BA219B434F0B96DB128DA65B25A0F11C9D68D83DC13F71E50098F513CECD33, s=3EAF8FD6C37E8BA1865EEAD129DF5A4E3D6B515F2FFD8F8F5D4A411B4969FACC )
  • Null: 0x000...001.40ebca77( )
  • DSToken.transferFrom( src=0x6924a03BB710EaF199AB6AC9F2BB148215AE9B5D, dst=0x9a71F95EC6f4B023D80BD67378726d2036c1332C, wad=10000000000000000000000 ) => ( True )
  • ETH 19.513137558 0x6924a03bb710eaf199ab6ac9f2bb148215ae9b5d.CALL( )
    File 1 of 2: AirSwapExchange
    pragma solidity ^0.4.11;
    
    // See the Github at https://github.com/airswap/contracts
    
    // Abstract contract for the full ERC 20 Token standard
    // https://github.com/ethereum/EIPs/issues/20
    
    contract Token {
        /* This is a slight change to the ERC20 base standard.
        function totalSupply() constant returns (uint256 supply);
        is replaced with:
        uint256 public totalSupply;
        This automatically creates a getter function for the totalSupply.
        This is moved to the base contract since public getter functions are not
        currently recognised as an implementation of the matching abstract
        function by the compiler.
        */
        /// total amount of tokens
        uint256 public totalSupply;
    
        /// @param _owner The address from which the balance will be retrieved
        /// @return The balance
        function balanceOf(address _owner) constant returns (uint256 balance);
    
        /// @notice send `_value` token to `_to` from `msg.sender`
        /// @param _to The address of the recipient
        /// @param _value The amount of token to be transferred
        /// @return Whether the transfer was successful or not
        function transfer(address _to, uint256 _value) returns (bool success);
    
        /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
        /// @param _from The address of the sender
        /// @param _to The address of the recipient
        /// @param _value The amount of token to be transferred
        /// @return Whether the transfer was successful or not
        function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
    
        /// @notice `msg.sender` approves `_spender` to spend `_value` tokens
        /// @param _spender The address of the account able to transfer the tokens
        /// @param _value The amount of tokens to be approved for transfer
        /// @return Whether the approval was successful or not
        function approve(address _spender, uint256 _value) returns (bool success);
    
        /// @param _owner The address of the account owning tokens
        /// @param _spender The address of the account able to transfer the tokens
        /// @return Amount of remaining tokens allowed to spent
        function allowance(address _owner, address _spender) constant returns (uint256 remaining);
    
        event Transfer(address indexed _from, address indexed _to, uint256 _value);
        event Approval(address indexed _owner, address indexed _spender, uint256 _value);
    }
    
    
    /* Implements ERC 20 Token standard: https://github.com/ethereum/EIPs/issues/20 */
    
    contract ERC20 is Token {
    
        function transfer(address _to, uint256 _value) returns (bool success) {
            require(balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]);
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        }
    
        function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
            require(balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]);
            balances[_to] += _value;
            balances[_from] -= _value;
            allowed[_from][msg.sender] -= _value;
            Transfer(_from, _to, _value);
            return true;
        }
    
        function balanceOf(address _owner) constant returns (uint256 balance) {
            return balances[_owner];
        }
    
        function approve(address _spender, uint256 _value) returns (bool success) {
            allowed[msg.sender][_spender] = _value;
            Approval(msg.sender, _spender, _value);
            return true;
        }
    
        function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
          return allowed[_owner][_spender];
        }
    
        mapping (address => uint256) public balances; // *added public
        mapping (address => mapping (address => uint256)) public allowed; // *added public
    }
    
    /** @title AirSwap exchange contract.
      * Assumes makers and takers have approved this contract to access their balances.
      */
    contract AirSwapExchange {
    
        // Mapping of order hash to bool (true = already filled).
        mapping (bytes32 => bool) public fills;
    
        // Events that are emitted in different scenarios.
        event Filled(address indexed makerAddress, uint makerAmount, address indexed makerToken, address takerAddress, uint takerAmount, address indexed takerToken, uint256 expiration, uint256 nonce);
        event Canceled(address indexed makerAddress, uint makerAmount, address indexed makerToken, address takerAddress, uint takerAmount, address indexed takerToken, uint256 expiration, uint256 nonce);
    
        /** Event thrown when a trade fails
          * Error codes:
          * 1 -> 'The makeAddress and takerAddress must be different',
          * 2 -> 'The order has expired',
          * 3 -> 'This order has already been filled',
          * 4 -> 'The ether sent with this transaction does not match takerAmount',
          * 5 -> 'No ether is required for a trade between tokens',
          * 6 -> 'The sender of this transaction must match the takerAddress',
          * 7 -> 'Order has already been cancelled or filled'
          */
        event Failed(uint code, address indexed makerAddress, uint makerAmount, address indexed makerToken, address takerAddress, uint takerAmount, address indexed takerToken, uint256 expiration, uint256 nonce);
    
        /** Fills an order by transferring tokens between (maker or escrow) and taker.
          * maker is given tokenA to taker,
          */
        function fill(address makerAddress, uint makerAmount, address makerToken,
                      address takerAddress, uint takerAmount, address takerToken,
                      uint256 expiration, uint256 nonce, uint8 v, bytes32 r, bytes32 s) payable {
    
            if (makerAddress == takerAddress) {
                msg.sender.transfer(msg.value);
                Failed(1,
                makerAddress, makerAmount, makerToken,
                takerAddress, takerAmount, takerToken,
                expiration, nonce);
                return;
            }
    
            // Check if this order has expired
            if (expiration < now) {
                msg.sender.transfer(msg.value);
                Failed(2,
                    makerAddress, makerAmount, makerToken,
                    takerAddress, takerAmount, takerToken,
                    expiration, nonce);
                return;
            }
    
            // Validate the message by signature.
            bytes32 hash = validate(makerAddress, makerAmount, makerToken,
                takerAddress, takerAmount, takerToken,
                expiration, nonce, v, r, s);
    
            // Check if this order has already been filled
            if (fills[hash]) {
                msg.sender.transfer(msg.value);
                Failed(3,
                    makerAddress, makerAmount, makerToken,
                    takerAddress, takerAmount, takerToken,
                    expiration, nonce);
                return;
            }
    
            // Check to see if this an order for ether.
            if (takerToken == address(0x0)) {
    
                // Check to make sure the message value is the order amount.
                if (msg.value == takerAmount) {
    
                    // Mark order as filled to prevent reentrancy.
                    fills[hash] = true;
    
                    // Perform the trade between makerAddress and takerAddress.
                    // The transfer will throw if there's a problem.
                    assert(transfer(makerAddress, takerAddress, makerAmount, makerToken));
    
                    // Transfer the ether received from sender to makerAddress.
                    makerAddress.transfer(msg.value);
    
                    // Log an event to indicate completion.
                    Filled(makerAddress, makerAmount, makerToken,
                        takerAddress, takerAmount, takerToken,
                        expiration, nonce);
    
                } else {
                    msg.sender.transfer(msg.value);
                    Failed(4,
                        makerAddress, makerAmount, makerToken,
                        takerAddress, takerAmount, takerToken,
                        expiration, nonce);
                }
    
            } else {
                // This is an order trading two tokens
                // Check that no ether has been sent accidentally
                if (msg.value != 0) {
                    msg.sender.transfer(msg.value);
                    Failed(5,
                        makerAddress, makerAmount, makerToken,
                        takerAddress, takerAmount, takerToken,
                        expiration, nonce);
                    return;
                }
    
                if (takerAddress == msg.sender) {
    
                    // Mark order as filled to prevent reentrancy.
                    fills[hash] = true;
    
                    // Perform the trade between makerAddress and takerAddress.
                    // The transfer will throw if there's a problem.
                    // Assert should never fail
                    assert(trade(makerAddress, makerAmount, makerToken,
                        takerAddress, takerAmount, takerToken));
    
                    // Log an event to indicate completion.
                    Filled(
                        makerAddress, makerAmount, makerToken,
                        takerAddress, takerAmount, takerToken,
                        expiration, nonce);
    
                } else {
                    Failed(6,
                        makerAddress, makerAmount, makerToken,
                        takerAddress, takerAmount, takerToken,
                        expiration, nonce);
                }
            }
        }
    
        /** Cancels an order by refunding escrow and adding it to the fills mapping.
          * Will log an event if
          * - order has been cancelled or
          * - order has already been filled
          * and will do nothing if the maker of the order in question is not the
          * msg.sender
          */
        function cancel(address makerAddress, uint makerAmount, address makerToken,
                        address takerAddress, uint takerAmount, address takerToken,
                        uint256 expiration, uint256 nonce, uint8 v, bytes32 r, bytes32 s) {
    
            // Validate the message by signature.
            bytes32 hash = validate(makerAddress, makerAmount, makerToken,
                takerAddress, takerAmount, takerToken,
                expiration, nonce, v, r, s);
    
            // Only the maker can cancel an order
            if (msg.sender == makerAddress) {
    
                // Check that order has not already been filled/cancelled
                if (fills[hash] == false) {
    
                    // Cancel the order by considering it filled.
                    fills[hash] = true;
    
                    // Broadcast an event to the blockchain.
                    Canceled(makerAddress, makerAmount, makerToken,
                        takerAddress, takerAmount, takerToken,
                        expiration, nonce);
    
                } else {
                    Failed(7,
                        makerAddress, makerAmount, makerToken,
                        takerAddress, takerAmount, takerToken,
                        expiration, nonce);
                }
            }
        }
    
        /** Atomic trade of tokens between first party and second party.
          * Throws if one of the trades does not go through.
          */
        function trade(address makerAddress, uint makerAmount, address makerToken,
                       address takerAddress, uint takerAmount, address takerToken) private returns (bool) {
            return (transfer(makerAddress, takerAddress, makerAmount, makerToken) &&
            transfer(takerAddress, makerAddress, takerAmount, takerToken));
        }
    
        /** Transfers tokens from first party to second party.
          * Prior to a transfer being done by the contract, ensure that
          * tokenVal.approve(this, amount, {from : address}) has been called
          * throws if the transferFrom of the token returns false
          * returns true if, the transfer went through
          */
        function transfer(address from, address to, uint amount, address token) private returns (bool) {
            require(ERC20(token).transferFrom(from, to, amount));
            return true;
        }
    
        /** Validates order arguments for fill() and cancel() functions. */
        function validate(address makerAddress, uint makerAmount, address makerToken,
                          address takerAddress, uint takerAmount, address takerToken,
                          uint256 expiration, uint256 nonce, uint8 v, bytes32 r, bytes32 s) private returns (bytes32) {
    
            // Hash arguments to identify the order.
            bytes32 hashV = keccak256(makerAddress, makerAmount, makerToken,
                takerAddress, takerAmount, takerToken,
                expiration, nonce);
    
            bytes memory prefix = "\x19Ethereum Signed Message:\n32";
            bytes32 prefixedHash = sha3(prefix, hashV);
    
            require(ecrecover(prefixedHash, v, r, s) == makerAddress);
    
            return hashV;
        }
    }

    File 2 of 2: DSToken
    pragma solidity ^0.4.13;
    
    ////// lib/ds-math/src/math.sol
    /// math.sol -- mixin for inline numerical wizardry
    
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // (at your option) any later version.
    
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    // You should have received a copy of the GNU General Public License
    // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    /* pragma solidity ^0.4.13; */
    
    contract DSMath {
        function add(uint x, uint y) internal pure returns (uint z) {
            require((z = x + y) >= x);
        }
        function sub(uint x, uint y) internal pure returns (uint z) {
            require((z = x - y) <= x);
        }
        function mul(uint x, uint y) internal pure returns (uint z) {
            require(y == 0 || (z = x * y) / y == x);
        }
    
        function min(uint x, uint y) internal pure returns (uint z) {
            return x <= y ? x : y;
        }
        function max(uint x, uint y) internal pure returns (uint z) {
            return x >= y ? x : y;
        }
        function imin(int x, int y) internal pure returns (int z) {
            return x <= y ? x : y;
        }
        function imax(int x, int y) internal pure returns (int z) {
            return x >= y ? x : y;
        }
    
        uint constant WAD = 10 ** 18;
        uint constant RAY = 10 ** 27;
    
        function wmul(uint x, uint y) internal pure returns (uint z) {
            z = add(mul(x, y), WAD / 2) / WAD;
        }
        function rmul(uint x, uint y) internal pure returns (uint z) {
            z = add(mul(x, y), RAY / 2) / RAY;
        }
        function wdiv(uint x, uint y) internal pure returns (uint z) {
            z = add(mul(x, WAD), y / 2) / y;
        }
        function rdiv(uint x, uint y) internal pure returns (uint z) {
            z = add(mul(x, RAY), y / 2) / y;
        }
    
        // This famous algorithm is called "exponentiation by squaring"
        // and calculates x^n with x as fixed-point and n as regular unsigned.
        //
        // It's O(log n), instead of O(n) for naive repeated multiplication.
        //
        // These facts are why it works:
        //
        //  If n is even, then x^n = (x^2)^(n/2).
        //  If n is odd,  then x^n = x * x^(n-1),
        //   and applying the equation for even x gives
        //    x^n = x * (x^2)^((n-1) / 2).
        //
        //  Also, EVM division is flooring and
        //    floor[(n-1) / 2] = floor[n / 2].
        //
        function rpow(uint x, uint n) internal pure returns (uint z) {
            z = n % 2 != 0 ? x : RAY;
    
            for (n /= 2; n != 0; n /= 2) {
                x = rmul(x, x);
    
                if (n % 2 != 0) {
                    z = rmul(z, x);
                }
            }
        }
    }
    
    ////// lib/ds-stop/lib/ds-auth/src/auth.sol
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // (at your option) any later version.
    
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    // You should have received a copy of the GNU General Public License
    // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    /* pragma solidity ^0.4.13; */
    
    contract DSAuthority {
        function canCall(
            address src, address dst, bytes4 sig
        ) public view returns (bool);
    }
    
    contract DSAuthEvents {
        event LogSetAuthority (address indexed authority);
        event LogSetOwner     (address indexed owner);
    }
    
    contract DSAuth is DSAuthEvents {
        DSAuthority  public  authority;
        address      public  owner;
    
        function DSAuth() public {
            owner = msg.sender;
            LogSetOwner(msg.sender);
        }
    
        function setOwner(address owner_)
            public
            auth
        {
            owner = owner_;
            LogSetOwner(owner);
        }
    
        function setAuthority(DSAuthority authority_)
            public
            auth
        {
            authority = authority_;
            LogSetAuthority(authority);
        }
    
        modifier auth {
            require(isAuthorized(msg.sender, msg.sig));
            _;
        }
    
        function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
            if (src == address(this)) {
                return true;
            } else if (src == owner) {
                return true;
            } else if (authority == DSAuthority(0)) {
                return false;
            } else {
                return authority.canCall(src, this, sig);
            }
        }
    }
    
    ////// lib/ds-stop/lib/ds-note/src/note.sol
    /// note.sol -- the `note' modifier, for logging calls as events
    
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // (at your option) any later version.
    
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    // You should have received a copy of the GNU General Public License
    // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    /* pragma solidity ^0.4.13; */
    
    contract DSNote {
        event LogNote(
            bytes4   indexed  sig,
            address  indexed  guy,
            bytes32  indexed  foo,
            bytes32  indexed  bar,
            uint              wad,
            bytes             fax
        ) anonymous;
    
        modifier note {
            bytes32 foo;
            bytes32 bar;
    
            assembly {
                foo := calldataload(4)
                bar := calldataload(36)
            }
    
            LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);
    
            _;
        }
    }
    
    ////// lib/ds-stop/src/stop.sol
    /// stop.sol -- mixin for enable/disable functionality
    
    // Copyright (C) 2017  DappHub, LLC
    
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // (at your option) any later version.
    
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    // You should have received a copy of the GNU General Public License
    // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    /* pragma solidity ^0.4.13; */
    
    /* import "ds-auth/auth.sol"; */
    /* import "ds-note/note.sol"; */
    
    contract DSStop is DSNote, DSAuth {
    
        bool public stopped;
    
        modifier stoppable {
            require(!stopped);
            _;
        }
        function stop() public auth note {
            stopped = true;
        }
        function start() public auth note {
            stopped = false;
        }
    
    }
    
    ////// lib/erc20/src/erc20.sol
    /// erc20.sol -- API for the ERC20 token standard
    
    // See <https://github.com/ethereum/EIPs/issues/20>.
    
    // This file likely does not meet the threshold of originality
    // required for copyright to apply.  As a result, this is free and
    // unencumbered software belonging to the public domain.
    
    /* pragma solidity ^0.4.8; */
    
    contract ERC20Events {
        event Approval(address indexed src, address indexed guy, uint wad);
        event Transfer(address indexed src, address indexed dst, uint wad);
    }
    
    contract ERC20 is ERC20Events {
        function totalSupply() public view returns (uint);
        function balanceOf(address guy) public view returns (uint);
        function allowance(address src, address guy) public view returns (uint);
    
        function approve(address guy, uint wad) public returns (bool);
        function transfer(address dst, uint wad) public returns (bool);
        function transferFrom(
            address src, address dst, uint wad
        ) public returns (bool);
    }
    
    ////// src/base.sol
    /// base.sol -- basic ERC20 implementation
    
    // Copyright (C) 2015, 2016, 2017  DappHub, LLC
    
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // (at your option) any later version.
    
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    // You should have received a copy of the GNU General Public License
    // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    /* pragma solidity ^0.4.13; */
    
    /* import "erc20/erc20.sol"; */
    /* import "ds-math/math.sol"; */
    
    contract DSTokenBase is ERC20, DSMath {
        uint256                                            _supply;
        mapping (address => uint256)                       _balances;
        mapping (address => mapping (address => uint256))  _approvals;
    
        function DSTokenBase(uint supply) public {
            _balances[msg.sender] = supply;
            _supply = supply;
        }
    
        function totalSupply() public view returns (uint) {
            return _supply;
        }
        function balanceOf(address src) public view returns (uint) {
            return _balances[src];
        }
        function allowance(address src, address guy) public view returns (uint) {
            return _approvals[src][guy];
        }
    
        function transfer(address dst, uint wad) public returns (bool) {
            return transferFrom(msg.sender, dst, wad);
        }
    
        function transferFrom(address src, address dst, uint wad)
            public
            returns (bool)
        {
            if (src != msg.sender) {
                _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
            }
    
            _balances[src] = sub(_balances[src], wad);
            _balances[dst] = add(_balances[dst], wad);
    
            Transfer(src, dst, wad);
    
            return true;
        }
    
        function approve(address guy, uint wad) public returns (bool) {
            _approvals[msg.sender][guy] = wad;
    
            Approval(msg.sender, guy, wad);
    
            return true;
        }
    }
    
    ////// src/token.sol
    /// token.sol -- ERC20 implementation with minting and burning
    
    // Copyright (C) 2015, 2016, 2017  DappHub, LLC
    
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // (at your option) any later version.
    
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    // You should have received a copy of the GNU General Public License
    // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    /* pragma solidity ^0.4.13; */
    
    /* import "ds-stop/stop.sol"; */
    
    /* import "./base.sol"; */
    
    contract DSToken is DSTokenBase(0), DSStop {
    
        bytes32  public  symbol;
        uint256  public  decimals = 18; // standard token precision. override to customize
    
        function DSToken(bytes32 symbol_) public {
            symbol = symbol_;
        }
    
        event Mint(address indexed guy, uint wad);
        event Burn(address indexed guy, uint wad);
    
        function approve(address guy) public stoppable returns (bool) {
            return super.approve(guy, uint(-1));
        }
    
        function approve(address guy, uint wad) public stoppable returns (bool) {
            return super.approve(guy, wad);
        }
    
        function transferFrom(address src, address dst, uint wad)
            public
            stoppable
            returns (bool)
        {
            if (src != msg.sender && _approvals[src][msg.sender] != uint(-1)) {
                _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
            }
    
            _balances[src] = sub(_balances[src], wad);
            _balances[dst] = add(_balances[dst], wad);
    
            Transfer(src, dst, wad);
    
            return true;
        }
    
        function push(address dst, uint wad) public {
            transferFrom(msg.sender, dst, wad);
        }
        function pull(address src, uint wad) public {
            transferFrom(src, msg.sender, wad);
        }
        function move(address src, address dst, uint wad) public {
            transferFrom(src, dst, wad);
        }
    
        function mint(uint wad) public {
            mint(msg.sender, wad);
        }
        function burn(uint wad) public {
            burn(msg.sender, wad);
        }
        function mint(address guy, uint wad) public auth stoppable {
            _balances[guy] = add(_balances[guy], wad);
            _supply = add(_supply, wad);
            Mint(guy, wad);
        }
        function burn(address guy, uint wad) public auth stoppable {
            if (guy != msg.sender && _approvals[guy][msg.sender] != uint(-1)) {
                _approvals[guy][msg.sender] = sub(_approvals[guy][msg.sender], wad);
            }
    
            _balances[guy] = sub(_balances[guy], wad);
            _supply = sub(_supply, wad);
            Burn(guy, wad);
        }
    
        // Optional token name
        bytes32   public  name = "";
    
        function setName(bytes32 name_) public auth {
            name = name_;
        }
    }