Analise smart-contract
07.08.2024

Gemeinsame ERC-20 Smart Contract-Fehler in Solidity verstehen

Smart Contracts im Ethereum-Ökosystem enthalten oft komplexe Logik, um die Sicherheit und Funktionalität dezentraler Anwendungen zu gewährleisten. Fehler können jedoch aus verschiedenen Gründen auftreten, was zu fehlgeschlagenen Transaktionen und potenziellen Sicherheitsanfälligkeiten führen kann. In diesem Blogbeitrag werden einige häufige Fehler bei ERC-20 Token-Transaktionen, ihre Ursachen und Lösungen untersucht.

1. Pancake: K

Der Fehler tritt auf, wenn die Invarianz „Das Produkt der Reserven muss konstant sein“ verletzt wird. Diese Bedingung stellt sicher, dass nach der Ausführung des Swaps das neue Produkt der Reserven (einschließlich Gebühren) nicht kleiner ist als das alte Produkt. Eine Verletzung dieser Bedingung kann auftreten, wenn:

  1. Die in den Pool eingezahlten Token (amount0In oder amount1In) nicht mit den erwarteten Werten gemäß der Invariantengleichung übereinstimmen. Es gab einen Fehler bei der Berechnung der Bilanzen nach dem Swap.
  2. Jemand versucht hat, den Pool zu manipulieren, was dazu führte, dass sich die Token-Bilanzen ändern und den Standard-Swap-Prozess umgangen wurden.
  3. Wenn diese Bedingung nicht erfüllt ist, wird der Fehler „Pancake: K“ ausgelöst, der auf eine Verletzung der mathematischen Invarianz hinweist.

Eine Verletzung der Invarianz bedeutet, dass eine der grundlegenden Bedingungen, die eine korrekte Funktion des Systems sicherstellen, nicht mehr erfüllt ist. Im Kontext von dezentralisierten Börsen wie PancakeSwap ist die Invarianz in der Regel mit einer mathematischen Gleichung verbunden, die wahr bleiben muss, um das Gleichgewicht zwischen den Token-Reserven im Liquiditätspool aufrechtzuerhalten.


require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(10000**2), 'Pancake: K');

Lösung:
Überprüfen Sie, ob der Pool über genügend Liquidität verfügt, um den Austausch durchzuführen, und dass die Werte die Reserven (_reserve0, _reserve1) nicht überschreiten. Überwachen Sie kontinuierlich die Pool-Reserven und ergreifen Sie gegebenenfalls Maßnahmen zur Auffüllung.

2. TransferHelper: TRANSFER_FROM_FAILED

Dieser Fehler weist auf einen fehlgeschlagenen Token-Transfer mithilfe der Methode safeTransferFrom hin, die ein häufiges Muster für das sichere Übertragen von ERC-20-Token ist.


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');
  }

Ursache:

  1. Die Adresse „from“ hat keine oder nicht genügend Berechtigungen für die Adresse „msg.sender“ zum Übertragen von Token gewährt (allowance, approve).
  2. Die Adresse „from“ hat nicht genügend Token, um den Transfer durchzuführen. Dies kann auch daran liegen, dass die Token-Administratoren die Fähigkeit haben, das Token-Guthaben zu ändern und zum Zeitpunkt der Abhebung der Benutzer, der die Investition getätigt hat, möglicherweise nicht über genügend Guthaben verfügt, um die Abhebung durchzuführen.
  3. Der Token-Vertrag implementiert möglicherweise nicht die Funktion „transferFrom“ oder implementiert sie nicht korrekt.
  4. Der Token-Vertrag kann zusätzliche Überprüfungen oder Einschränkungen in der Funktion „transferFrom“ enthalten, die dazu führen können, dass die Transaktion abgebrochen wird.
  5. Wenn nicht genügend Gas vorhanden ist, um die Transaktion auszuführen, kann die Transaktion fehlschlagen.

