Aby wyłapać crypto drainera albo rug pulla zanim stracisz środki, prześwietl smart kontrakt na BscScan lub Etherscan pod kątem niezweryfikowanego kodu, ukrytych funkcji mint() czy podatków od sprzedaży (sell tax) przekraczających 10%. Zawsze przepuszczaj adresy kontraktów przez automatyczne skanery, takie jak Token Sniffer, DEXScreener czy GoPlus Security, aby zweryfikować zrzeczenie się praw do kontraktu (ownership renunciation) oraz czas blokady płynności. Na koniec zabezpiecz swój portfel przed drainerami opartymi na podpisach — odrzucaj ślepe żądania eth_sign, Permit2 oraz setApprovalForAll i symuluj każdą transakcję za pomocą narzędzi typu Rabby Wallet czy Pocket Universe.
Siema wszystkim! Z tej strony Oleg Filatov. Ostatnie trzy lata spędziłem na utrzymywaniu przy życiu infrastruktury giełdy, walcząc z każdym możliwym wektorem on-chainowego oszustwa. Wcześniej łamałem smart kontrakty na audytach bezpieczeństwa i zarywałem nocki na hackathonach Web3. Żyję tym na co dzień — szczerze mówiąc, nie ma nic lepszego niż zastrzyk adrenaliny o 2:00 w nocy, gdy robisz inżynierię wsteczną złośliwego bajtkodu i nagle dociera do Ciebie, jak dokładnie ktoś próbował wykręcić exploit na grube miliony dolarów.
Wskakujmy więc w temat — zobaczmy, jak uchronić Twój portfel przed minami, którymi gęsto usłana jest dzisiejsza przestrzeń Web3.
1. Szybkie porównanie: Honeypot vs. Rug Pull vs. Wallet Drainer
| Typ scamem | Jak to działa | Główna czerwona flaga | Podstawowe narzędzie do detekcji |
|---|---|---|---|
| Honeypot | Smart kontrakt pozwala swobodnie kupować tokeny, ale blokuje wywołania sprzedaży przez ukrytą logikę lub warunkowe revert-y. | Podatek od sprzedaży 100%, błąd TRANSFER_FAILED przy swapie na DEX-ie lub zero transakcji sprzedaży w ostatniej historii. | Token Sniffer / DEXScreener |
| Rug Pull | Deweloperzy wrzucają płynność, pompują hype na token, a potem wyciągają wszystkie tokeny LP albo zrzucają swój przydział w cenowy dół. | Nieprzejęta/odblokowana płynność, blokada LP poniżej 6 miesięcy albo portfel deva trzymający >10% całkowitej podaży. | DEXTools / Uncx Network |
| Wallet Drainer | Phishingowa strona podstępem skłania Cię do podpisania wiadomości off-chain lub transakcji typu allowance, dającej pełny dostęp do portfela. | Żądania podpisów eth_sign, Permit2 lub setApprovalForAll na niesprawdzonych dAppach. | Pocket Universe / Rabby Wallet |
2. Krok po kroku: Checklist bezpieczeństwa przed zakupem jakiegokolwiek tokena
Krok 1: Automatyczny skan kontraktu
Przepuść adres tokena przez Token Sniffera, API GoPlus Security i DEXScreenera. Jeśli DEXScreener pokazuje 800 transakcji kupna i dosłownie zero sprzedaży w ciągu 4 godzin — zatrzymaj się. To honeypot. Kropka.
Krok 2: Czas blokady płynności (Liquidity Lock)
Prawilny zespół blokuje swoje tokeny puli płynności (LP) przez protokoły takie jak Uncx Network czy PinkSale.
- Czerwona flaga: Płynność jest odblokowana, trzymana na EOA (Externally Owned Account) lub zablokowana na mniej niż 6 miesięcy.
- Zielona flaga: Tokeny LP zostały spalone (wysłane pod adres 0x000000000000000000000000000000000000dead) albo zablokowane w zweryfikowanym kontrakcie na co najmniej rok.
Krok 3: Sprawdzenie dystrybucji i praw własności
Zajrzyj do zakładki Holders na Etherscanie lub BscScanie.
Jeśli garść niegiełdowych i niespalonych portfeli kontroluje ponad 5–10% całkowitej podaży, to gratulacje — jesteś dla nich płynnością wyjściową (exit liquidity). Sprawdź też, czy właściciel zrzekł się praw do kontraktu (renounced ownership). Jeśli nie, właściciel może w dowolnym momencie samowolnie zmienić podatki, wrzucić Twój adres na czarną listę albo wstrzymać transfery, kiedy tylko przyjdzie mu na to ochota.
Krok 4: Audyt transakcji i podpisów
Nigdy nie podpisuj transakcji w ciemno. Nowoczesne drainery portfeli rzadko proszą już o zwykłe transfery ETH — zamiast tego wykorzystują podpisy off-chain, takie jak EIP-712, Permit2 czy EIP-2612, by ominąć standardowe ostrzeżenia portfela. Używaj wtyczek do dynamicznej symulacji transakcji, aby sprawdzić zmiany stanu (state changes) przed wysłaniem ich do sieci.
3. Głęboka analiza bezpieczeństwa i mechanika kodu
Pogadajmy o twardych konkretach technicznych. Dlaczego tradycyjne analizatory statyczne przepuszczają wyrafinowane scamy? Bo scammerzy piszą logikę uwzględniającą kontekst (context-aware).
Chwila... dlaczego ludzie wciąż myślą, że weryfikacja kodu na Etherscanie gwarantuje bezpieczeństwo? Zadaję sobie to pytanie za każdym razem, gdy ktoś płacze, że stracił kasę na „zweryfikowanym” projekcie. Weryfikacja kodu źródłowego dowodzi jedynie, że wdrożony bajtkod EVM zgadza się z przesłanymi plikami Solidity. Nie mówi kompletnie NIC o tym, czy logika wewnątrz tych plików jest uczciwa, czy złośliwa!
Sztuczka na Honeypota: Gas-Griefing i dynamiczne podatki
Popularna technika w honeypotach polega na ustawieniu standardowej opłaty 2% przy starcie, a potem wyśrubowaniu jej do 99% wewnątrz funkcji _transfer(), gdy tylko do puli wpadnie odpowiednio dużo płynności.
Jeszcze gorsze są honeypoty stosujące dynamiczny gas-griefing:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/*
* Moja szybka replika logiki honeypota odtworzona na bazie inżynierii wstecznej z "dziczy".
* NIE WDRAŻAJ TEGO. To służy wyłącznie do celów edukacyjnych.
*/
contract SneakyHoneypot {
address private _owner;
mapping(address => bool) private _isWhitelisted;
mapping(address => uint256) private _balances;
constructor() {
_owner = msg.sender;
_isWhitelisted[msg.sender] = true;
}
function transfer(address to, uint256 amount) public returns (bool) {
_transfer(msg.sender, to, amount);
return true;
}
function _transfer(address from, address to, uint256 amount) internal {
require(_balances[from] >= amount, "ERC20: balance too low");
// Jeśli to zlecenie sprzedaży (transfer na adres pary) i nadawca nie jest na białej liście
if (!_isWhitelisted[from] && !_isWhitelisted[to]) {
// Trik: Przepalamy gigantyczne ilości gazu używając nieskończonej pętli lub ciężkiej alokacji pamięci,
// co powoduje wywalenie transakcji kupującego błędem "Out of Gas"!
assembly {
let m := mload(0x40)
mstore(m, 0xdeadbeef)
// Sztucznie palimy gaz przy próbach sprzedaży
invalid()
}
}
_balances[from] -= amount;
_balances[to] += amount;
}
}Widzisz, co tu się dzieje? Kiedy kupujesz, wszystko przechodzi bez problemu. Ale w momencie, gdy puszczasz wywołanie swapExactTokensForETH na Uniswapie, kontrakt sprawdza, czy Twój portfel jest na białej liście. Jeśli nie jest, wykonuje opkod invalid() albo wchodzi w nieskończoną pętlę, zżerając cały przydzielony gaz i cofając (revert) transakcję z enigmatycznym błędem. Większość inwestorów detalicznych myśli wtedy: „Ehh, pewnie za mały slippage” i odpuszcza, podczas gdy dev powoli czyści całą pulę.
4. Jak wallet drainery omijają zabezpieczenia Web3
Omówmy teraz exploity oparte na podpisach off-chain — a konkretnie nadużycia Permit2 i EIP-712.
Tradycyjne zgody (allowances) wymagają wysłania transakcji on-chain wywołującej approve(spender, amount). To kosztuje gaz i wywołuje czytelne okienko w interfejsie portfela z ostrzeżeniem.
Skrypty drainerów omijają ten krok, wykorzystując standard Permit2 od Uniswapa albo zgody EIP-2612. Złośliwa dAppka prosi Cię o podpisanie pozornie niegroźnego ciągu danych podpisem Twojego portfela (eth_signTypedData_v4). Za kulisami ten podpis cyfrowy daje smart kontraktowi napastnika pełne upoważnienie do wyciągnięcia Twoich tokenów ERC-20 lub NFT z konta — bez potrzeby jakiejkolwiek kolejnej weryfikacji on-chain z Twojej strony!
// Przykładowy złośliwy payload skonstruowany przez skrypty drainera
const domain = {
name: 'Permit2',
chainId: 1, // Mainnet
verifyingContract: '0x000000000022D473030F116dDEE9F6B43aC78BA3' // Oficjalny adres Uniswap Permit2
};
const types = {
PermitSingle: [
{ name: 'details', type: 'PermitDetails' },
{ name: 'spender', type: 'address' },
{ name: 'sigDeadline', type: 'uint256' }
],
PermitDetails: [
{ name: 'token', type: 'address' },
{ name: 'amount', type: 'uint160' },
{ name: 'expiration', type: 'uint48' },
{ name: 'nonce', type: 'uint48' }
]
};
// Użytkownik myśli, że loguje się na stronę, a w rzeczywistości podpisuje zgodę na maks. balans tokenów:
const value = {
details: {
token: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC
amount: "1461501637330902918203684832716283019655932542975", // Maksymalna wartość uint160
expiration: 2000000000,
nonce: 0
},
spender: "0xMaliciousAttackerContractAddressHere...",
sigDeadline: 2000000000
};Jeśli podpiszesz taki payload, napastnik bierze ten podpis off-chain, sam wysyła go do kontraktu Permit2, płaci opłatę za gaz i w ułamku sekundy czyści Twoje USDC.
5. Inżynieria wsteczna bajtkodu EVM: Jak wykryć scam bez kodu źródłowego
Co się dzieje, gdy nowy token nie jest jeszcze zweryfikowany na Etherscanie ani BscScanorze? Większość ludzi wieje, gdzie pieprz rośnie. Ale dla mnie – jako CTO i byłego audytora bezpieczeństwa – niezweryfikowany bajtkod to moment, w którym zaczyna się prawdziwa zabawa. Wcale nie potrzebujesz oryginalnego kodu źródłowego w Solidity, żeby ogarnąć, czy kontrakt próbuje Cię opylić z kasy.
Gdy deweloperzy kompilują kod Solidity do bajtkodu EVM, nazwy funkcji zamieniają się w 4-bajtowe identyfikatory zwane selektorami funkcji (Function Selectors) – czyli pierwsze 4 bajty hasha Keccak-256 z sygnatury funkcji.
Dla przykładu, transfer(address,uint256) zawsze daje po hashowaniu 0xa9059cbb.
Jeśli wkleisz bajtkod niezweryfikowanego kontraktu do narzędzia typu Dedaub Bytecode Decompiler albo ethervm.io, uderzaj od razu do dyspozytora selektorów (selector dispatcher) albo szukaj w surowym bajtkodzie takich oto podejrzanych hashów funkcji:
0x40c10f19 -> mint(address,uint256)
0xbf8b0f72 -> enableTrading() / setTradingStatus(bool)
0x0283c741 -> setFee(uint256)
0xe47d6060 -> setBlacklist(address,bool)Zaraz, zaraz... po co w ogóle przejmować się akurat tymi sygnaturami? A no dlatego, że jeśli niezweryfikowany kontrakt tokena ma w sobie 0x40c10f19 (mint), a owner nie został zrzeczony (renounced), deweloper może po cichu dodrukować 10 miliardów tokenów z powietrza prosto na swój prywatny portfel, zrzucić je na Uniswapie i wyssać całą płynność w ułamku sekundy.
Oto prosty skrypt w Pythonie z wykorzystaniem web3.py, którego używam wewnętrznie do skanowania bajtkodu niezweryfikowanych kontraktów pod kątem niebezpiecznych uprawnień admina, zanim w ogóle dotknę jakiegokolwiek tokena:
# Wewnętrzny skrypt bezpieczeństwa do wykrywania niebezpiecznych sygnatur funkcji w niezweryfikowanym bajtkodzie EVM.
# Napisany na potrzeby szybkiej, automatycznej weryfikacji podczas analizy smart kontraktów.
from web3 import Web3
# Połączenie z publicznym węzłem RPC
w3 = Web3(Web3.HTTPProvider('https://eth.llamarpc.com'))
# Znane, ryzykowne 4-bajtowe selektory funkcji (hashe Keccak-256)
DANGEROUS_SELECTORS = {
"0x40c10f19": "mint(address,uint256)",
"0xe47d6060": "setBlacklist(address,bool)",
"0x8a8c523c": "preventSell(address)",
"0x70480932": "pauseTrading()"
}
def analyze_bytecode(contract_address: str):
# Pobranie surowego bajtkodu z łańcucha
code = w3.eth.get_code(Web3.to_checksum_address(contract_address)).hex()
if code == '0x' or len(code) <= 2:
print("[-] Podany adres nie posiada wdrożonego kodu kontraktu (to adres EOA).")
return
print(f"[+] Analiza bajtkodu EVM dla: {contract_address}")
found_flags = []
for selector, func_name in DANGEROUS_SELECTORS.items():
# Usunięcie prefiksu '0x' na potrzeby dopasowania w surowym ciągu hex
clean_selector = selector[2:]
if clean_selector in code:
found_flags.append(func_name)
if found_flags:
print("[!] CZERWONA FLAGA! Wykryto niebezpieczne funkcje w bajtkodzie:")
for flag in found_flags:
print(f" - {flag}")
else:
print("[+] Standardowy skan nie wykrył ukrytych selektorów funkcji administratorskich.")
# Przykładowe użycie z dowolnym adresem
# analyze_bytecode("0x...")6. Zaawansowane taktyki drainerów: Zatruwanie approvali i Address Poisoning
Oszuści nie polegają już tylko na poolach płynności na DEX-ach. Teraz celują bezpośrednio w Twoje środki na portfelu, wykorzystując luki w UX oraz sztuczki socjotechniczne.
Ataki typu Address Poisoning (Zatruwanie adresów)
Zdarzyło Ci się kiedyś przeglądać historię portfela i trafić na transfer 0 ETH albo 0.0001 tokena z adresu, który wygląda niemal identycznie jak Twój własny?
To właśnie Address Poisoning.
Skrypty atakujące monitorują mempool w poszukiwaniu transakcji z portfeli o dużej wartości. Następnie generują tzw. vanity address za pomocą generatorów GPU (np. Profanity) – taki adres ma dokładnie te same pierwsze 4-5 i ostatnie 4-5 znaków co Twój portfel (lub adres, na który często wysyłasz krypto).
Potem wysyłają na Twój portfel transakcję o wartości zerowej przy użyciu transferFrom().
Jaki jest cel? Chodzi o to, żeby ich fałszywy adres pojawił się w Twojej historii ostatnich transakcji. Następnym razem, gdy otworzysz portfel, żeby wysłać środki, zamiast wpisywać adres z palca czy sprawdzać każdy znak, skopiujesz adres z samej góry historii... i nieświadomie wyślesz swoje ETH prosto do oszusta.
Złota zasada: Nigdy nie kopiuj adresów portfeli z historii transakcji! Zawsze kopiuj je z zapisanych zakładek, domen ENS albo weryfikuj bezwzględnie każdy znak adresu.
7. Ostateczny checklist do utwardzenia Twojej ochrony on-chain
Aby bezpiecznie poruszać się po dzisiejszym Web3 i nie stracić aktywów, wdróż ten zestaw dobrych praktyk bezpieczeństwa (SecOps):
- Rozdziel portfele sprzętowe do interakcji i do przechowywania: Miej dedykowany zimny portfel (Ledger, Trezor, Keystone), który nigdy nie łączy się z dAppami, nie podpisuje żadnych wiadomości ani nie odbiera airdropów. Do codziennych swapów i zabawy z nowymi protokołami DeFi używaj osobnego "portfela na straty" (burn-wallet) z minimalną ilością środków.
- Odrzucaj podpisanie "w ciemno" wiadomości off-chain: Wyłącz opcję "blind signing" na swoim urządzeniu sprzętowym, kiedy tylko się da. Jeśli dApp wymaga
eth_signalbo nieczytelnego ciągu hex, którego nie jesteś w stanie rozszyfrować, natychmiast odrzuć taką prośbę. - Ustawiaj własne limity wydatków (Allowance): Zatwierdzając limit wydatków dla tokenów ERC-20 na Uniswapie czy 1inch, nigdy nie wybieraj opcji "Unlimited". Ręcznie ustawiaj allowance dokładnie na taką kwotę, jaką zamierzasz przehandlować. Dzięki temu, nawet jeśli protokół zostanie później zhakowany, Twoje pozostałe tokeny będą bezpieczne.
- Regularne czyszczenie uprawnień: Ustaw sobie przypomnienie w kalendarzu na 1. dzień każdego miesiąca, aby wpaść na Revoke.cash lub Token Approval Checker na Etherscanie i cofnąć przestarzałe lub nieużywane uprawnienia w sieciach (Ethereum, Arbitrum, Solana, Base, BSC).
Dobra, myślę, że to wyczerpuje wszystkie najważniejsze mechaniki! Jeśli natrafiłeś na jakiś podejrzany kontrakt, masz pytania do snippetów kodu albo potrzebujesz pomocy przy rozłożeniu na czynniki pierwsze dziwnego hasha transakcji — uderzaj śmiało w komentarzach poniżej. Postaram się wpaść i na wszystko odpowiedzieć!