function executeOffset(
        address user_,
        uint256 xpaAmount_,
        address xpaAssetToken,
        uint256 feeRate
    )
        internal
    returns(uint256){
        uint256 fromXPAAsset = safeDiv(safeMul(xpaAmount_,getPrice(xpaAssetToken)),1 ether);
        uint256 userToAmount = toAmountBooks[user_][xpaAssetToken];
        uint256 fee = safeDiv(safeMul(userToAmount, feeRate), 1 ether);
        uint256 burnXPA;
        uint256 burnXPAAsset;
        if(fromXPAAsset >= safeAdd(userToAmount, fee)){
            burnXPA = safeDiv(safeMul(safeAdd(userToAmount, fee), 1 ether), getPrice(xpaAssetToken));
            emit eExecuteOffset(burnXPA, xpaAssetToken, safeAdd(userToAmount, fee));
            xpaAmount_ = safeSub(xpaAmount_, burnXPA);
            toAmountBooks[user_][xpaAssetToken] = 0;
            profit = safeAdd(profit, safeDiv(safeMul(fee,1 ether), getPrice(xpaAssetToken)));
            if(
                !FundAccount(fundAccount).burn(xpaAssetToken, userToAmount)
            ){
                unPaidFundAccount[xpaAssetToken] = safeAdd(unPaidFundAccount[xpaAssetToken],userToAmount);
            }

        }else{
            
            fee = safeDiv(safeMul(xpaAmount_, feeRate), 1 ether);
            profit = safeAdd(profit, fee);
            burnXPAAsset = safeDiv(safeMul(safeSub(xpaAmount_, fee),getPrice(xpaAssetToken)),1 ether);
            toAmountBooks[user_][xpaAssetToken] = safeSub(userToAmount, burnXPAAsset);
            emit eExecuteOffset(xpaAmount_, xpaAssetToken, burnXPAAsset);
            
            xpaAmount_ = 0;
            if(
                !FundAccount(fundAccount).burn(xpaAssetToken, burnXPAAsset)
            ){
                unPaidFundAccount[xpaAssetToken] = safeAdd(unPaidFundAccount[xpaAssetToken], burnXPAAsset);
            }
            
        }
        return xpaAmount_;
    }