pragma solidity ^0.5.16; // Internal References import "./interfaces/IAddressResolver.sol"; // https://docs.synthetix.io/contracts/source/contracts/contractstorage contract ContractStorage { IAddressResolver public resolverProxy; mapping(bytes32 => bytes32) public hashes; constructor(address _resolver) internal { // ReadProxyAddressResolver resolverProxy = IAddressResolver(_resolver); } /* ========== INTERNAL FUNCTIONS ========== */ function _memoizeHash(bytes32 contractName) internal returns (bytes32) { bytes32 hashKey = hashes[contractName]; if (hashKey == bytes32(0)) { // set to unique hash at the time of creation hashKey = keccak256(abi.encodePacked(msg.sender, contractName, block.number)); hashes[contractName] = hashKey; } return hashKey; } /* ========== VIEWS ========== */ /* ========== RESTRICTED FUNCTIONS ========== */ function migrateContractKey( bytes32 fromContractName, bytes32 toContractName, bool removeAccessFromPreviousContract ) external onlyContract(fromContractName) { require(hashes[fromContractName] != bytes32(0), "Cannot migrate empty contract"); hashes[toContractName] = hashes[fromContractName]; if (removeAccessFromPreviousContract) { delete hashes[fromContractName]; } emit KeyMigrated(fromContractName, toContractName, removeAccessFromPreviousContract); } /* ========== MODIFIERS ========== */ modifier onlyContract(bytes32 contractName) { address callingContract = resolverProxy.requireAndGetAddress(contractName, "Cannot find contract in Address Resolver"); require(callingContract == msg.sender, "Can only be invoked by the configured contract"); _; } /* ========== EVENTS ========== */ event KeyMigrated(bytes32 fromContractName, bytes32 toContractName, bool removeAccessFromPreviousContract); }