Back to Blog

Revest Finance Schwachstellen: Mehr als nur Re-entrancy

Code Auditing
March 31, 2022
8 min read

Am 27. März 2022 wurde das Staking-DeFi-Projekt Revest Finance auf Ethereum aufgrund des ERC-1155-Callback-Mechanismus angegriffen, was zum Diebstahl von Token im Wert von rund 2 Millionen US-Dollar (nämlich BLOCKS, ECO, LYXe und RENA) führte. Wir haben den Angriff zunächst analysiert und unsere Analyse noch am selben Abend (UTC+8) auf Twitter veröffentlicht.

Tatsächlich hatten wir zum Zeitpunkt der Twitter-Veröffentlichung noch Zweifel an einer Funktion im Revest TokenVault-Vertrag. Wir haben den Vertrag untersucht, um seine Funktionalität zu verstehen. Später stellten wir fest, dass es sich um eine weitere kritische Zero-Day-Schwachstelle handelt, die auf wesentlich einfachere Weise ausgenutzt werden kann und zu den gleichen enormen Verlusten führen kann (wie beim aufgetretenen Angriff).

Wir haben uns umgehend an das Revest Finance-Team gewandt, das schnell reagierte und eine Umgehungslösung für die Schwachstelle vorschlug. Nachdem wir bestätigt hatten, dass die Schwachstelle nicht ausgelöst werden kann, entschieden wir uns, diesen Blog zu veröffentlichen.

Der folgende Teil dieses Blogs besteht aus drei Teilen: dem Mechanismus von Revest Finance, dem ursprünglichen Re-entrancy-Angriff und der neuen Zero-Day-Schwachstelle.

Was ist das Revest Finance FNFT?

Der Financial Non-Fungible Token (FNFT) von Revest Finance ermöglicht die vertrauenslose Übertragung zukünftiger Rechte an gesperrte Vermögenswerte. Der Einstiegsvertrag (Revest-Vertrag) bietet drei verschiedene Schnittstellen, um FNFTs durch Sperren zugrunde liegender Vermögenswerte zu prägen:

  • mintTimeLock: Der zugrunde liegende Vermögenswert wird nach einer bestimmten Zeit freigeschaltet.
  • mintValueLock: Der zugrunde liegende Vermögenswert wird freigeschaltet, wenn sein Wert einen vorgeschriebenen Wert über- oder unterschreitet.
  • mintAddressLock: Der zugrunde liegende Vermögenswert wird von einem vorgeschriebenen Konto freigeschaltet.

Der Revest-Vertrag verbindet die anderen drei Verträge zum Sperren und Entsperren zugrunde liegender Vermögenswerte.

  • FNFTHandler: Erbt vom ERC-1155-Token. Er erstellt für jede Sperre einen neuen FNFT mit der inkrementellen fnftId. Die Sperre schreibt die Gesamtzahl der neu erstellten FNFTs bei der Erstellung vor. Die FNFTs können nicht auf andere Weise geprägt werden, können aber zum Freischalten zugrunde liegender Vermögenswerte verbrannt werden.

  • LockManager: Erfasst die Entsperrungsbedingungen für jede Sperre bei der Erstellung und entscheidet, ob die Sperre beim Entsperren freigegeben werden kann.

  • TokenVault: Empfängt und sendet die zugrunde liegenden Vermögenswerte und erfasst die Metadaten für jeden FNFT, wie z. B. den Wert eines bestimmten FNFT.

Wir nehmen mintAddressLock als Beispiel, um den Prozess der Prägung von FNFTs zu veranschaulichen.

Abbildung 1
Abbildung 2

Die beiden obigen Abbildungen beschreiben, wie ein FNFT erstellt, geprägt und verbrannt wird. Konkret sperrt Benutzer A 100 WETH in Revest Finance, wodurch der entsprechende FNFT mit fnftId als 1 erstellt wird. Schließlich prägt er 100 1-FNFTs an angegebene Empfänger mit angegebenen Anteilen.

Beachten Sie, dass nach dem Freischalten des zugrunde liegenden Vermögenswerts jeder 1-FNFT zum Erhalt eines (1e18) WETH verbrannt werden kann. Wie in Abbildung 2 gezeigt, zieht Benutzer B 25 ( 1e18) WETH ab, indem er 25 1-FNFTs verbrennt.

