// SPDX-License-Identifier: GPL-3.0pragmasolidity 0.8.20;// Base contract for all contracts intended to be delegatecalled into.abstractcontractImplementation{
errorOnlyDelegateCallError();
errorOnlyConstructorError();
addresspublicimmutable IMPL;
constructor() {
IMPL =address(this);
}
// Reverts if the current function context is not inside of a delegatecall.modifieronlyDelegateCall() virtual{
if (address(this) == IMPL) {
revert OnlyDelegateCallError();
}
_;
}
// Reverts if the current function context is not inside of a constructor.modifieronlyConstructor() {
if (address(this).code.length!=0) {
revert OnlyConstructorError();
}
_;
}
}
Contract Source Code
File 2 of 3: LibRawResult.sol
// SPDX-License-Identifier: GPL-3.0pragmasolidity 0.8.20;libraryLibRawResult{
// Revert with the data in `b`.functionrawRevert(bytesmemory b) internalpure{
assembly {
revert(add(b, 32), mload(b))
}
}
// Return with the data in `b`.functionrawReturn(bytesmemory b) internalpure{
assembly {
return(add(b, 32), mload(b))
}
}
}
Contract Source Code
File 3 of 3: Proxy.sol
// SPDX-License-Identifier: GPL-3.0pragmasolidity 0.8.20;import"./LibRawResult.sol";
import"./Implementation.sol";
/// @notice Base class for all proxy contracts.contractProxy{
usingLibRawResultforbytes;
/// @notice The address of the implementation contract used by this proxy.
Implementation publicimmutable IMPL;
// Made `payable` to allow initialized crowdfunds to receive ETH as an// initial contribution.constructor(Implementation impl, bytesmemory initCallData) payable{
IMPL = impl;
(bool s, bytesmemory r) =address(impl).delegatecall(initCallData);
if (!s) {
r.rawRevert();
}
}
// Forward all calls to the implementation.fallback() externalpayable{
Implementation impl = IMPL;
assembly {
calldatacopy(0x00, 0x00, calldatasize())
let s :=delegatecall(gas(), impl, 0x00, calldatasize(), 0x00, 0)
returndatacopy(0x00, 0x00, returndatasize())
ifiszero(s) {
revert(0x00, returndatasize())
}
return(0x00, returndatasize())
}
}
}