// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {CustomRevert} from "./libraries/CustomRevert.sol"; /// @title Prevents delegatecall to a contract /// @notice Base contract that provides a modifier for preventing delegatecall to methods in a child contract abstract contract NoDelegateCall { using CustomRevert for bytes4; error DelegateCallNotAllowed(); /// @dev The original address of this contract address private immutable original; constructor() { // Immutables are computed in the init code of the contract, and then inlined into the deployed bytecode. // In other words, this variable won't change when it's checked at runtime. original = address(this); } /// @dev Private method is used instead of inlining into modifier because modifiers are copied into each method, /// and the use of immutable means the address bytes are copied in every place the modifier is used. function checkNotDelegateCall() private view { if (address(this) != original) DelegateCallNotAllowed.selector.revertWith(); } /// @notice Prevents delegatecall into the modified method modifier noDelegateCall() { checkNotDelegateCall(); _; } }