Darüber hinaus bietet der Revest-Vertrag eine weitere Schnittstelle namens depositAdditionalToFNFT, die zwei Schwachstellen birgt, die im Folgenden besprochen werden.

Wir verwenden zunächst die folgenden beiden Abbildungen, um die normale Verwendung dieser Funktion zu beschreiben.

Abbildung 3
Abbildung 4

Die Funktion depositAdditionalToFNFT sperrt weitere zugrunde liegende Vermögenswerte in eine bestehende Sperre (angegeben durch fnftId). Sinnvollerweise (Abbildung 3) erfordert sie, dass die angegebene Menge der Gesamtversorgung des angegebenen FNFT entspricht und verteilt dann die zusätzlichen Vermögenswerte gleichmäßig auf jeden angegebenen FNFT.

Andernfalls (Abbildung 4) erstellt sie eine neue Sperre mit der neuesten fnftId, verbrennt die angegebenen Mengen alter FNFTs und prägt die angegebene Menge neuer FNFTs und zeichnet dann den depositAmount der neuen Sperre als Summe des depositAmount der alten Sperre und des angegebenen Betrags auf, wie im folgenden Code gezeigt.

// Jetzt transferieren wir zum Token-Tresor
if(fnft.asset != address(0)){
    IERC20(fnft.asset).safeTransferFrom(_msgSender(), vault, quantity * amount);
}

ITokenVault(vault).handleMultipleDeposits(fnftId, newFNFTId, fnft.depositAmount + amount);

emit FNFTAddionalDeposited(_msgSender(), newFNFTId, quantity, amount);

Da der im TokenVault-Vertrag gespeicherte depositAmount den Betrag des zugrunde liegenden Vermögenswerts angibt, den ein bestimmter FNFT abheben kann, überträgt diese Operation den Wert der angegebenen Mengen des alten FNFT von der alten Sperre zur neuen Sperre.

(Eine angegebene Menge, die größer als die Gesamtversorgung ist, führt zum Zurücksetzen der Transaktion)

Was ist die Re-entrancy-Schwachstelle?

In diesem Teil werden wir erläutern, wie der Re-entrancy-Angriff funktioniert, und die Ursache sowie die Korrekturmethode erörtern.

Abbildung 5
Abbildung 6
Abbildung 7

Die obigen drei Abbildungen beschreiben im Wesentlichen den gesamten Prozess des Re-entrancy-Angriffs. Insbesondere sperrt der Angreifer zunächst null RENA-Token, um 2 1-FNFTs zu prägen, die keinen Wert haben. Zweitens sperrt der Angreifer erneut null RENA-Token, prägt aber 360.000 2-FNFTs, die ebenfalls (noch) keinen Wert haben. Im letzten Schritt greift der Angreifer den Revest-Vertrag der Funktion depositAdditionalToFNFT über den Callback-Mechanismus des FNFTHandler wieder auf, der vom ERC-1155-Token-Standard geerbt wird, was den depositAmount der Sperre mit fnftId als 2 überschreibt, bevor fnftId aktualisiert wird. Infolgedessen erhält der Angreifer 360.001 2-FNFTs mit einem depositAmount von 1e18, was bedeutet, dass er 360.001 * 1e18 RENA aus dem TokenVault-Vertrag abziehen kann. Außerdem betragen die einzigen Kosten 1e18 RENA.

Korrekturmethode

Die Codes von Revest Finance entsprechen vollständig dem klassischen Re-entrancy-Muster: Verwende fnftId -> externer Aufruf mit Callback-Mechanismus -> Aktualisiere fnftId. Daher ist der einfachste Weg, die Probleme zu beheben, dieses Muster zu durchbrechen. Der korrigierte Code ist unten gezeigt:

function mint(
    address account,
    uint id,
    uint amount,
    bytes memory data
) external override onlyRevestController {
    require(amount > 0, "Invalid amount");
    require(supply[id] == 0, "Repeated mint for the same FNFT");
    supply[id] += amount;
    fnftsCreated += 1;
    _mint(account, id, amount, data);
}