Lösung:

  1. Stellen Sie sicher, dass die Adresse „from“ genügend allowance für „msg.sender“ gewährt hat. Dies kann durch Aufrufen der Funktion „allowance“ des Token-Vertrags erfolgen.
  2. Stellen Sie sicher, dass die Adresse „from“ über genügend Token verfügt, um den Transfer durchzuführen.
  3. Überprüfen Sie, ob die Adresse des Token-Vertrags korrekt ist und ob der Vertrag ERC-20-konform ist.
  4. Überprüfen Sie die Implementierung der Funktion „transferFrom“ im Token-Vertrag. Stellen Sie sicher, dass sie korrekt implementiert ist und keine zusätzlichen Einschränkungen aufweist, die zu einem Fehler führen könnten.
  5. Versuchen Sie, das Gaslimit bei der Transaktion zu erhöhen, um sicherzustellen, dass das Problem nicht am Mangel an Gas liegt.

3. INSUFFICIENT_LIQUIDITY

Dieser Fehler tritt auf, wenn versucht wird, mehr Liquidität abzuheben, als in den Reserven eines Liquiditätspools verfügbar ist.


(uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
        require(amount0Out < _reserve0 && amount1Out < _reserve1, 'Pancake:
INSUFFICIENT_LIQUIDITY');

Ursache:

  1. Der Liquiditätspool enthält nicht genügend Menge eines oder beider Token, um den angeforderten Austausch zu erfüllen.
  2. Der angeforderte Betrag an Token für die Abhebung (amount0Out oder amount1Out) überschreitet die verfügbaren Anzahl an Token im Pool.
  3. Mismatch zwischen den Reserven im Vertrag und dem tatsächlichen Zustand des Pools. Die im Vertrag gespeicherten Reserven stimmen möglicherweise nicht mit dem tatsächlichen Kontostand der Token im Pool überein, was auf Fehler oder Manipulationen zurückzuführen sein kann.

Lösung:

  1. Überprüfen Sie die Pool-Reserven und stellen Sie sicher, dass sie ausreichen, um den angeforderten Austausch zu erfüllen. Dies kann durch die Verwendung der Funktion „getReserves“ erfolgen.
  2. Stellen Sie sicher, dass die Parameter amount0Out und amount1Out korrekt sind und die verfügbaren Token im Pool nicht überschreiten.
  3. Stellen Sie sicher, dass die Reserven im Vertrag mit dem tatsächlichen Token-Guthaben übereinstimmen. Dazu können Sie Überprüfungen und Aktualisierungen der Reserven vor der Durchführung des Austauschs hinzufügen.

INSUFFICIENT_LIQUIDITY

4. APPROVE_FAILED

Der Fehler „APPROVE_FAILED“ tritt bei der Ausführung der Funktion „safeApprove“ auf. Diese Funktion dient dazu, den Betrag an Token festzulegen, den ein Besitzer einem Ausgeber zur Verfügung stellt.


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');
}

Ursache:

  1. Der Token-Vertrag hat möglicherweise nicht die Funktion „approve“ oder sie ist möglicherweise fehlerhaft implementiert.
  2. Es könnte ein Problem mit dem Zustand des Token-Vertrags vorliegen, wie z.B. unzureichendes Guthaben oder allowance.
  3. Die Funktion „approve“ könnte aus Sicherheitsgründen, die im Token-Vertrag implementiert sind, zurückgewiesen werden.

Lösung:

  1. Stellen Sie sicher, dass der Token-Vertrag dem ERC-20-Standard entspricht und eine korrekt implementierte „approve“-Funktion enthält.
  2. Überprüfen Sie den Zustand des Token-Vertrags und stellen Sie sicher, dass das Konto über genügend Token zum Genehmigen verfügt.
  3. Überprüfen Sie, ob die an die Funktion „safeApprove“ übergebene Adresse und der Betrag korrekt sind.
  4. Debuggen Sie weiter, indem Sie die spezifische Fehlermeldung oder den Grund für das Zurückweisen im Token-Vertrag überprüfen.

5. Fehler „ds-math-sub-underflow“

Der Fehler „ds-math-sub-underflow“ wird ausgelöst, wenn eine Subtraktionsoperation unterläuft, d.h. wenn das Ergebnis der Subtraktion kleiner als Null ist.


    function sub(uint x, uint y) internal pure returns (uint z) {
      require((z = x - y) <= x, 'ds-math-sub-underflow');
    } 

Ursache:
Dieser Fehler tritt auf, weil die Subtraktionsoperation „x - y“ eine negative Zahl ergibt, was für unsigned Integers in Solidity nicht erlaubt ist.

Lösung:

  1. Stellen Sie sicher, dass der Wert von „y“ immer kleiner oder gleich „x“ ist, bevor Sie die Subtraktion durchführen.
  2. Implementieren Sie Überprüfungen in Ihrem Code, um Fälle zu behandeln, in denen „y“ größer als „x“ sein könnte, und ergreifen Sie geeignete Maßnahmen, wie z.B. das Zurücksetzen der Transaktion oder das Anpassen der Logik.

6. Fehler mit 'ERC20: transfer amount exceeds allowance'

Der Fehler `ERC20: transfer amount exceeds allowance` tritt auf, wenn versucht wird, Token im Auftrag eines anderen Benutzers zu übertragen, aber der übertragene Betrag die Genehmigungsgrenze überschreitet, die der Token-Besitzer für den Ausgeber festgelegt hat.

Ursache:
Dieser Fehler wird von der Funktion `transferFrom` des ERC-20 Token-Vertrags ausgelöst, wenn der zu übertragende Betrag die vom Token-Besitzer festgelegte Genehmigungsgrenze überschreitet.

Lösung:

  1. Stellen Sie sicher, dass der Token-Besitzer eine angemessene Genehmigung für den Ausgeber mit der Funktion `approve` festgelegt hat.
  2. Überprüfen Sie die aktuelle Genehmigung, bevor Sie die `transferFrom`-Operation ausführen.
  3. Falls erforderlich, bitten Sie den Token-Besitzer, die Genehmigung zu erhöhen, indem er die Funktion `approve` mit einem höheren Betrag aufruft.

7. TRANSFER_FAILED

Dieser Fehler tritt auf, wenn der Transfer von Token von einer Adresse zu einer anderen fehlschlägt. Die Funktion `_safeTransfer` stellt sicher, dass die Übertragungsoperation erfolgreich ist und die zurückgegebenen Daten, falls vorhanden, in `true` decodiert werden.


    `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'); }`

Ursache:

  1. Die `token.call`-Funktion wird nicht erfolgreich ausgeführt (d.h. `success` ist `false`).
  2. Der Aufruf gibt Daten zurück, die nicht in `true` decodiert werden, was auf einen Fehler in der `transfer`-Funktion des Token-Vertrags hinweist.

Lösung:

  1. Sicherstellen, dass die ERC-20-Konformität gegeben ist: Verifizieren Sie, dass der Token-Vertrag dem ERC-20-Standard entspricht, einschließlich einer korrekt implementierten `transfer`-Funktion.
  2. Überprüfen Sie die Parameter: Stellen Sie sicher, dass die Adresse `to` gültig ist und der `value` innerhalb der zulässigen Grenzen liegt, unter Berücksichtigung des Guthabens des Absenders und der Logik des Vertrags.
  3. Zusätzliche Bedingungen: Überprüfen Sie, ob der Token-Vertrag zusätzliche Bedingungen wie eine Vorabgenehmigung des Ausgabenbetrags (`approve` und `allowance`-Funktionen) erfordert.

INSUFFICIENT_LIQUIDITY

8. INSUFFICIENT_OUTPUT_AMOUNT

Dieser Fehler tritt im Kontext einer dezentralen Börse auf, wenn der Ausgabebetrag eines Token-Swaps kleiner ist als der vom Benutzer angegebene Mindestbetrag. Dies ist ein Schutzmechanismus, um sicherzustellen, dass die Benutzer nicht weniger Token erhalten, als sie aufgrund von Slippage oder Preisänderungen während der Transaktion erwartet haben.


    `require(amounts[amounts.length - 1] >= amountOutMin,
    'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT');`

Ursache:

  1. Marktschwankungen, die die Token-Preise zwischen dem Zeitpunkt der Transaktionsinitiierung und der Ausführung beeinflussen.
  2. Hohe Slippage-Einstellungen, die erhebliche Abweichungen bei den erwarteten Ergebnissen zulassen.
  3. Unzureichende Liquidität im Handels-Pool, die größere Preisbewegungen verursacht.

Lösung:

  1. Sicherstellen, dass der Token-Vertrag den ERC-20-Standard einhält, einschließlich einer korrekt implementierten `transfer`-Funktion.
  2. Überprüfen Sie die Parameter: Stellen Sie sicher, dass die Adresse `to` gültig ist und der `value` innerhalb der zulässigen Grenzen liegt, unter Berücksichtigung des Guthabens des Absenders und der Logik des Vertrags.
  3. Zusätzliche Bedingungen: Überprüfen Sie, ob der Token-Vertrag zusätzliche Bedingungen wie eine Vorabgenehmigung des Ausgabenbetrags (`approve` und `allowance`-Funktionen) erfordert.

9. INSUFFICIENT_INPUT_AMOUNT

Dieser Fehler tritt auf, wenn keiner der Eingabemengen für einen Token-Swap größer als null ist. Er stellt sicher, dass mindestens eine der Eingabemengen (`amount0In` oder `amount1In`) positiv ist, um den Swap durchzuführen.


    uint amount0In = ...; // Input amount of token0
    uint amount1In = ...; // Input amount of token1
    require(amount0In > 0 || amount1In > 0, 'Pancake: INSUFFICIENT_INPUT_AMOUNT');

Ursache:

  1. Falsche Eingabeparameter für die Swap-Funktion.
  2. Unzureichende Mittel auf dem Benutzerkonto.
  3. Fehler in der Logik, die die Eingabemengen berechnet.

Lösung:

  1. Eingabemengen validieren: Stellen Sie sicher, dass die Eingabemengen korrekt festgelegt sind, bevor Sie die Swap-Funktion aufrufen. Dies beinhaltet die ordnungsgemäße Validierung der Benutzereingaben und die Festlegung der Parameter.
  2. Überprüfen Sie die Benutzerkonten: Verifizieren Sie, dass der Benutzer über ausreichendes Guthaben der für den Swap vorgesehenen Token verfügt. Dies kann durch Aufruf der Funktion `balanceOf` der entsprechenden Token-Verträge erfolgen.

10. Fehler

Ursache:

  1. Eine Transaktion kann nicht ausgeführt werden, weil nicht genügend Gas vorhanden ist, um alle Operationen abzuschließen.
  2. Falsche Logik oder Bedingungen innerhalb eines Smart Contracts können dazu führen, dass die Ausführung fehlschlägt (zum Beispiel ein fehlgeschlagener `require`- oder `assert`-Aufruf).
  3. Versuch, eine Token- oder Kryptowährungstransaktion durchzuführen, wenn das Konto nicht genügend Guthaben aufweist.
  4. Beim Arbeiten mit ERC-20- und ERC-721-Standard-Token kann die Transaktion aufgrund unzureichender Berechtigungen fehlschlagen.
  5. Ein Aufruf eines Smart Contracts kann aufgrund der Nichterfüllung der Bedingungen innerhalb des Vertrags zurückgesetzt werden (z.B. durch die Verwendung der `revert`-Funktion).

Lösung:

  1. Erhöhen Sie das Gaslimit bei der Übermittlung der Transaktion.
  2. Überprüfen Sie die Bedingungen und die Logik innerhalb des Smart Contracts.
  3. Stellen Sie sicher, dass das Konto über genügend Mittel verfügt, um die Transaktion abzuschließen.
  4. Rufen Sie die `approve`-Funktion mit dem ausreichenden Wert auf, bevor Sie `transferFrom` aufrufen.
  5. Überprüfen Sie die Bedingungen, die dazu führen, dass die Transaktion zurückgesetzt wird.
  6. Überprüfen Sie Ihr Guthaben für Gebühren.

Fazit

Das Verständnis und die Behebung dieser häufigen Fehler in ERC-20-Smart Contracts erfordert ein fundiertes Verständnis der Solidity-Programmierung, des ERC-20-Standards und der Funktionsweise dezentraler Börsen. Durch sorgfältige Überprüfung der Ursachen und Umsetzung der vorgeschlagenen Lösungen können Entwickler robustere und zuverlässigere Smart Contracts erstellen und so ein nahtloses Erlebnis für Benutzer im dezentralen Ökos ystem gewährleisten.

All posts

Connect to a wallet

Metamask