scam token - cannot be sold/swapped

6.1k Views Asked by At

Recently I bought a token from pancakeswap. Looks, like it's scammed - it's new, there are only buy operations, and no sell operations. And I also cannot swap it back.

I'm providing its contract source code and would be happy if someone explains why it cannot be sold:

#
#  Panoramix v4 Oct 2019 
#  Decompiled source of bsc:0xEF45178482b5868668D4ae8f2556D4F23c4Ffe51
# 
#  Let's make the world open source 
# 

def storage:
  owner is addr at storage 0
  newOwner is addr at storage 1
  symbol is array of uint256 at storage 2
  name is array of uint256 at storage 3
  decimals is uint8 at storage 4
  stor5 is uint256 at storage 5
  unknown1ee59f20Address is addr at storage 6
  balanceOf is mapping of uint256 at storage 7
  allowance is mapping of uint256 at storage 8

def name(): # not payable
  return name[0 len name.length]

def unknown1ee59f20(): # not payable
  return unknown1ee59f20Address

def decimals(): # not payable
  return decimals

def balanceOf(address _owner): # not payable
  require calldata.size - 4 >= 32
  return balanceOf[addr(_owner)]

def owner(): # not payable
  return owner

def symbol(): # not payable
  return symbol[0 len symbol.length]

def newOwner(): # not payable
  return newOwner

def allowance(address _owner, address _spender): # not payable
  require calldata.size - 4 >= 64
  return allowance[addr(_owner)][addr(_spender)]

#
#  Regular functions
#

def _fallback() payable: # default function
  revert

def totalSupply(): # not payable
  require balanceOf[0] <= stor5
  return (stor5 - balanceOf[0])

def transferOwnership(address _newOwner): # not payable
  require calldata.size - 4 >= 32
  require caller == owner
  newOwner = _newOwner

def unknown81f4f399(addr _param1): # not payable
  require calldata.size - 4 >= 32
  require caller == owner
  unknown1ee59f20Address = _param1

def acceptOwnership(): # not payable
  require caller == newOwner
  log OwnershipTransferred(
        address previousOwner=owner,
        address newOwner=newOwner)
  owner = newOwner
  newOwner = 0

def approve(address _spender, uint256 _value): # not payable
  require calldata.size - 4 >= 64
  allowance[caller][addr(_spender)] = _value
  log Approval(
        address owner=_value,
        address spender=caller,
        uint256 value=_spender)
  return 1

def transfer(address _to, uint256 _value): # not payable
  require calldata.size - 4 >= 64
  if unknown1ee59f20Address == _to:
      revert with 0, 'Please wait'
  require _value <= balanceOf[caller]
  balanceOf[caller] -= _value
  require _value + balanceOf[_to] >= balanceOf[_to]
  balanceOf[addr(_to)] = _value + balanceOf[_to]
  log Transfer(
        address from=_value,
        address to=caller,
        uint256 value=_to)
  return 1

def approveAndCall(address _spender, uint256 _amount, bytes _extraData): # not payable
  require calldata.size - 4 >= 96
  require _extraData <= 4294967296
  require _extraData + 36 <= calldata.size
  require _extraData.length <= 4294967296 and _extraData + _extraData.length + 36 <= calldata.size
  allowance[caller][addr(_spender)] = _amount
  mem[ceil32(_extraData.length) + 128] = _amount
  log Approval(address owner, address spender, uint256 value):
               Mask(8 * -ceil32(_extraData.length) + _extraData.length + 32, 0, 0),
               mem[_extraData.length + 160 len -_extraData.length + ceil32(_extraData.length)],
               caller,
               _spender,
  require ext_code.size(_spender)
  call _spender with:
       gas gas_remaining wei
      args caller, _amount, this.address, Array(len=_extraData.length, data=_extraData[all])
  if not ext_call.success:
      revert with ext_call.return_data[0 len return_data.size]
  return 0, 1

def transferFrom(address _from, address _to, uint256 _value): # not payable
  require calldata.size - 4 >= 96
  if not _from:
      if unknown1ee59f20Address == _to:
          revert with 0, 'Please wait'
  else:
      if unknown1ee59f20Address:
          if unknown1ee59f20Address == _to:
              revert with 0, 'Please wait'
      else:
          unknown1ee59f20Address = _to
  require _value <= balanceOf[addr(_from)]
  balanceOf[addr(_from)] -= _value
  require _value <= allowance[addr(_from)][caller]
  allowance[addr(_from)][caller] -= _value
  require _value + balanceOf[addr(_to)] >= balanceOf[addr(_to)]
  balanceOf[addr(_to)] += _value
  log Transfer(
        address from=_value,
        address to=_from,
        uint256 value=_to)
  return 1

I would greately appreciate for any help to swap it back and return back my investment.

1

There are 1 best solutions below

1
Iñigo González On

This contract blacklists the last address that sent tokens from a contract.

What does it mean?

This means if you buy tokens from a DeFi contract pool (like Pancake swap / uniswap, 1Inch, etc) you cannot sell through them immediately (transfer the tokens) because the pool address will be blacklisted.

If you want to sell that tokens, you can either:

  • Sell them in a different Defi exchange (if it was Pancakeswap, make it uniswap or 1inc, etc.).
  • Or create a contract that hold the tokens for you and then release them. This will (not reccomended).

How they do it?

The contract contains a variable that stores an address. It reverts all operations from that address.

It the last address that he received tokens with TransferFrom:

def storage:
  ...
  unknown1ee59f20Address is addr at storage 6
  ...

When someone buy tokens from a pool like PancakeSwap / Uniswap it calls the transferFrom method it records the last address that received the tokens.

def transferFrom(address _from, address _to, uint256 _value): # not payable
  require calldata.size - 4 >= 96
  if not _from:
      if unknown1ee59f20Address == _to:
          revert with 0, 'Please wait'
  else:
      if unknown1ee59f20Address:
          if unknown1ee59f20Address == _to:
              revert with 0, 'Please wait'
      else:
          unknown1ee59f20Address = _to   # <-- Address Blacklisted HERE !!!!

Since this contract stores just one addess globally, using a different contract will overwrite this variable.