Erstens verschiebt er die Aktualisierungsoperation vor den externen Aufruf (_mint), was den Angriff vermeiden kann. Zweitens, da das System keine null FNFTs prägen und dieselbe FNFT wiederholt prägen lässt, fügt er zwei Prüfungen hinzu, um sicherzustellen, dass das System wie erwartet funktioniert, was die Sicherheit des Systems verbessern kann.

Die neue Zero-day-Schwachstelle

Bei der Analyse des Codes von Revest Finance verwirrte uns immer die Funktion handleMultipleDeposits im TokenVault-Vertrag, deren Code wie folgt gezeigt wird:

function handleMultipleDeposits(
    uint fnftId,
    uint newFNFTId,
    uint amount
) external override onlyRevestController {
    require(amount >= fnfts[fnftId].depositAmount, 'E003');
    IRevest.FNFTConfig storage config = fnfts[fnftId];
    config.depositAmount = amount;
    mapFNFTToToken(fnftId, config);
    if(newFNFTId != 0) {
        mapFNFTToToken(newFNFTId, config);
    }
}

Beim Aufruf der Funktion depositAdditionalToFNFT ändert die Funktion handleMultipleDeposits den depositAmount der alten Sperre oder erfasst ihn für die neue. Wenn newFNFTId null ist, erfasst sie den depositAmount der neuen Sperre nicht, da es sich um eine Operation zum Hinzufügen zusätzlicher Vermögenswerte zu einer bestehenden Sperre handelt.

Laut gesundem Menschenverstand erfasst sie, wenn newFNFTId nicht null ist, nur den depositAmount der neuen Sperre, ändert aber nicht den depositAmount der alten. Der Code besagt jedoch, dass er nicht nur den depositAmount der neuen Sperre erfasst, sondern auch den depositAmount der alten ändert.

Wir halten dies für eine schwerwiegende Zero-Day-Logik-Schwachstelle und haben daraufhin eine PoC zur Verifizierung geschrieben. Die folgenden drei Abbildungen beschreiben, wie die PoC funktioniert.

Abbildung 8
Abbildung 9
Abbildung 10

Konkret sperrt der Angreifer zunächst null RENA, um 360.000 1-FNFTs zu prägen. Danach ruft der Angreifer direkt die Funktion depositAdditionalToFNFT auf, um eine neue Sperre zu erstellen. Aufgrund des Logikfehlers ändert der TokenVault-Vertrag den depositAmount der alten Sperre fälschlicherweise von null auf 1e18. Infolgedessen erhält der Angreifer 359.999 1-FNFTs im Wert von 359.999 RENA. Offensichtlich ist die PoC weitaus einfacher als der tatsächliche Re-entrancy-Angriff.

Die Umgehungslösung zur Behebung der Schwachstelle

Dies ist ein Logikfehler, und wir empfehlen die Verwendung des folgenden Codes zur Behebung:

function handleMultipleDeposits(
    uint fnftId,
    uint newFNFTId,
    uint amount
) external override onlyRevestController {
    require(amount >= fnfts[fnftId].depositAmount, 'E003');
    IRevest.FNFTConfig memory config = fnfts[fnftId];
    config.depositAmount = amount;
    if(newFNFTId != 0) {
        mapFNFTToToken(newFNFTId, config);
    } else {
        mapFNFTToToken(fnftId, config);
    }
}

Da die beiden anfälligen Verträge: TokenVault und FNFTHandler viele kritische Zustände speichern, kann das Projekt den TokenVault-Vertrag und den FNFTHandler-Vertrag nicht ohne Migration von Zuständen neu bereitstellen. Um weitere Angriffe auf diese Schwachstelle zu vermeiden, hat das Projekt eine Lite-Version des Revest-Vertrags neu bereitgestellt, die komplexere Funktionen deaktiviert, um die Angriffsflächen für potenzielle Angreifer zu reduzieren. Nach der Überprüfung der Umgehungslösung sind wir der Meinung, dass der Lite- Revest-Vertrag die in diesem Blog genannten möglichen Angriffe abmildern kann.

Fazit

