Skip to content

Commit

Permalink
Added the eternal storage here as well and using it for the Interchai…
Browse files Browse the repository at this point in the history
…nRouter.
  • Loading branch information
Foivos committed Oct 20, 2023
1 parent fee271d commit b4705c8
Show file tree
Hide file tree
Showing 3 changed files with 306 additions and 0 deletions.
65 changes: 65 additions & 0 deletions contracts/interfaces/IInterchainRouter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IContractIdentifier } from './IContractIdentifier.sol';

/**
* @title IRemoteAddressValidator
* @dev Manages and validates remote addresses, keeps track of addresses supported by the Axelar gateway contract
*/
interface IInterchainRouter is IContractIdentifier {
error ZeroAddress();
error LengthMismatch();
error ZeroStringLength();
error UntrustedChain();

event TrustedAddressAdded(string sourceChain, string sourceAddress);
event TrustedAddressRemoved(string sourceChain);
/**
* @dev Gets the name of the chain this is deployed at
*/
function getChainName() external view returns (string memory chainName);

/**
* @dev Gets the trusted address at a remote chain
* @param chain Chain name of the remote chain
* @return trustedAddress the trusted address for the chain. Returns '' if the chain is untrusted
*/
function getTrustedAddress(string memory chain) external view returns (string memory trustedAddress);

/**
* @dev Gets the trusted address hash at a remote chain
* @param chain Chain name of the remote chain
* @return trustedAddressHash the hash of the trusted address
*/
function getTrustedAddressHash(string memory chain) external view returns (bytes32 trustedAddressHash);

/**
* @dev Validates that the sender is a valid interchain token service address
* @param sourceChain Source chain of the transaction
* @param sourceAddress Source address of the transaction
* @return bool true if the sender is validated, false otherwise
*/
function validateSender(string calldata sourceChain, string calldata sourceAddress) external view returns (bool);

/**
* @dev Adds a trusted interchain token service address for the specified chain
* @param sourceChain Chain name of the interchain token service
* @param sourceAddress Interchain token service address to be added
*/
function addTrustedAddress(string memory sourceChain, string memory sourceAddress) external;

/**
* @dev Removes a trusted interchain token service address
* @param sourceChain Chain name of the interchain token service to be removed
*/
function removeTrustedAddress(string calldata sourceChain) external;

/**
* @dev Fetches the interchain token service address for the specified chain
* @param chainName Name of the chain
* @return remoteAddress Interchain token service address for the specified chain
*/
function getRemoteAddress(string calldata chainName) external view returns (string memory remoteAddress);
}
91 changes: 91 additions & 0 deletions contracts/utils/EternalStorage.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// 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];
}
}
150 changes: 150 additions & 0 deletions contracts/utils/InterchainRouter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IInterchainRouter } from '../interfaces/IInterchainRouter.sol';
import { Upgradable } from '../upgradable/Upgradable.sol';
import { EternalStorage } from './EternalStorage.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 {

bytes32 internal constant PREFIX_ADDRESS_MAPPING = keccak256('interchain-router-address-mapping');
bytes32 internal constant CHAIN_NAME_KEY = keccak256('interchain-router-chain-name-slot');

bytes32 private constant CONTRACT_ID = keccak256('remote-address-validator');

/**
* @dev Constructs the RemoteAddressValidator contract, both array parameters must be equal in length.
* @param chainName_ The name of the current chain.
*/
constructor(string memory chainName_) {
if (bytes(chainName_).length == 0) revert ZeroStringLength();
_setChainName(chainName_);
}

/**
* @notice Getter for the contract id.
*/
function contractId() external pure returns (bytes32) {
return CONTRACT_ID;
}

function _setup(bytes calldata params) internal override {
(string[] memory trustedChainNames, string[] memory trustedAddresses) = abi.decode(params, (string[], string[]));
uint256 length = trustedChainNames.length;

if (length != trustedAddresses.length) revert LengthMismatch();

for (uint256 i; i < length; ++i) {
addTrustedAddress(trustedChainNames[i], trustedAddresses[i]);
}
}

/**
* @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
*/
function _setChainName(string memory chainName) internal {
_setString(CHAIN_NAME_KEY, chainName);
}

/**
* @dev Gets the name of the chain this is deployed at
*/
function getChainName() external view returns (string memory chainName) {
chainName = getString(CHAIN_NAME_KEY);
}

/**
* @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
*/
function _getTrustedAddressKey(string memory chain) internal pure returns (bytes32 key) {
key = keccak256(abi.encode(PREFIX_ADDRESS_MAPPING, chain));
}

/**
* @dev Sets the trusted address and its hash for a remote chain
* @param chain Chain name of the remote chain
* @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))));
}

/**
* @dev Gets the trusted address at a remote chain
* @param chain Chain name of the remote chain
* @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));
}

/**
* @dev Gets the trusted address hash at a remote chain
* @param chain Chain name of the remote chain
* @return trustedAddressHash the hash of the trusted address
*/
function getTrustedAddressHash(string memory chain) public view returns (bytes32 trustedAddressHash) {
trustedAddressHash = bytes32(getUint(_getTrustedAddressKey(chain)));
}

/**
* @dev Validates that the sender is a valid interchain token service address
* @param sourceChain Source chain of the transaction
* @param sourceAddress Source address of the transaction
* @return bool true if the sender is validated, false otherwise
*/
function validateSender(string calldata sourceChain, string calldata sourceAddress) external view returns (bool) {
bytes32 sourceAddressHash = keccak256(bytes(sourceAddress));

return sourceAddressHash == getTrustedAddressHash(sourceChain);
}

/**
* @dev Adds a trusted interchain token service address for the specified chain
* @param sourceChain Chain name of the interchain token service
* @param sourceAddress Interchain token service address to be added
*/
function addTrustedAddress(string memory sourceChain, string memory sourceAddress) public onlyOwner {
if (bytes(sourceChain).length == 0) revert ZeroStringLength();
if (bytes(sourceAddress).length == 0) revert ZeroStringLength();

_setTrustedAddress(sourceChain, sourceAddress);

emit TrustedAddressAdded(sourceChain, sourceAddress);
}

/**
* @dev Removes a trusted interchain token service address
* @param sourceChain Chain name of the interchain token service to be removed
*/
function removeTrustedAddress(string calldata sourceChain) external onlyOwner {
if (bytes(sourceChain).length == 0) revert ZeroStringLength();

_deleteString(_getTrustedAddressKey(sourceChain));
_deleteUint(_getTrustedAddressKey(sourceChain));

emit TrustedAddressRemoved(sourceChain);
}

/**
* @dev Fetches the interchain token service address for the specified chain
* @param chainName Name of the chain
* @return remoteAddress Interchain token service address for the specified chain
*/
function getRemoteAddress(string calldata chainName) external view returns (string memory remoteAddress) {
remoteAddress = getTrustedAddress(chainName);

if (bytes(remoteAddress).length == 0) {
revert UntrustedChain();
}
}
}

0 comments on commit b4705c8

Please sign in to comment.