contract XPAAssetToken is StandardToken, Authorization {
    // metadata
    address[] public burners;
    string public name;
    string public symbol;
    uint256 public defaultExchangeRate;
    uint256 public constant decimals = 18;

    // constructor
    function XPAAssetToken(
        string symbol_,
        string name_,
        uint256 defaultExchangeRate_
    )
        public
    {
        totalSupply = 0;
        symbol = symbol_;
        name = name_;
        defaultExchangeRate = defaultExchangeRate_ > 0 ? defaultExchangeRate_ : 0.01 ether;
    }

    function transferOwnership(
        address newOwner_
    )
        onlyOwner
        public
    {
        owner = newOwner_;
    }

    function create(
        address user_,
        uint256 amount_
    )
        public
        onlyOperator
    returns(bool success) {
        if(amount_ > 0 && user_ != address(0)) {
            totalSupply = safeAdd(totalSupply, amount_);
            balances[user_] = safeAdd(balances[user_], amount_);
            emit Issue(owner, amount_);
            emit Transfer(owner, user_, amount_);
            return true;
        }
    }

    function burn(
        uint256 amount_
    )
        public
    returns(bool success) {
        require(allowToBurn(msg.sender));
        if(amount_ > 0 && balances[msg.sender] >= amount_) {
            balances[msg.sender] = safeSub(balances[msg.sender], amount_);
            totalSupply = safeSub(totalSupply, amount_);
            emit Transfer(msg.sender, owner, amount_);
            emit Burn(owner, amount_);
            return true;
        }
    }

    function burnFrom(
        address user_,
        uint256 amount_
    )
        public
    returns(bool success) {
        require(allowToBurn(msg.sender));
        if(balances[user_] >= amount_ && allowed[user_][msg.sender] >= amount_ && amount_ > 0) {
            balances[user_] = safeSub(balances[user_], amount_);
            totalSupply = safeSub(totalSupply, amount_);
            allowed[user_][msg.sender] = safeSub(allowed[user_][msg.sender], amount_);
            emit Transfer(user_, owner, amount_);
            emit Burn(owner, amount_);
            return true;
        }
    }

    function getDefaultExchangeRate(
    )
        public
        view
    returns(uint256) {
        return defaultExchangeRate;
    }

    function getSymbol(
    )
        public
        view
    returns(bytes32) {
        return keccak256(symbol);
    }

    function assignBurner(
        address account_
    )
        public
        onlyOperator
    {
        require(account_ != address(0));
        for(uint256 i = 0; i < burners.length; i++) {
            if(burners[i] == account_) {
                return;
            }
        }
        burners.push(account_);
    }

    function dismissBunner(
        address account_
    )
        public
        onlyOperator
    {
        require(account_ != address(0));
        for(uint256 i = 0; i < burners.length; i++) {
            if(burners[i] == account_) {
                burners[i] = burners[burners.length - 1];
                burners.length -= 1;
            }
        }
    }

    function allowToBurn(
        address account_
    )
        public
        view
    returns(bool) {
        if(checkOperator(account_)) {
            return true;
        }
        for(uint256 i = 0; i < burners.length; i++) {
            if(burners[i] == account_) {
                return true;
            }
        }
    }
}
function XPAAssetToken(
    string symbol_,
    string name_,
    uint256 defaultExchangeRate_
)
    public
{
    totalSupply = 0;
    symbol = symbol_;
    name = name_;
    defaultExchangeRate = defaultExchangeRate_ > 0 ? defaultExchangeRate_ : 0.01 ether;
}

// constructor