Die Absicherung eines DeFi-Projekts ist keine leichte Aufgabe. Neben der Code-Prüfung sind wir der Meinung, dass die Community einen proaktiven Ansatz verfolgen sollte, um den Projektstatus zu überwachen und den Angriff zu blockieren, bevor er überhaupt stattfindet.

Über BlockSec

BlockSec ist ein wegweisendes Blockchain-Sicherheitsunternehmen, das 2021 von einer Gruppe weltweit angesehener Sicherheitsexperten gegründet wurde. Das Unternehmen engagiert sich für die Verbesserung der Sicherheit und Benutzerfreundlichkeit für die aufstrebende Web3-Welt, um deren breite Akzeptanz zu fördern. Zu diesem Zweck bietet BlockSec Audit-Dienste für Smart Contracts und EVM-Ketten-Sicherheit, die Phalcon-Plattform für die sichere Entwicklung und proaktive Bedrohungsabwehr, die MetaSleuth-Plattform für die Verfolgung und Untersuchung von Geldern sowie die MetaDock-Erweiterung für Web3-Entwickler zum effizienten Surfen in der Krypto-Welt.

Bis heute hat das Unternehmen über 300 angesehene Kunden wie MetaMask, Uniswap Foundation, Compound, Forta und PancakeSwap betreut und in zwei Finanzierungsrunden von führenden Investoren wie Matrix Partners, Vitalbridge Capital und Fenbushi Capital zweistellige Millionenbeträge erhalten.

Offizielle Website: https://blocksec.com/

Offizielles Twitter-Konto: https://twitter.com/BlockSecTeam

Sign up for the latest updates
Newsletter - April 2026
Security Insights

Newsletter - April 2026

In April 2026, the DeFi ecosystem experienced three major security incidents. KelpDAO lost ~$290M due to an insecure 1-of-1 DVN bridge configuration exploited via RPC infrastructure compromise, Drift Protocol suffered ~$285M from a multisig governance takeover leveraging Solana's durable nonce mechanism, and Rhea Finance incurred ~$18.4M following a business logic flaw in its margin-trading module that allowed circular swap path manipulatio

~$7.04M Lost: GiddyDefi, Volo Vault & More | BlockSec Weekly
Security Insights

~$7.04M Lost: GiddyDefi, Volo Vault & More | BlockSec Weekly

This BlockSec weekly security report covers eight attack incidents detected between April 20 and April 26, 2026, across Ethereum, Avalanche, Sui, Base, HyperLiquid, and MegaETH, with total estimated losses of approximately $7.04M. The highlighted incident is the $1.3M GiddyDefi exploit, where the attacker did not break any cryptography or use a flash loan but simply replayed an existing on-chain EIP-712 signature with the unsigned `aggregator` and `fromToken` fields swapped out for a malicious contract, demonstrating how partial signature coverage turns any historical signature into a generic permit. Other incidents include a $3.5M Volo Vault operator key compromise on Sui, a $1.5M Purrlend privileged-role takeover, a $413K SingularityFinance oracle misconfiguration, a $142.7K Scallop cross-pool index injection, a $72.35K Kipseli Router decimal mismatch, a $50.7K REVLoans (Juicebox) accounting pollution, and a $64K Custom Rebalancer arbitrary-call exploit.

Weekly Web3 Security Incident Roundup | Apr 13 – Apr 19, 2026
Security Insights

Weekly Web3 Security Incident Roundup | Apr 13 – Apr 19, 2026

This BlockSec weekly security report covers four attack incidents detected between April 13 and April 19, 2026, across multiple chains such as Ethereum, Unichain, Arbitrum, and NEAR, with total estimated losses of approximately $310M. The highlighted incident is the $290M KelpDAO rsETH bridge exploit, where an attacker poisoned the RPC infrastructure of the sole LayerZero DVN to fabricate a cross-chain message, triggering a cascading WETH freeze across five chains and an Arbitrum Security Council forced state transition that raises questions about the actual trust boundaries of decentralized systems. Other incidents include a $242K MMR proof forgery on Hyperbridge, a $1.5M signed integer abuse on Dango, and an $18.4M circular swap path exploit on Rhea Finance's Burrowland protocol.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit