ETH Price: $1,980.05 (-3.84%)

Transaction Decoder

Block:
11317238 at Nov-23-2020 10:42:18 PM +UTC
Transaction Fee:
0.00288816 ETH $5.72
Gas Used:
48,136 Gas / 60 Gwei

Emitted Events:

365 Tribute.Approval( _owner=[Sender] 0x23f5880b0265749651c3c30bdeab14eaf479c734, _spender=0x00000000...000000000, _value=115792089237316195423570985008687907853269984665640564039457584007913129639935 )

Account State Difference:

  Address   Before After State Difference Code
0x23F5880b...aF479c734
4.578362733408093198 Eth
Nonce: 737
4.575474573408093198 Eth
Nonce: 738
0.00288816
105.475810508367531651 Eth105.478698668367531651 Eth0.00288816
0x55Ee5c0e...6371Cd887

Execution Trace

Tribute.approve( _spender=0x0000000000000000000000000000000000000000, _value=115792089237316195423570985008687907853269984665640564039457584007913129639935 ) => ( True )
  • 0x55ee5c0e87a72d85e9483091db441d96371cd887.e2e52ec1( )
    pragma solidity ^0.5.17;
    
    
    
    /*
    ******************** TRIBUTE *********************
    *
    *       _____                    _____                    _____                    _____                    _____                _____                    _____
    *      /\    \                  /\    \                  /\    \                  /\    \                  /\    \              /\    \                  /\    \
    *     /::\    \                /::\    \                /::\    \                /::\    \                /::\____\            /::\    \                /::\    \
    *     \:::\    \              /::::\    \               \:::\    \              /::::\    \              /:::/    /            \:::\    \              /::::\    \
    *      \:::\    \            /::::::\    \               \:::\    \            /::::::\    \            /:::/    /              \:::\    \            /::::::\    \
    *       \:::\    \          /:::/\:::\    \               \:::\    \          /:::/\:::\    \          /:::/    /                \:::\    \          /:::/\:::\    \
    *        \:::\    \        /:::/__\:::\    \               \:::\    \        /:::/__\:::\    \        /:::/    /                  \:::\    \        /:::/__\:::\    \
    *        /::::\    \      /::::\   \:::\    \              /::::\    \      /::::\   \:::\    \      /:::/    /                   /::::\    \      /::::\   \:::\    \
    *       /::::::\    \    /::::::\   \:::\    \    ____    /::::::\    \    /::::::\   \:::\    \    /:::/    /      _____        /::::::\    \    /::::::\   \:::\    \
    *      /:::/\:::\    \  /:::/\:::\   \:::\____\  /\   \  /:::/\:::\    \  /:::/\:::\   \:::\ ___\  /:::/____/      /\    \      /:::/\:::\    \  /:::/\:::\   \:::\    \
    *     /:::/  \:::\____\/:::/  \:::\   \:::|    |/::\   \/:::/  \:::\____\/:::/__\:::\   \:::|    ||:::|    /      /::\____\    /:::/  \:::\____\/:::/__\:::\   \:::\____\
    *    /:::/    \::/    /\::/   |::::\  /:::|____|\:::\  /:::/    \::/    /\:::\   \:::\  /:::|____||:::|____\     /:::/    /   /:::/    \::/    /\:::\   \:::\   \::/    /
    *   /:::/    / \/____/  \/____|:::::\/:::/    /  \:::\/:::/    / \/____/  \:::\   \:::\/:::/    /  \:::\    \   /:::/    /   /:::/    / \/____/  \:::\   \:::\   \/____/
    *  /:::/    /                 |:::::::::/    /    \::::::/    /            \:::\   \::::::/    /    \:::\    \ /:::/    /   /:::/    /            \:::\   \:::\    \
    * /:::/    /                  |::|\::::/    /      \::::/____/              \:::\   \::::/    /      \:::\    /:::/    /   /:::/    /              \:::\   \:::\____\
    * \::/    /                   |::| \::/____/        \:::\    \               \:::\  /:::/    /        \:::\__/:::/    /    \::/    /                \:::\   \::/    /
    * \/____/                    |::|  ~|               \:::\    \               \:::\/:::/    /          \::::::::/    /      \/____/                  \:::\   \/____/
    *                            |::|   |                \:::\    \               \::::::/    /            \::::::/    /                                 \:::\    \
    *                            \::|   |                 \:::\____\               \::::/    /              \::::/    /                                   \:::\____\
    *                             \:|   |                  \::/    /                \::/____/                \::/____/                                     \::/    /
    *                              \|___|                   \/____/                  ~~                       ~~                                            \/____/
    *
    *
    ******************** TRIBUTE *********************
    *
    * Official Website: https://tributedefi.com/
    * Official Discord: https://discord.com/invite/TBmMHb5
    * Official Telegram: https://t.me/tributedefi
    * Official Twitter: https://twitter.com/TributeDefi
    * Buy Tokens at https://app.uniswap.org/#/swap
    */
    
    
    interface ApproveAndCallFallBack {
        function receiveApproval(address from, uint256 tokens, address token, bytes20 data) external;
    }
    
    library SafeMath {
      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
          return 0;
        }
        uint256 c = a * b;
        require(c / a == b);
        return c;
      }
      function mult(uint256 x, uint256 y) internal pure returns (uint256) {
          if (x == 0) {
              return 0;
          }
    
          uint256 z = x * y;
          require(z / x == y, "Mult overflow");
          return z;
      }
      function div(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a / b;
        return c;
      }
      function divRound(uint256 x, uint256 y) internal pure returns (uint256) {
          require(y != 0, "Div by zero");
          uint256 r = x / y;
          if (x % y != 0) {
              r = r + 1;
          }
    
          return r;
      }
      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        return a - b;
      }
    
      function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);
        return c;
      }
    
      function ceil(uint256 a, uint256 m) internal pure returns (uint256) {
        uint256 c = add(a,m);
        uint256 d = sub(c,1);
        return mul(div(d,m),m);
      }
    }
    
    contract Ownable {
        address public owner;
    
        event TransferOwnership(address _from, address _to);
    
        constructor() public {
            owner = msg.sender;
            emit TransferOwnership(address(0), msg.sender);
        }
    
        modifier onlyOwner() {
            require(msg.sender == owner, "only owner");
            _;
        }
    
        function setOwner(address _owner) external onlyOwner {
            emit TransferOwnership(owner, _owner);
            owner = _owner;
        }
    }
    
    
    
    
    contract StorageUnit {
        address private owner;
        mapping(bytes32 => bytes32) private store;
    
        constructor() public {
            owner = msg.sender;
        }
    
        function write(bytes32 _key, bytes32 _value) external {
            /* solium-disable-next-line */
            require(msg.sender == owner);
            store[_key] = _value;
        }
    
        function read(bytes32 _key) external view returns (bytes32) {
            return store[_key];
        }
    }
    
    
    
    
    library IsContract {
        function isContract(address _addr) internal view returns (bool) {
            bytes32 codehash;
            /* solium-disable-next-line */
            assembly { codehash := extcodehash(_addr) }
            return codehash != bytes32(0) && codehash != bytes32(0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470);
        }
    }
    
    
    
    
    library DistributedStorage {
        function contractSlot(bytes32 _struct) private view returns (address) {
            return address(
                uint256(
                    keccak256(
                        abi.encodePacked(
                            byte(0xff),
                            address(this),
                            _struct,
                            keccak256(type(StorageUnit).creationCode)
                        )
                    )
                )
            );
        }
    
        function deploy(bytes32 _struct) private {
            bytes memory slotcode = type(StorageUnit).creationCode;
            /* solium-disable-next-line */
            assembly{ pop(create2(0, add(slotcode, 0x20), mload(slotcode), _struct)) }
        }
    
        function write(
            bytes32 _struct,
            bytes32 _key,
            bytes32 _value
        ) internal {
            StorageUnit store = StorageUnit(contractSlot(_struct));
            if (!IsContract.isContract(address(store))) {
                deploy(_struct);
            }
    
            /* solium-disable-next-line */
            (bool success, ) = address(store).call(
                abi.encodeWithSelector(
                    store.write.selector,
                    _key,
                    _value
                )
            );
    
            require(success, "error writing storage");
        }
    
        function read(
            bytes32 _struct,
            bytes32 _key
        ) internal view returns (bytes32) {
            StorageUnit store = StorageUnit(contractSlot(_struct));
            if (!IsContract.isContract(address(store))) {
                return bytes32(0);
            }
    
            /* solium-disable-next-line */
            (bool success, bytes memory data) = address(store).staticcall(
                abi.encodeWithSelector(
                    store.read.selector,
                    _key
                )
            );
    
            require(success, "error reading storage");
            return abi.decode(data, (bytes32));
        }
    }
    
    
    
    
    contract Inject {
        bytes32 private stub;
    
        modifier requestGas(uint256 _factor) {
            if (tx.gasprice == 0 || gasleft() > block.gaslimit) {
                uint256 startgas = gasleft();
                _;
                uint256 delta = startgas - gasleft();
                uint256 target = (delta * _factor) / 100;
                startgas = gasleft();
                while (startgas - gasleft() < target) {
    
                    stub = keccak256(abi.encodePacked(stub));
                }
            } else {
                _;
            }
        }
    }
    
    
    
    
    interface IERC20 {
        event Transfer(address indexed _from, address indexed _to, uint256 _value);
        event Approval(address indexed _owner, address indexed _spender, uint256 _value);
        function transfer(address _to, uint _value) external returns (bool success);
        function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
        function allowance(address _owner, address _spender) external view returns (uint256 remaining);
        function approve(address _spender, uint256 _value) external returns (bool success);
        function balanceOf(address _owner) external view returns (uint256 balance);
    }
    
    
    
    
    library AddressMinMound {
        using AddressMinMound for AddressMinMound.Mound;
    
        struct Mound {
            uint256[] entries;
            mapping(address => uint256) index;
        }
    
        function initialize(Mound storage _mound) internal {
            require(_mound.entries.length == 0, "already initialized");
            _mound.entries.push(0);
        }
    
        function encode(address _addr, uint256 _value) internal pure returns (uint256 _entry) {
            /* solium-disable-next-line */
            assembly {
                _entry := not(or(and(0xffffffffffffffffffffffffffffffffffffffff, _addr), shl(160, _value)))
            }
        }
    
        function decode(uint256 _entry) internal pure returns (address _addr, uint256 _value) {
            /* solium-disable-next-line */
            assembly {
                let entry := not(_entry)
                _addr := and(entry, 0xffffffffffffffffffffffffffffffffffffffff)
                _value := shr(160, entry)
            }
        }
    
        function decodeAddress(uint256 _entry) internal pure returns (address _addr) {
            /* solium-disable-next-line */
            assembly {
                _addr := and(not(_entry), 0xffffffffffffffffffffffffffffffffffffffff)
            }
        }
    
        function top(Mound storage _mound) internal view returns(address, uint256) {
            if (_mound.entries.length < 2) {
                return (address(0), 0);
            }
    
            return decode(_mound.entries[1]);
        }
    
        function has(Mound storage _mound, address _addr) internal view returns (bool) {
            return _mound.index[_addr] != 0;
        }
    
        function size(Mound storage _mound) internal view returns (uint256) {
            return _mound.entries.length - 1;
        }
    
        function entry(Mound storage _mound, uint256 _i) internal view returns (address, uint256) {
            return decode(_mound.entries[_i + 1]);
        }
    
        function popTop(Mound storage _mound) internal returns(address _addr, uint256 _value) {
            // Mound true or false
            uint256 moundLength = _mound.entries.length;
            require(moundLength > 1, "The mound does not exist");
    
            // Origin Mound Value
            (_addr, _value) = decode(_mound.entries[1]);
            _mound.index[_addr] = 0;
    
            if (moundLength == 2) {
                _mound.entries.length = 1;
            } else {
                uint256 val = _mound.entries[moundLength - 1];
                _mound.entries[1] = val;
                _mound.entries.length = moundLength - 1;
    
                uint256 ind = 1;
    
                ind = _mound.deflatIt(ind, val);
    
                _mound.index[decodeAddress(val)] = ind;
            }
        }
    
        function insert(Mound storage _mound, address _addr, uint256 _value) internal {
            require(_mound.index[_addr] == 0, "The entry already exists");
    
            uint256 encoded = encode(_addr, _value);
            _mound.entries.push(encoded);
    
            uint256 currentIndex = _mound.entries.length - 1;
    
            currentIndex = _mound.inflatIt(currentIndex, encoded);
    
            _mound.index[_addr] = currentIndex;
        }
    
        function update(Mound storage _mound, address _addr, uint256 _value) internal {
            uint256 ind = _mound.index[_addr];
            require(ind != 0, "The entry does not exist");
    
            uint256 can = encode(_addr, _value);
            uint256 val = _mound.entries[ind];
            uint256 newInd;
    
            if (can < val) {
                // deflate It
                newInd = _mound.deflatIt(ind, can);
            } else if (can > val) {
                // inflate It
                newInd = _mound.inflatIt(ind, can);
            } else {
    
                return;
            }
    
            _mound.entries[newInd] = can;
    
            if (newInd != ind) {
                _mound.index[_addr] = newInd;
            }
        }
    
        function inflatIt(Mound storage _mound, uint256 _ind, uint256 _val) internal returns (uint256 ind) {
            ind = _ind;
            if (ind != 1) {
                uint256 parent = _mound.entries[ind / 2];
                while (parent < _val) {
                    (_mound.entries[ind / 2], _mound.entries[ind]) = (_val, parent);
    
                    _mound.index[decodeAddress(parent)] = ind;
    
                    ind = ind / 2;
                    if (ind == 1) {
                        break;
                    }
                    parent = _mound.entries[ind / 2];
                }
            }
        }
    
        function deflatIt(Mound storage _mound, uint256 _ind, uint256 _val) internal returns (uint256 ind) {
    
            ind = _ind;
    
            uint256 lenght = _mound.entries.length;
            uint256 target = lenght - 1;
    
            while (ind * 2 < lenght) {
    
                uint256 j = ind * 2;
    
                uint256 leftChild = _mound.entries[j];
    
                uint256 childValue;
    
                if (target > j) {
    
                    uint256 rightChild = _mound.entries[j + 1];
    
                    if (leftChild < rightChild) {
                        childValue = rightChild;
                        j = j + 1;
                    } else {
    
                        childValue = leftChild;
                    }
                } else {
    
                    childValue = leftChild;
                }
    
                if (_val > childValue) {
                    break;
                }
    
                (_mound.entries[ind], _mound.entries[j]) = (childValue, _val);
    
                _mound.index[decodeAddress(childValue)] = ind;
    
                ind = j;
            }
        }
    }
    
    
    
    
    contract Mound is Ownable {
        using AddressMinMound for AddressMinMound.Mound;
    
        // Mound
        AddressMinMound.Mound private mound;
    
        // Mound events
        event Joinmound(address indexed _address, uint256 _balance, uint256 _prevSize);
        event Leavemound(address indexed _address, uint256 _balance, uint256 _prevSize);
    
        uint256 public constant TOP_SIZE = 50;//1000;
    
        constructor() public {
            mound.initialize();
        }
    
        function topSize() external pure returns (uint256) {
            return TOP_SIZE;
        }
    
        function addressAt(uint256 _i) external view returns (address addr) {
            (addr, ) = mound.entry(_i);
        }
    
        function indexOf(address _addr) external view returns (uint256) {
            return mound.index[_addr];
        }
    
        function entry(uint256 _i) external view returns (address, uint256) {
            return mound.entry(_i);
        }
    
        function top() external view returns (address, uint256) {
            return mound.top();
        }
    
        function size() external view returns (uint256) {
            return mound.size();
        }
    
        function update(address _addr, uint256 _new) external onlyOwner {
            uint256 _size = mound.size();
    
            if (_size == 0) {
                emit Joinmound(_addr, _new, 0);
                mound.insert(_addr, _new);
                return;
            }
    
            (, uint256 lastBal) = mound.top();
            if (mound.has(_addr)) {
                mound.update(_addr, _new);
                 if (_new == 0) {
                    mound.popTop();
                    emit Leavemound(_addr, 0, _size);
                }
            } else {
    
                if (_new != 0 && (_size < TOP_SIZE || lastBal < _new)) {
    
                    if (_size >= TOP_SIZE) {
                        (address _poped, uint256 _balance) = mound.popTop();
                        emit Leavemound(_poped, _balance, _size);
                    }
    
                    // New
                    mound.insert(_addr, _new);
                    emit Joinmound(_addr, _new, _size);
                }
            }
        }
    }
    
    
    
    
    contract Tribute is Ownable, Inject, IERC20 {
        using DistributedStorage for bytes32;
        using SafeMath for uint256;
    
        // Distribution
        event Choosen(address indexed _addr, uint256 _value);
    
        // Org
        event SetName(string _prev, string _new);
        event SetExtraGas(uint256 _prev, uint256 _new);
        event Setmound(address _prev, address _new);
        event WhitelistFrom(address _addr, bool _whitelisted);
        event WhitelistTo(address _addr, bool _whitelisted);
    
        uint256 public totalSupply;
        uint256 public totalBurned;
    
        bytes32 private constant BALANCE_KEY = keccak256("balance");
    
        // Burn Mechanism: 5% burn 5% reward
        uint256 public constant FEE = 20;
    
        // Token Parameters
        string public name = "Tribute";
        string public constant symbol = "TRBT";
        uint8 public constant decimals = 18;
    
        // fee whitelist
        mapping(address => bool) public whitelistFrom;
        mapping(address => bool) public whitelistTo;
    
        // mound
        Mound public mound;
    
        // internal
        uint256 public extraGas;
        bool inited;
    
        function init(
            address _to,
            uint256 _amount
        ) external {
            // Init limited to one
            assert(!inited);
            inited = true;
    
            assert(totalSupply == 0);
            assert(address(mound) == address(0));
    
            // Create mound
            mound = new Mound();
            emit Setmound(address(0), address(mound));
    
            extraGas = 15;
            emit SetExtraGas(0, extraGas);
            emit Transfer(address(0), _to, _amount);
            _setBalance(_to, _amount);
            totalSupply = _amount;
        }
    
        // Get Functions
    
        function _toKey(address a) internal pure returns (bytes32) {
            return bytes32(uint256(a));
        }
    
        function _balanceOf(address _addr) internal view returns (uint256) {
            return uint256(_toKey(_addr).read(BALANCE_KEY));
        }
    
        function _allowance(address _addr, address _spender) internal view returns (uint256) {
            return uint256(_toKey(_addr).read(keccak256(abi.encodePacked("allowance", _spender))));
        }
    
        function _nonce(address _addr, uint256 _cat) internal view returns (uint256) {
            return uint256(_toKey(_addr).read(keccak256(abi.encodePacked("nonce", _cat))));
        }
    
        // Set Functions
    
        function _setAllowance(address _addr, address _spender, uint256 _value) internal {
            _toKey(_addr).write(keccak256(abi.encodePacked("allowance", _spender)), bytes32(_value));
        }
    
        function _setNonce(address _addr, uint256 _cat, uint256 _value) internal {
            _toKey(_addr).write(keccak256(abi.encodePacked("nonce", _cat)), bytes32(_value));
        }
    
        function _setBalance(address _addr, uint256 _balance) internal {
            _toKey(_addr).write(BALANCE_KEY, bytes32(_balance));
            mound.update(_addr, _balance);
        }
    
        // Distribution Functions
    
        function _isWhitelisted(address _from, address _to) internal view returns (bool) {
            return whitelistFrom[_from]||whitelistTo[_to];
        }
    
        function _random(address _s1, uint256 _s2, uint256 _s3, uint256 _max) internal pure returns (uint256) {
            uint256 rand = uint256(keccak256(abi.encodePacked(_s1, _s2, _s3)));
            return rand % (_max + 1);
        }
    
        function _pickChoosen(address _from, uint256 _value) internal returns (address choosen) {
            uint256 magnitude = Math.orderOfMagnitude(_value);
            uint256 nonce = _nonce(_from, magnitude);
            _setNonce(_from, magnitude, nonce + 1);
            // choose from mound
            choosen = mound.addressAt(_random(_from, nonce, magnitude, mound.size() - 1));
        }
        //event DebugTest2(uint allowance,uint from,address sender);
        function _transferFrom(address _operator, address _from, address _to, uint256 _value, bool _payFee) internal {
            if (_value == 0) {
                emit Transfer(_from, _to, 0);
                return;
            }
    
            uint256 balanceFrom = _balanceOf(_from);
            require(balanceFrom >= _value, "balance not enough");
    
            if (_from != _operator) {
                uint256 allowanceFrom = _allowance(_from, _operator);
                if (allowanceFrom != uint(-1)) {
                    //emit DebugTest2(allowanceFrom,_value,_operator);
                    require(allowanceFrom >= _value, "allowance not enough");
                    _setAllowance(_from, _operator, allowanceFrom.sub(_value));
                }
            }
    
            uint256 receive = _value;
            uint256 burn = 0;
            uint256 distribute = 0;
    
            _setBalance(_from, balanceFrom.sub(_value));
    
            // Fees Calculation
            if (_payFee || !_isWhitelisted(_from, _to)) {
                // SAME for BURN and DISTRIBUTION
                burn = _value.divRound(FEE);
                distribute = _value == 1 ? 0 : burn;
    
                receive = receive.sub(burn.add(distribute));
    
                // Burn
                totalSupply = totalSupply.sub(burn);
                totalBurned = totalBurned.add(burn);
                emit Transfer(_from, address(0), burn);
    
                // Distribute to choosen add
                address choosen = _pickChoosen(_from, _value);
                // Tokens to choosen
                _setBalance(choosen, _balanceOf(choosen).add(distribute));
                emit Choosen(choosen, distribute);
                emit Transfer(_from, choosen, distribute);
            }
    
            assert(burn.add(distribute).add(receive) == _value);
    
            _setBalance(_to, _balanceOf(_to).add(receive));
            emit Transfer(_from, _to, receive);
        }
    
        // Org functions
    
        function setWhitelistedTo(address _addr, bool _whitelisted) external onlyOwner {
            emit WhitelistTo(_addr, _whitelisted);
            whitelistTo[_addr] = _whitelisted;
        }
    
        function setWhitelistedFrom(address _addr, bool _whitelisted) external onlyOwner {
            emit WhitelistFrom(_addr, _whitelisted);
            whitelistFrom[_addr] = _whitelisted;
        }
    
        function setName(string calldata _name) external onlyOwner {
            emit SetName(name, _name);
            name = _name;
        }
    
        function setExtraGas(uint256 _gas) external onlyOwner {
            emit SetExtraGas(extraGas, _gas);
            extraGas = _gas;
        }
    
        function setmound(Mound _mound) external onlyOwner {
            emit Setmound(address(mound), address(_mound));
            mound = _mound;
        }
    
        // Mound functions
    
        function topSize() external view returns (uint256) {
            return mound.topSize();
        }
    
        function moundSize() external view returns (uint256) {
            return mound.size();
        }
    
        function moundEntry(uint256 _i) external view returns (address, uint256) {
            return mound.entry(_i);
        }
    
        function moundTop() external view returns (address, uint256) {
            return mound.top();
        }
    
        function moundIndex(address _addr) external view returns (uint256) {
            return mound.indexOf(_addr);
        }
    
        function getNonce(address _addr, uint256 _cat) external view returns (uint256) {
            return _nonce(_addr, _cat);
        }
    
        // ERC20 functions
    
        function balanceOf(address _addr) external view returns (uint256) {
            return _balanceOf(_addr);
        }
    
        function allowance(address _addr, address _spender) external view returns (uint256) {
            return _allowance(_addr, _spender);
        }
    
        function approve(address _spender, uint256 _value) external returns (bool) {
            emit Approval(msg.sender, _spender, _value);
            _setAllowance(msg.sender, _spender, _value);
            return true;
        }
    
        function transfer(address _to, uint256 _value) external requestGas(extraGas) returns (bool) {
            _transferFrom(msg.sender, msg.sender, _to, _value, false);
            return true;
        }
    
        function transferWithFee(address _to, uint256 _value) external requestGas(extraGas) returns (bool) {
            _transferFrom(msg.sender, msg.sender, _to, _value, true);
            return true;
        }
    
        function transferFrom(address _from, address _to, uint256 _value) external requestGas(extraGas) returns (bool) {
            _transferFrom(msg.sender, _from, _to, _value, false);
            return true;
        }
    
        function transferFromWithFee(address _from, address _to, uint256 _value) external requestGas(extraGas) returns (bool) {
            _transferFrom(msg.sender, _from, _to, _value, true);
            return true;
        }
        function approveAndCall(address _spender, uint256 _value, bytes20 _data) external returns (bool) {
          emit Approval(msg.sender, _spender, _value);
          _setAllowance(msg.sender, _spender, _value);
          ApproveAndCallFallBack(_spender).receiveApproval(msg.sender, _value, address(this), _data);
          return true;
        }
        function burn(uint256 _value) public {
          _transferFrom(msg.sender, msg.sender, address(0), _value, true);
          totalSupply = totalSupply.sub(_value);
        }
    }
    
    
    
    
    
    library Math {
        function orderOfMagnitude(uint256 input) internal pure returns (uint256){
            uint256 counter = uint(-1);
            uint256 temp = input;
    
            do {
                temp /= 10;
                counter++;
            } while (temp != 0);
    
            return counter;
        }
    
        function min(uint256 _a, uint256 _b) internal pure returns (uint256) {
            if (_a < _b) {
                return _a;
            } else {
                return _b;
            }
        }
    
        function max(uint256 _a, uint256 _b) internal pure returns (uint256) {
            if (_a > _b) {
                return _a;
            } else {
                return _b;
            }
        }
    }