Skip to content

spherex-xyz/reentrancy-guard-proxy

Repository files navigation

Reentrancy Guard Proxy

A Proxy contract incorporating a Reentrancy Guard

Motivation

While some protocols, such as Orion and Fei-Rari, employed ReentrancyGuard, they still suffered from reentrancy attacks. This implementation now offers several benefits over the traditional approach:

  • Developers no longer need to add the nonReentrant modifier to every function.
  • Public functions can now be called internally while still being blocked externally.
  • View and pure functions are now protected against "Read-Only Reentrancy" attacks.

Installation

forge install spherex-xyz/reentrancy-guard-proxy

(npm will be added in the future)

Usage

pragma solidity ^0.8.0;


import "reentrancy-guard-proxy/ReentrancyGuardTransparentUpgradeableProxy.sol";

The proxy should be deployed and used same as Open Zeppelin proxies

Test

The ReentrancyGuardTransparentUpgradeableProxy and StaticStorageSlotReentrancyGuard pass all OpenZeppelin original tests for TransparentUpgradeableProxy and ReentrancyGuard respectively.

npx hardhat test

Other tests for specific unique cases were also introduced

forge test -vv

Or simply run:

./test.sh

Caveats

  • As with original proxies, it does not support transfer and send to the contract (due to gas limitation)
  • The proxy contract, currently, does not have any exclusion mechanism, which means that callbacks to the same contract will be blocked, as they are essentially reentrant calls (e.g. ERC721 onERC721Received to the same contract)
  • To check if the current context is a STATICCALL, we use a pattern in which we try to emit an event and check if it was successful. The side-effects are emitted event in case of a normal CALL and a partial revert in case of a STATICCALL (This is the only way currently, at least until EIP-2770 will be accepted)