// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
//import "hardhat/console.sol"; // DEV_MODE
import "./Storage.sol";
import "./Events.sol";
import "./Proxy.sol";
abstract contract Base is Storage, Events {
// Modules
function _createProxy(uint proxyModuleId) internal returns (address) {
require(proxyModuleId != 0, "e/create-proxy/invalid-module");
require(proxyModuleId <= MAX_EXTERNAL_MODULEID, "e/create-proxy/internal-module");
// If we've already created a proxy for a single-proxy module, just return it:
if (proxyLookup[proxyModuleId] != address(0)) return proxyLookup[proxyModuleId];
// Otherwise create a proxy:
address proxyAddr = address(new Proxy());
if (proxyModuleId <= MAX_EXTERNAL_SINGLE_PROXY_MODULEID) proxyLookup[proxyModuleId] = proxyAddr;
trustedSenders[proxyAddr] = TrustedSenderInfo({ moduleId: uint32(proxyModuleId), moduleImpl: address(0) });
emit ProxyCreated(proxyAddr, proxyModuleId);
return proxyAddr;
}
function callInternalModule(uint moduleId, bytes memory input) internal returns (bytes memory) {
(bool success, bytes memory result) = moduleLookup[moduleId].delegatecall(input);
if (!success) revertBytes(result);
return result;
}
// Modifiers
modifier nonReentrant() {
require(reentrancyLock == REENTRANCYLOCK__UNLOCKED, "e/reentrancy");
reentrancyLock = REENTRANCYLOCK__LOCKED;
_;
reentrancyLock = REENTRANCYLOCK__UNLOCKED;
}
modifier reentrantOK() { // documentation only
_;
}
// Used to flag functions which do not modify storage, but do perform a delegate call
// to a view function, which prohibits a standard view modifier. The flag is used to
// patch state mutability in compiled ABIs and interfaces.
modifier staticDelegate() {
_;
}
// WARNING: Must be very careful with this modifier. It resets the free memory pointer
// to the value it was when the function started. This saves gas if more memory will
// be allocated in the future. However, if the memory will be later referenced
// (for example because the function has returned a pointer to it) then you cannot
// use this modifier.
modifier FREEMEM() {
uint origFreeMemPtr;
assembly {
origFreeMemPtr := mload(0x40)
}
_;
/*
assembly { // DEV_MODE: overwrite the freed memory with garbage to detect bugs
let garbage := 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF
for { let i := origFreeMemPtr } lt(i, mload(0x40)) { i := add(i, 32) } { mstore(i, garbage) }
}
*/
assembly {
mstore(0x40, origFreeMemPtr)
}
}
// Error handling
function revertBytes(bytes memory errMsg) internal pure {
if (errMsg.length > 0) {
assembly {
revert(add(32, errMsg), mload(errMsg))
}
}
revert("e/empty-error");
}
}
|