Analise smart-contract
07.08.2024

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:

  1. 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.
  2. Valaki megpróbálta manipulálni a pool-t, ami miatt a token szaldók megváltoztak, megkerülve a standard swap folyamatot.
  3. 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:

  1. 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).
  2. 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.
  3. A token kontraktus nem implementálhatja a transferFrom funkciót, vagy helytelenül implementálhatja.
  4. 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.
  5. Ha nincs elegendő gáz a tranzakció végrehajtásához, a tranzakció meghiúsulhat.

Megoldás:

  1. 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.
  2. Győződjön meg arról, hogy az from cím rendelkezik elegendő tokennel az átvitel végrehajtásához.
  3. Ellenőrizze, hogy a token kontraktus címe helyes és a kontraktus ERC-20 kompatibilis.
  4. 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.
  5. 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:

  1. A likviditási pool nem tartalmaz elegendő mennyiségű egy vagy mindkét tokenből a kért csere teljesítéséhez.
  2. A kért token mennyiség visszavonásához (amount0Out vagy amount1Out) meghaladja a pool-ban elérhető tokenek számát.
  3. 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:

  1. 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.
  2. 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.
  3. 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.

INSUFFICIENT_LIQUIDITY

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:

  1. A token kontraktus nem tartalmazhatja az `approve` funkciót, vagy az helytelenül van implementálva.
  2. Lehet, hogy probléma van a token kontraktus állapotával, például elégtelen egyenleggel vagy engedéllyel.
  3. Az `approve` funkció visszavonhat, ha biztonsági okokból van implementálva a token kontraktusban.

Megoldás:

  1. Biztosítsa, hogy a token kontraktus megfelel az ERC-20 szabványnak és tartalmaz egy helyesen implementált `approve` funkciót.
  2. 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.
  3. Ellenőrizze, hogy az `safeApprove` funkcióhoz átadott cím és mennyiség helyes-e.
  4. 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:

  1. Biztosítsa, hogy `y` értéke mindig kisebb vagy egyenlő legyen `x`-szel a kivonás végrehajtása előtt.
  2. 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:

  1. 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.
  2. Ellenőrizze az aktuális engedélyezést, mielőtt megpróbálja végrehajtani a `transferFrom` műveletet.
  3. 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:

  1. A `token.call` funkció nem hajtódik végre sikeresen (azaz `success` értéke `false`).
  2. 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:

  1. 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.
  2. 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.
  3. 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).

INSUFFICIENT_LIQUIDITY

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:

  1. A piaci volatilitás, amely befolyásolja a tokenek árát a tranzakció kezdeményezése és végrehajtása között.
  2. Magas csúszás beállítások, amelyek jelentős eltéréseket engednek meg a várt kimenetekben.
  3. Elégtelen likviditás a kereskedési poolban, ami nagyobb árhatásokat okoz.

Megoldás:

  1. 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.
  2. 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.
  3. 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:

  1. Helytelen bemeneti paraméterek a swap funkcióhoz.
  2. Elégtelen alapok a felhasználó számláján.
  3. Hibák a bemeneti összegek kiszámításában.

Megoldás:

  1. 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.
  2. 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:

  1. A tranzakció nem hajtható végre, mert nincs elegendő gáz az összes művelet befejezéséhez.
  2. 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).
  3. Kísérlet token vagy kriptovaluta tranzakció végrehajtására, amikor a számla egyenlege nem elegendő.
  4. ERC-20 és ERC-721 szabványú tokenek esetén a tranzakció meghiúsulhat az elégtelen jogosultságok miatt.
  5. 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:

  1. Emelje meg a gázlimitet a tranzakció küldésekor.
  2. Vizsgálja meg a feltételeket és a logikát az okos szerződésben.
  3. Győződjön meg arról, hogy a számla elegendő pénzeszközzel rendelkezik a tranzakció végrehajtásához.
  4. Hívja meg az `approve` funkciót megfelelő értékkel, mielőtt a `transferFrom`-ot hívná.
  5. Vizsgálja meg a tranzakció visszavonásához vezető feltételeket.
  6. 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

Connect to a wallet

Metamask