contract LD2Token is ERC20, RocketBase, Issuable {
  using SafeMath for uint256;

  event TokensIssued(address indexed issuer, uint256 amount);

  // The balances of the token, per ERC20, but stored in contract storage (rocketStorage)
  // mapping(address => uint256) token.balances;

  // The totalSupply of the token, per ERC20, but stored in contract storage (rocketStorage)
  // uint256 token.totalSupply;

  // The authorizations of the token, per ERC20, but stored in contract storage (rocketStorage)
  // This is accomplished by hashing token.allowed + _fromAddr + _toAddr
  // mapping (address => mapping (address => uint256)) internal allowed;

  /**
  * @dev total number of tokens in existence
  */
  function totalSupply() public view returns (uint256) {
    return rocketStorage.getUint(keccak256("token.totalSupply"));
  }

  /**
  * @dev increase total number of tokens in existence
  */
  function increaseTotalSupply(uint256 _increase) internal {
    uint256 totalSupply_ = totalSupply();
    totalSupply_ = totalSupply_.add(_increase);
    rocketStorage.setUint(keccak256("token.totalSupply"),totalSupply_);
  }

  /**
  * @dev decrease total number of tokens in existence
  */
  function decreaseTotalSupply(uint256 _decrease) internal {
    uint256 totalSupply_ = totalSupply();
    totalSupply_ = totalSupply_.sub(_decrease);
    rocketStorage.setUint(keccak256("token.totalSupply"),totalSupply_);
  }

  /**
  * @dev transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_to != address(0));
    require(_value <= balanceOf(msg.sender));

    // SafeMath.sub will throw if there is not enough balance.
    // Use the contract storage
    setBalanceOf(msg.sender, balanceOf(msg.sender).sub(_value));
    setBalanceOf(_to, balanceOf(_to).add(_value));
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

  /**
  * @dev Gets the balance of the specified address.
  * @param _owner The address to query the the balance of.
  * @return An uint256 representing the amount owned by the passed address.
  */
  function balanceOf(address _owner) public view returns (uint256 balance) {
    return rocketStorage.getUint(keccak256("token.balances",_owner));
  }

  /**
  * @dev Updates the balance of the specified address.
  * @param _owner The address to query the the balance of.
  * @param _balance An uint256 representing the amount owned by the passed address.
  */
  function setBalanceOf(address _owner, uint256 _balance) internal {
    rocketStorage.setUint(keccak256("token.balances",_owner), _balance);
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param _owner address The address which owns the funds.
   * @param _spender address The address which will spend the funds.
   * @return A uint256 specifying the amount of tokens still available for the spender.
   */
  function allowance(address _owner, address _spender) public view returns (uint256) {
    return rocketStorage.getUint(keccak256("token.allowed",_owner,_spender));
  }

  /**
  * @dev Updates the allowance by _owner of the _spender to have access to _balance.
  * @param _owner The address to query the the balance of.
  * @param _spender The address which will spend the funds
  * @param _balance An uint256 representing the amount owned by the passed address.
  */
  function setAllowance(address _owner, address _spender, uint256 _balance) internal {
    rocketStorage.setUint(keccak256("token.allowed",_owner,_spender), _balance);
  }

  /**
   * @dev Transfer tokens from one address to another
   * @param _from address The address which you want to send tokens from
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amount of tokens to be transferred
   */
  function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
    require(_to != address(0));
    require(_value <= balanceOf(_from));
    require(_value <= allowance(_from, msg.sender));
    
    setBalanceOf(_from, balanceOf(_from).sub(_value));
    setBalanceOf(_to, balanceOf(_to).add(_value));
    setAllowance(_from, msg.sender, allowance(_from, msg.sender).sub(_value));
    emit Transfer(_from, _to, _value);
    return true;
  }

  /**
   * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
   *
   * Beware that changing an allowance with this method brings the risk that someone may use both the old
   * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
   * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
   * @param _spender The address which will spend the funds.
   * @param _value The amount of tokens to be spent.
   */
  function approve(address _spender, uint256 _value) public returns (bool) {
    setAllowance(msg.sender, _spender, _value);
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  /**
   * @dev Increase the amount of tokens that an owner allowed to a spender.
   *
   * approve should be called when allowed[_spender] == 0. To increment
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _addedValue The amount of tokens to increase the allowance by.
   */
  function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
    setAllowance(msg.sender, _spender, allowance(msg.sender, _spender).add(_addedValue));
    emit Approval(msg.sender, _spender, allowance(msg.sender, _spender));
    return true;
  }

  /**
   * @dev Decrease the amount of tokens that an owner allowed to a spender.
   *
   * approve should be called when allowed[_spender] == 0. To decrement
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _subtractedValue The amount of tokens to decrease the allowance by.
   */
  function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
    uint oldValue = allowance(msg.sender, _spender);
    if (_subtractedValue > oldValue) {
      setAllowance(msg.sender, _spender, 0);
    } else {
      setAllowance(msg.sender, _spender, oldValue.sub(_subtractedValue));
    }
    emit Approval(msg.sender, _spender, allowance(msg.sender, _spender));
    return true;
  }


  /**
   * @dev Decrease the amount of tokens that an owner allowed to a spender.
   *
   * Issuer can only issue tokens up to the lesser of assetsOnDeposit and
   * assetsCertified.  This prevents issuing uncertified tokens and ensures
   * that every token issued has exactly one unit of the asset backing it.
   * @param _units Total amount of additional tokens to issue
   */
  function issueTokensForAssets( uint256 _units ) public onlyIssuer {

    uint256 newSupply_ = totalSupply().add(_units);

    // Find the greater of assetsOnDeposit and assetsCertified
    uint256 limit_ = 0;
    if ( assetsOnDeposit() > assetsCertified() )
      limit_ = assetsOnDeposit();
    else
      limit_ = assetsCertified();

    // the new supply can't be larger than our issuance limit
    require( newSupply_ <= limit_ );

    // Increase the total supply
    increaseTotalSupply( _units );

    // Increase the issuer's balance
    setBalanceOf(issuer(), balanceOf(issuer()).add(_units));

    emit TokensIssued(issuer(), _units);
  }

}
/// @title The primary ERC20 token contract, using LD2 storage
/// @author Steven Brendtro
function setBalanceOf(address _owner, uint256 _balance) internal {
  rocketStorage.setUint(keccak256("token.balances",_owner), _balance);
}

/**
 * @dev Updates the balance of the specified address.
 * @param _owner The address to query the the balance of.
 * @param _balance An uint256 representing the amount owned by the passed address.
 */