Az ERC-20 intelligens szerződések gyakori hibáinak megértése Solidityben
Az Ethereum ökoszisztémájában a smart contractok gyakran bonyolult logikát tartalmaznak, hogy biztosítsák a decentralizált alkalmazások biztonságát és működőképességét. Azonban különböző okok miatt hibák léphetnek fel, amelyek sikertelen tranzakciókhoz és potenciális sebezhetőségekhez vezethetnek. Ez a blogbejegyzés néhány gyakori hibát fog vizsgálni, amelyek ERC-20 token tranzakciók során előfordulhatnak, azok okait és megoldásait.
1. Pancake: K
Az hiba akkor lép fel, ha a 'a tartalékok szorzata állandó' invariáns megsértésre kerül. Ez a feltétel garantálja, hogy a swap végrehajtása után az új tartalékok szorzata (a jutalékokat is beleértve) nem lesz kisebb, mint a régi szorzat. Az invariáns megsértése akkor fordulhat elő, ha:
- A poolba bevitt tokenek (amount0In vagy amount1In) nem felelnek meg az invariáns képlet szerinti elvárt értékeknek. Hiba történt a szaldók számításakor a swap után.
- Valaki megpróbálta manipulálni a pool-t, ami miatt a token szaldók megváltoztak, megkerülve a standard swap folyamatot.
- Ha ez a feltétel nem teljesül, akkor a 'Pancake: K' hiba lép fel, jelezve a matematikai invariáns megsértését.
Az invariáns megsértése azt jelenti, hogy az alapvető feltételek egyike, amely biztosítja a rendszer helyes működését, már nem teljesül. A PancakeSwap-hoz hasonló decentralizált cserék kontextusában az invariáns általában egy matematikai egyenlethez kapcsolódik, amelynek igaznak kell maradnia a likviditási pool token tartalékainak egyensúlyának fenntartásához.
require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(10000**2), 'Pancake: K');
Megoldás:
Ellenőrizze, hogy a pool rendelkezik-e elegendő likviditással a csere végrehajtásához, és hogy az értékek nem haladják-e meg a tartalékokat (_reserve0, _reserve1). Folyamatosan figyelje a pool tartalékait, és tegye meg a szükséges lépéseket azok feltöltésére, ha szükséges.
2. TransferHelper: TRANSFER_FROM_FAILED
Ez a hiba egy sikertelen token átvitelre utal a safeTransferFrom módszer használatával, amely egy gyakori minta az ERC-20 tokenek biztonságos átvitelére.
function safeTransferFrom(address token, address from, address to, uint value)
internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) =
token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper: TRANSFER_FROM_FAILED');
}
Ok:
- Az from cím nem adott engedélyt vagy nem adott elegendő engedélyt a msg.sender címnek a tokenek átvitelére (allowance, approve).
- Az from cím nem rendelkezik elegendő tokennel az átvitel végrehajtásához. Ez származhat abból is, hogy a token adminisztrátorok képesek módosítani a token egyenleget, és az eszköz visszavonásakor lehet, hogy a befektető nem rendelkezik elegendő egyenleggel a visszavonáshoz.
- A token kontraktus nem implementálhatja a transferFrom funkciót, vagy helytelenül implementálhatja.
- A token kontraktus tartalmazhat további ellenőrzéseket vagy korlátozásokat a transferFrom funkcióban, ami a tranzakció törléséhez vezethet.
- Ha nincs elegendő gáz a tranzakció végrehajtásához, a tranzakció meghiúsulhat.
Megoldás:
- Győződjön meg arról, hogy az from cím elegendő engedélyt adott a msg.sender cím számára. Ezt a token kontraktus allowance funkciójának hívásával lehet ellenőrizni.
- Győződjön meg arról, hogy az from cím rendelkezik elegendő tokennel az átvitel végrehajtásához.
- Ellenőrizze, hogy a token kontraktus címe helyes és a kontraktus ERC-20 kompatibilis.
- Ellenőrizze a transferFrom funkció implementációját a token kontraktusban. Győződjön meg arról, hogy helyesen van implementálva, és nincsenek olyan további korlátozások, amelyek hibát okozhatnak.
- Próbálja meg növelni a gáz limitet a tranzakció hívásakor, hogy megbizonyosodjon róla, hogy a probléma nem a gáz hiánya.
3. INSUFFICIENT_LIQUIDITY
Ez a hiba akkor fordul elő, amikor megpróbálunk több likviditást visszavonni, mint ami rendelkezésre áll egy likviditási pool tartalékaiban.
(uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
require(amount0Out < _reserve0 && amount1Out < _reserve1, 'Pancake:
INSUFFICIENT_LIQUIDITY');
Ok:
- A likviditási pool nem tartalmaz elegendő mennyiségű egy vagy mindkét tokenből a kért csere teljesítéséhez.
- A kért token mennyiség visszavonásához (amount0Out vagy amount1Out) meghaladja a pool-ban elérhető tokenek számát.
- Az összehangolatlanság a kontraktus tartalékai és a pool tényleges állapota között. A kontraktusban tárolt tartalékok nem biztos, hogy megegyeznek a pool tényleges token egyenlegével hibák vagy manipulációk miatt.
Megoldás:
- Ellenőrizze a pool tartalékait, és győződjön meg arról, hogy elegendőek a kért csere teljesítéséhez. Ezt a getReserves funkció használatával teheti meg.
- Győződjön meg arról, hogy az amount0Out és amount1Out paraméterek helyesek és nem haladják meg a pool-ban elérhető tokenek számát.
- Győződjön meg arról, hogy a kontraktusban lévő tartalékok megfelelnek a tényleges token egyenlegnek. Ehhez hozzáadhat ellenőrzéseket és frissítheti a tartalékokat a csere végrehajtása előtt.
4. APPROVE_FAILED
Az `APPROVE _FAILED` hiba az `safeApprove` funkció végrehajtása során lép fel. Ez a funkció arra szolgál, hogy beállítsa a tokenek számát, amelyet a tulajdonos engedélyez egy kiadónak, hogy a nevében használhassa.
function safeApprove(address token, address to, uint value) internal {
(bool success, bytes memory data) =
token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper: APPROVE_FAILED');
}
Ok:
- A token kontraktus nem tartalmazhatja az `approve` funkciót, vagy az helytelenül van implementálva.
- Lehet, hogy probléma van a token kontraktus állapotával, például elégtelen egyenleggel vagy engedéllyel.
- Az `approve` funkció visszavonhat, ha biztonsági okokból van implementálva a token kontraktusban.
Megoldás:
- Biztosítsa, hogy a token kontraktus megfelel az ERC-20 szabványnak és tartalmaz egy helyesen implementált `approve` funkciót.
- Ellenőrizze a token kontraktus állapotát, és győződjön meg arról, hogy a fióknak elegendő tokenje van az engedélyezéshez.
- Ellenőrizze, hogy az `safeApprove` funkcióhoz átadott cím és mennyiség helyes-e.
- További hibakeresés a token kontraktusban a konkrét hibaüzenet vagy ok ellenőrzésével.
5. Hiba 'ds-math-sub-underflow'
A `ds-math-sub-underflow` hiba akkor lép fel, amikor egy kivonási művelet alulfolyik, azaz amikor a kivonás eredménye kisebb, mint nulla.
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x, 'ds-math-sub-underflow');
}
Ok:
Ez a hiba azért fordul elő, mert a kivonási művelet `x - y` negatív számot eredményez, ami nem megengedett a Solidity-ben az aláíratlan egész számok számára.
Megoldás:
- Biztosítsa, hogy `y` értéke mindig kisebb vagy egyenlő legyen `x`-szel a kivonás végrehajtása előtt.
- Implementáljon ellenőrzéseket a kódjában, hogy kezelje azokat az eseteket, amikor `y` nagyobb lehet, mint `x`, és tegyen meg megfelelő lépéseket, például vonja vissza a tranzakciót vagy módosítsa a logikát.
6. Hiba: 'ERC20: a tranzakciós összeg meghaladja az engedélyezett mértéket'
Az 'ERC20: a tranzakciós összeg meghaladja az engedélyezett mértéket' hiba akkor lép fel, amikor megpróbálunk tokeneket átkonvertálni egy másik felhasználó nevében, de az átkonvertált összeg meghaladja az engedélyezett mértéket, amelyet a token tulajdonosa beállított a költő számára.
Oka:
Ezt a hibát az ERC-20 token kontraktus `transferFrom` funkciója dobja, amikor az átkonvertálandó összeg meghaladja a token tulajdonosa által beállított engedélyezett limitet.
Megoldás:
- Győződjön meg arról, hogy a token tulajdonosa megfelelő engedélyezést állított be a költő számára az `approve` funkció használatával.
- Ellenőrizze az aktuális engedélyezést, mielőtt megpróbálja végrehajtani a `transferFrom` műveletet.
- Szükség esetén kérje meg a token tulajdonosát, hogy növelje az engedélyezést a `approve` funkció magasabb értékkel történő hívásával.
7. TRANSFER_FAILED
Ez a hiba akkor fordul elő, amikor a tokenek átvitele egyik címről a másikra nem sikerül. Az `_safeTransfer` funkció biztosítja, hogy az átvitel sikeres legyen, és a visszaadott adat, ha van, dekódolódjon `true`-ra.
`function _safeTransfer(address token, address to, uint value) private { (bool
success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to,
value)); require(success && (data.length == 0 || abi.decode(data, (bool))),
'Pancake: TRANSFER_FAILED'); }`
Oka:
- A `token.call` funkció nem hajtódik végre sikeresen (azaz `success` értéke `false`).
- A hívás olyan adatokat ad vissza, amelyek nem dekódolódnak `true`-ra, ami a token kontraktus `transfer` funkciójának hibájára utal.
Megoldás:
- Biztosítsa az ERC-20 kompatibilitást: Ellenőrizze, hogy a token kontraktus megfelel-e az ERC-20 szabványnak, ami magában foglalja a `transfer` funkció helyes implementálását.
- Helyes paraméterek: Győződjön meg arról, hogy a `to` cím érvényes, és az `value` az engedélyezett határokon belül van, figyelembe véve a küldő egyenlegét és a kontraktus logikáját.
- További feltételek: Ellenőrizze, hogy a token kontraktus nem igényel-e további feltételeket, például az előzetes engedélyezést (`approve` és `allowance` funkciók).
8. INSUFFICIENT_OUTPUT_AMOUNT
Ez a hiba egy decentralizált csere esetén fordul elő, amikor a token swap kimeneti összeg kisebb, mint a felhasználó által megadott minimális összeg. Ez egy biztonsági intézkedés, hogy biztosítsa, hogy a felhasználók ne kapjanak kevesebb tokent, mint amire számítottak a tranzakció során előforduló csúszás vagy árváltozások miatt.
`require(amounts[amounts.length - 1] >= amountOutMin,
'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT');`
Oka:
- A piaci volatilitás, amely befolyásolja a tokenek árát a tranzakció kezdeményezése és végrehajtása között.
- Magas csúszás beállítások, amelyek jelentős eltéréseket engednek meg a várt kimenetekben.
- Elégtelen likviditás a kereskedési poolban, ami nagyobb árhatásokat okoz.
Megoldás:
- Biztosítsa az ERC-20 kompatibilitást: Ellenőrizze, hogy a token kontraktus megfelel-e az ERC-20 szabványnak, amely magában foglalja a `transfer` funkció helyes implementálását.
- Helyes paraméterek: Győződjön meg arról, hogy a `to` cím érvényes, és az `value` az engedélyezett határokon belül van, figyelembe véve a küldő egyenlegét és a kontraktus logikáját.
- További feltételek: Ellenőrizze, hogy a token kontraktus nem igényel-e további feltételeket, például az előzetes engedélyezést (`approve` és `allowance` funkciók).
9. INSUFFICIENT_INPUT_AMOUNT
Ez a hiba akkor fordul elő, amikor egyik bemeneti összeg sem nagyobb nulla értéknél a token swap során. Biztosítja, hogy legalább az egyik bemeneti összeg (`amount0In` vagy `amount1In`) pozitív legyen a swap folytatásához.
uint amount0In = ...; // Input amount of token0
uint amount1In = ...; // Input amount of token1
require(amount0In > 0 || amount1In > 0, 'Pancake: INSUFFICIENT_INPUT_AMOUNT');
Oka:
- Helytelen bemeneti paraméterek a swap funkcióhoz.
- Elégtelen alapok a felhasználó számláján.
- Hibák a bemeneti összegek kiszámításában.
Megoldás:
- Validálja a bemeneti összegeket: Győződjön meg arról, hogy a bemeneti összegek helyesen vannak beállítva a swap funkció hívása előtt. Ez magában foglalja a felhasználói bemenet érvényesítését és a paraméterek beállítását.
- Ellenőrizze a felhasználói egyenlegeket: Győződjön meg arról, hogy a felhasználónak elegendő egyenlege van a swap-hoz szánt tokenekből. Ezt a megfelelő token kontraktusok `balanceOf` funkciójának hívásával lehet ellenőrizni.
10. Hiba
Oka:
- A tranzakció nem hajtható végre, mert nincs elegendő gáz az összes művelet befejezéséhez.
- Helytelen logika vagy feltételek egy okos szerződésen belül végrehajtási hibákat okozhatnak (például egy `require` vagy `assert` hívás, amely meghiúsul).
- Kísérlet token vagy kriptovaluta tranzakció végrehajtására, amikor a számla egyenlege nem elegendő.
- ERC-20 és ERC-721 szabványú tokenek esetén a tranzakció meghiúsulhat az elégtelen jogosultságok miatt.
- Egy okos szerződés hívása visszavonható lehet, ha nem teljesíti a feltételeket (pl. a `revert` funkció használata).
Megoldás:
- Emelje meg a gázlimitet a tranzakció küldésekor.
- Vizsgálja meg a feltételeket és a logikát az okos szerződésben.
- Győződjön meg arról, hogy a számla elegendő pénzeszközzel rendelkezik a tranzakció végrehajtásához.
- Hívja meg az `approve` funkciót megfelelő értékkel, mielőtt a `transferFrom`-ot hívná.
- Vizsgálja meg a tranzakció visszavonásához vezető feltételeket.
- Ellenőrizze az egyenlegét a jutalékok miatt
Összegzés
Ezen gyakori hibák megértése és megoldása az ERC-20 okos szerződéseknél szilárd Solidity programozási ismereteket, az ERC-20 szabványt és a decentralizált tőzsdék belső működését igényli. A kiváltó okok gondos átnézésével és a javasolt megoldások alkalmazásával a fejlesztők robusztusabb és megbízhatóbb okos szerződéseket készíthetnek, biztosítva a zökkenőmentes élményt a felhasználók számára a decentralizált ökoszisztémában.
All posts