function doTrade( ERC20 sourceToken,
                      uint sourceAmount,
                      ERC20 destToken,
                      address destAddress,
                      bool validate ) internal returns(bool) {

        
        if( validate ) {
            if( ! isPairListed( sourceToken, destToken, block.number ) ) {
                
                ErrorReport( tx.origin, 0x800000001, 0 );
                return false;

            }
            if( sourceToken == ETH_TOKEN_ADDRESS ) {
                if( msg.value != sourceAmount ) {
                    
                    ErrorReport( tx.origin, 0x800000002, msg.value );
                    return false;
                }
            }
            else if( msg.value > 0 ) {
                
                ErrorReport( tx.origin, 0x800000003, msg.value );
                return false;
            }
            else if( sourceToken.allowance(msg.sender, this ) < sourceAmount ) {
                
                ErrorReport( tx.origin, 0x800000004, sourceToken.allowance(msg.sender, this ) );
                return false;
            }
        }

        uint conversionRate = getConversionRate( sourceToken, destToken, block.number );
        
        uint destAmount = (conversionRate * sourceAmount) / PRECISION;

        
        if( destAmount == 0 ) {
            
            ErrorReport( tx.origin, 0x800000005, 0 );
            return false;
        }

        
        if( destToken == ETH_TOKEN_ADDRESS ) {
            if( this.balance < destAmount ) {
                
                ErrorReport( tx.origin, 0x800000006, destAmount );
                return false;
            }
        }
        else {
            if( destToken.balanceOf(this) < destAmount ) {
                
                ErrorReport( tx.origin, 0x800000007, uint(destToken) );
                return false;
            }
        }

        
        if( sourceToken != ETH_TOKEN_ADDRESS ) {
            if( ! sourceToken.transferFrom(msg.sender,this,sourceAmount) ) {
                
                ErrorReport( tx.origin, 0x800000008, uint(sourceToken) );
                return false;
            }
        }

        
        if( destToken == ETH_TOKEN_ADDRESS ) {
            if( ! destAddress.send(destAmount) ) {
                
                ErrorReport( tx.origin, 0x800000009, uint(destAddress) );
                return false;
            }
        }
        else {
            if( ! destToken.transfer(destAddress, destAmount) ) {
                
                ErrorReport( tx.origin, 0x80000000a, uint(destAddress) );
                return false;
            }
        }

        DoTrade( tx.origin, sourceToken, sourceAmount, destToken, destAmount, destAddress );

        return true;
    }