From af70a07ba6c361f377b4039bb7213fa729372cc0 Mon Sep 17 00:00:00 2001 From: Foivos Date: Mon, 23 Oct 2023 17:34:55 +0300 Subject: [PATCH] Removed Eternal Storage --- contracts/libs/StringStorage.sol | 45 ++++++++++++++ contracts/utils/EternalStorage.sol | 91 ---------------------------- contracts/utils/InterchainRouter.sol | 54 ++++++++++------- 3 files changed, 78 insertions(+), 112 deletions(-) create mode 100644 contracts/libs/StringStorage.sol delete mode 100644 contracts/utils/EternalStorage.sol diff --git a/contracts/libs/StringStorage.sol b/contracts/libs/StringStorage.sol new file mode 100644 index 00000000..f379861f --- /dev/null +++ b/contracts/libs/StringStorage.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +library StringStorage { + function storeString(uint256 slot, string memory str) internal { + uint256 length = bytes(str).length; + assembly { + sstore(slot, length) + } + length /= 32; + for(uint256 i = 1; i <= length; ++i) { + assembly { + sstore(add(slot, i), mload(add(str, mul(i, 32)))) + } + } + } + + function loadString(uint256 slot) internal view returns (string memory str) { + uint256 length; + assembly { + length := sload(slot) + } + str = new string(length); + length /= 32; + for(uint256 i = 1 ; i <= length; ++i) { + assembly { + mstore(add(str, mul(i, 32)), sload(add(slot, i))) + } + } + } + + function deleteString(uint256 slot) internal { + uint256 length; + assembly { + length := sload(slot) + sstore(slot, 0) + } + for(uint256 i = 1 ; i <= length; ++i) { + assembly { + sstore(sload(add(slot, i)), 0) + } + } + } +} \ No newline at end of file diff --git a/contracts/utils/EternalStorage.sol b/contracts/utils/EternalStorage.sol deleted file mode 100644 index 7f101ac9..00000000 --- a/contracts/utils/EternalStorage.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -/** - * @title EternalStorage - * @dev This contract holds all the necessary state variables to carry out the storage of any contract. - */ -contract EternalStorage { - mapping(bytes32 => uint256) private _uintStorage; - mapping(bytes32 => string) private _stringStorage; - mapping(bytes32 => address) private _addressStorage; - mapping(bytes32 => bytes) private _bytesStorage; - mapping(bytes32 => bool) private _boolStorage; - mapping(bytes32 => int256) private _intStorage; - - // *** Getter Methods *** - function getUint(bytes32 key) public view returns (uint256) { - return _uintStorage[key]; - } - - function getString(bytes32 key) public view returns (string memory) { - return _stringStorage[key]; - } - - function getAddress(bytes32 key) public view returns (address) { - return _addressStorage[key]; - } - - function getBytes(bytes32 key) public view returns (bytes memory) { - return _bytesStorage[key]; - } - - function getBool(bytes32 key) public view returns (bool) { - return _boolStorage[key]; - } - - function getInt(bytes32 key) public view returns (int256) { - return _intStorage[key]; - } - - // *** Setter Methods *** - function _setUint(bytes32 key, uint256 value) internal { - _uintStorage[key] = value; - } - - function _setString(bytes32 key, string memory value) internal { - _stringStorage[key] = value; - } - - function _setAddress(bytes32 key, address value) internal { - _addressStorage[key] = value; - } - - function _setBytes(bytes32 key, bytes memory value) internal { - _bytesStorage[key] = value; - } - - function _setBool(bytes32 key, bool value) internal { - _boolStorage[key] = value; - } - - function _setInt(bytes32 key, int256 value) internal { - _intStorage[key] = value; - } - - // *** Delete Methods *** - function _deleteUint(bytes32 key) internal { - delete _uintStorage[key]; - } - - function _deleteString(bytes32 key) internal { - delete _stringStorage[key]; - } - - function _deleteAddress(bytes32 key) internal { - delete _addressStorage[key]; - } - - function _deleteBytes(bytes32 key) internal { - delete _bytesStorage[key]; - } - - function _deleteBool(bytes32 key) internal { - delete _boolStorage[key]; - } - - function _deleteInt(bytes32 key) internal { - delete _intStorage[key]; - } -} diff --git a/contracts/utils/InterchainRouter.sol b/contracts/utils/InterchainRouter.sol index 60371bc9..76f5bd67 100644 --- a/contracts/utils/InterchainRouter.sol +++ b/contracts/utils/InterchainRouter.sol @@ -4,16 +4,17 @@ pragma solidity ^0.8.0; import { IInterchainRouter } from '../interfaces/IInterchainRouter.sol'; import { Upgradable } from '../upgradable/Upgradable.sol'; -import { EternalStorage } from './EternalStorage.sol'; +import { StringStorage } from '../libs/StringStorage.sol'; /** * @title RemoteAddressValidator * @dev Manages and validates remote addresses, keeps track of addresses supported by the Axelar gateway contract */ -contract InterchainRouter is IInterchainRouter, Upgradable, EternalStorage { +contract InterchainRouter is IInterchainRouter, Upgradable { bytes32 internal constant PREFIX_ADDRESS_MAPPING = keccak256('interchain-router-address-mapping'); - bytes32 internal constant CHAIN_NAME_KEY = keccak256('interchain-router-chain-name-slot'); + bytes32 internal constant PREFIX_ADDRESS_HASH_MAPPING = keccak256('interchain-router-address-hash-mapping'); + uint256 internal constant CHAIN_NAME_SLOT = 0x6406a0b603e31e24a15e9f663879eedde3bef27687f318a9875bafac9d63fc1f; bytes32 private constant CONTRACT_ID = keccak256('remote-address-validator'); @@ -23,7 +24,7 @@ contract InterchainRouter is IInterchainRouter, Upgradable, EternalStorage { */ constructor(string memory chainName_) { if (bytes(chainName_).length == 0) revert ZeroStringLength(); - _setChainName(chainName_); + StringStorage.storeString(CHAIN_NAME_SLOT, chainName_); } /** @@ -44,28 +45,30 @@ contract InterchainRouter is IInterchainRouter, Upgradable, EternalStorage { } } + /** - * @dev Sets the name of the chain this is deployed at. Should probably not chainge after being set initially - * @param chainName Chain name of the current chain + * @dev Gets the name of the chain this is deployed at */ - function _setChainName(string memory chainName) internal { - _setString(CHAIN_NAME_KEY, chainName); + function getChainName() external view returns (string memory chainName) { + chainName = StringStorage.loadString(CHAIN_NAME_SLOT); } /** - * @dev Gets the name of the chain this is deployed at + * @dev Gets the key for the trusted address at a remote chain + * @param chain Chain name of the remote chain + * @return slot the slot to store the trusted address in */ - function getChainName() external view returns (string memory chainName) { - chainName = getString(CHAIN_NAME_KEY); + function _getTrustedAddressSlot(string memory chain) internal pure returns (uint256 slot) { + slot = uint256(keccak256(abi.encode(PREFIX_ADDRESS_MAPPING, chain))); } /** * @dev Gets the key for the trusted address at a remote chain * @param chain Chain name of the remote chain - * @return key the key to use in the Eternal Storage for both the trusted address and its hash + * @return slot the slot to store the trusted address hash in */ - function _getTrustedAddressKey(string memory chain) internal pure returns (bytes32 key) { - key = keccak256(abi.encode(PREFIX_ADDRESS_MAPPING, chain)); + function _getTrustedAddressHashSlot(string memory chain) internal pure returns (uint256 slot) { + slot = uint256(keccak256(abi.encode(PREFIX_ADDRESS_HASH_MAPPING, chain))); } /** @@ -74,8 +77,12 @@ contract InterchainRouter is IInterchainRouter, Upgradable, EternalStorage { * @param trustedAddress the string representation of the trusted address */ function _setTrustedAddress(string memory chain, string memory trustedAddress) internal { - _setString(_getTrustedAddressKey(chain), trustedAddress); - _setUint(_getTrustedAddressKey(chain), uint256(keccak256(bytes(trustedAddress)))); + StringStorage.storeString(_getTrustedAddressSlot(chain), trustedAddress); + uint256 slot = _getTrustedAddressHashSlot(chain); + bytes32 addressHash = keccak256(bytes(trustedAddress)); + assembly { + sstore(slot, addressHash) + } } /** @@ -84,7 +91,7 @@ contract InterchainRouter is IInterchainRouter, Upgradable, EternalStorage { * @return trustedAddress the trusted address for the chain. Returns '' if the chain is untrusted */ function getTrustedAddress(string memory chain) public view returns (string memory trustedAddress) { - trustedAddress = getString(_getTrustedAddressKey(chain)); + trustedAddress = StringStorage.loadString(_getTrustedAddressSlot(chain)); } /** @@ -93,7 +100,10 @@ contract InterchainRouter is IInterchainRouter, Upgradable, EternalStorage { * @return trustedAddressHash the hash of the trusted address */ function getTrustedAddressHash(string memory chain) public view returns (bytes32 trustedAddressHash) { - trustedAddressHash = bytes32(getUint(_getTrustedAddressKey(chain))); + uint256 slot = _getTrustedAddressHashSlot(chain); + assembly { + trustedAddressHash := sload(slot) + } } /** @@ -129,9 +139,11 @@ contract InterchainRouter is IInterchainRouter, Upgradable, EternalStorage { function removeTrustedAddress(string calldata sourceChain) external onlyOwner { if (bytes(sourceChain).length == 0) revert ZeroStringLength(); - _deleteString(_getTrustedAddressKey(sourceChain)); - _deleteUint(_getTrustedAddressKey(sourceChain)); - + StringStorage.deleteString(_getTrustedAddressSlot(sourceChain)); + uint256 slot = _getTrustedAddressHashSlot(sourceChain); + assembly { + sstore(slot, 0) + } emit TrustedAddressRemoved(sourceChain); }