Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added Interchain Router #105

Merged
merged 19 commits into from
Oct 31, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rename interchain router to interchain address tracker
Foivos committed Oct 30, 2023
commit 6fd3e4b13286c3e96e99cb9e2a4f444e18c6d52f
2 changes: 1 addition & 1 deletion contracts/interfaces/IInterchainRouter.sol
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ 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 {
interface IInterchainAddressTracker is IContractIdentifier {
error ZeroAddress();
error LengthMismatch();
error ZeroStringLength();
6 changes: 3 additions & 3 deletions contracts/test/utils/TestInterchainRouterProxy.sol
Original file line number Diff line number Diff line change
@@ -2,14 +2,14 @@

pragma solidity ^0.8.0;

import { InterchainRouterProxy } from '../../utils/InterchainRouterProxy.sol';
import { InterchainAddressTrackerProxy } from '../../utils/InterchainAddressTrackerProxy.sol';

contract TestInterchainRouterProxy is InterchainRouterProxy {
contract TestInterchainAddressTrackerProxy is InterchainAddressTrackerProxy {
constructor(
address implementationAddress,
address owner,
bytes memory params
) InterchainRouterProxy(implementationAddress, owner, params) {
) InterchainAddressTrackerProxy(implementationAddress, owner, params) {
contractId();
}
}
8 changes: 4 additions & 4 deletions contracts/utils/InterchainRouter.sol
Original file line number Diff line number Diff line change
@@ -2,16 +2,16 @@

pragma solidity ^0.8.0;

import { IInterchainRouter } from '../interfaces/IInterchainRouter.sol';
import { IInterchainAddressTracker } from '../interfaces/IInterchainAddressTracker.sol';
import { Upgradable } from '../upgradable/Upgradable.sol';

import { StringStorage } from '../libs/StringStorage.sol';

/**
* @title InterchainRouter
* @title InterchainAddressTracker
* @dev Manages and validates remote addresses, keeps track of addresses supported by the Axelar gateway contract
*/
contract InterchainRouter is IInterchainRouter, Upgradable {
contract InterchainAddressTracker is IInterchainAddressTracker, Upgradable {
using StringStorage for string;

bytes32 internal constant PREFIX_ADDRESS_MAPPING = keccak256('interchain-router-address-mapping');
@@ -22,7 +22,7 @@ contract InterchainRouter is IInterchainRouter, Upgradable {
bytes32 private constant CONTRACT_ID = keccak256('interchain-router');

/**
* @dev Constructs the InterchainRouter contract, both array parameters must be equal in length.
* @dev Constructs the InterchainAddressTracker contract, both array parameters must be equal in length.
* @param chainName_ The name of the current chain.
*/
constructor(string memory chainName_) {
10 changes: 5 additions & 5 deletions contracts/utils/InterchainRouterProxy.sol
Original file line number Diff line number Diff line change
@@ -5,15 +5,15 @@ pragma solidity ^0.8.0;
import { Proxy } from '../upgradable/Proxy.sol';

/**
* @title InterchainRouterProxy
* @dev Proxy contract for the InterchainRouter contract. Inherits from the Proxy contract.
* @title InterchainAddressTrackerProxy
* @dev Proxy contract for the InterchainAddressTracker contract. Inherits from the Proxy contract.
*/
contract InterchainRouterProxy is Proxy {
contract InterchainAddressTrackerProxy is Proxy {
bytes32 private constant CONTRACT_ID = keccak256('interchain-router');

/**
* @dev Constructs the InterchainRouterProxy contract.
* @param implementationAddress Address of the InterchainRouter implementation
* @dev Constructs the InterchainAddressTrackerProxy contract.
* @param implementationAddress Address of the InterchainAddressTracker implementation
* @param owner Address of the owner of the proxy
* @param params The params to be passed to the _setup function of the implementation.
*/
80 changes: 40 additions & 40 deletions test/utils/InterchainRouter.js
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@ const {
const { expect } = chai;
const { deployContract } = require('../utils.js');

describe('InterchainRouter', () => {
let ownerWallet, otherWallet, interchainRouter, interchainRouterFactory;
describe('InterchainAddressTracker', () => {
let ownerWallet, otherWallet, interchainAddressTracker, interchainAddressTrackerFactory;

const otherRemoteAddress = 'any string as an address';
const otherChain = 'Other Name';
@@ -26,124 +26,124 @@ describe('InterchainRouter', () => {
defaultAddresses.push('another address format');
const implementation = await deployContract(
ownerWallet,
'InterchainRouter',
'InterchainAddressTracker',
[chainName],
);
const params = defaultAbiCoder.encode(
['string[]', 'string[]'],
[defaultChains, defaultAddresses],
);
interchainRouter = await deployContract(
interchainAddressTracker = await deployContract(
ownerWallet,
'InterchainRouterProxy',
'InterchainAddressTrackerProxy',
[implementation.address, ownerWallet.address, params],
);

interchainRouterFactory = await ethers.getContractFactory(
'InterchainRouter',
interchainAddressTrackerFactory = await ethers.getContractFactory(
'InterchainAddressTracker',
);
interchainRouter = interchainRouterFactory
.attach(interchainRouter.address)
interchainAddressTracker = interchainAddressTrackerFactory
.attach(interchainAddressTracker.address)
.connect(ownerWallet);
});

it('Should revert on interchainRouter deployment with invalid chain name', async () => {
it('Should revert on interchainAddressTracker deployment with invalid chain name', async () => {
await expect(
interchainRouterFactory.deploy(''),
).to.be.revertedWithCustomError(interchainRouter, 'ZeroStringLength');
interchainAddressTrackerFactory.deploy(''),
).to.be.revertedWithCustomError(interchainAddressTracker, 'ZeroStringLength');
});

it('Should revert on interchainRouter deployment with length mismatch between chains and trusted addresses arrays', async () => {
const interchainRouterImpl = await deployContract(
it('Should revert on interchainAddressTracker deployment with length mismatch between chains and trusted addresses arrays', async () => {
const interchainAddressTrackerImpl = await deployContract(
ownerWallet,
'InterchainRouter',
'InterchainAddressTracker',
[chainName],
);
const interchainRouterProxyFactory = await ethers.getContractFactory(
'InterchainRouterProxy',
const interchainAddressTrackerProxyFactory = await ethers.getContractFactory(
'InterchainAddressTrackerProxy',
);
const params = defaultAbiCoder.encode(
['string[]', 'string[]'],
[['Chain A'], []],
);
await expect(
interchainRouterProxyFactory.deploy(
interchainRouterImpl.address,
interchainAddressTrackerProxyFactory.deploy(
interchainAddressTrackerImpl.address,
ownerWallet.address,
params,
),
).to.be.revertedWithCustomError(interchainRouter, 'SetupFailed');
).to.be.revertedWithCustomError(interchainAddressTracker, 'SetupFailed');
});

it('Should get empty strings for the remote address for unregistered chains', async () => {
expect(await interchainRouter.getTrustedAddress(otherChain)).to.equal('');
expect(await interchainAddressTracker.getTrustedAddress(otherChain)).to.equal('');
});

it('Should be able to validate remote addresses properly', async () => {
expect(
await interchainRouter.validateSender(otherChain, otherRemoteAddress),
await interchainAddressTracker.validateSender(otherChain, otherRemoteAddress),
).to.equal(false);
});

it('Should not be able to add a custom remote address as not the owner', async () => {
await expect(
interchainRouter
interchainAddressTracker
.connect(otherWallet)
.addTrustedAddress(otherChain, otherRemoteAddress),
).to.be.revertedWithCustomError(interchainRouter, 'NotOwner');
).to.be.revertedWithCustomError(interchainAddressTracker, 'NotOwner');
});

it('Should be able to add a custom remote address as the owner', async () => {
await expect(
interchainRouter.addTrustedAddress(otherChain, otherRemoteAddress),
interchainAddressTracker.addTrustedAddress(otherChain, otherRemoteAddress),
)
.to.emit(interchainRouter, 'TrustedAddressAdded')
.to.emit(interchainAddressTracker, 'TrustedAddressAdded')
.withArgs(otherChain, otherRemoteAddress);
expect(await interchainRouter.getTrustedAddress(otherChain)).to.equal(
expect(await interchainAddressTracker.getTrustedAddress(otherChain)).to.equal(
otherRemoteAddress,
);
});

it('Should revert on adding a custom remote address with an empty chain name', async () => {
await expect(
interchainRouter.addTrustedAddress('', otherRemoteAddress),
).to.be.revertedWithCustomError(interchainRouter, 'ZeroStringLength');
interchainAddressTracker.addTrustedAddress('', otherRemoteAddress),
).to.be.revertedWithCustomError(interchainAddressTracker, 'ZeroStringLength');
});

it('Should revert on adding a custom remote address with an invalid remote address', async () => {
await expect(
interchainRouter.addTrustedAddress(otherChain, ''),
).to.be.revertedWithCustomError(interchainRouter, 'ZeroStringLength');
interchainAddressTracker.addTrustedAddress(otherChain, ''),
).to.be.revertedWithCustomError(interchainAddressTracker, 'ZeroStringLength');
});

it('Should be able to validate remote addresses properly.', async () => {
expect(
await interchainRouter.validateSender(otherChain, otherRemoteAddress),
await interchainAddressTracker.validateSender(otherChain, otherRemoteAddress),
).to.equal(true);
});

it('Should not be able to remove a custom remote address as not the owner', async () => {
await expect(
interchainRouter.connect(otherWallet).removeTrustedAddress(otherChain),
).to.be.revertedWithCustomError(interchainRouter, 'NotOwner');
interchainAddressTracker.connect(otherWallet).removeTrustedAddress(otherChain),
).to.be.revertedWithCustomError(interchainAddressTracker, 'NotOwner');
});

it('Should be able to remove a custom remote address as the owner', async () => {
await expect(interchainRouter.removeTrustedAddress(otherChain))
.to.emit(interchainRouter, 'TrustedAddressRemoved')
await expect(interchainAddressTracker.removeTrustedAddress(otherChain))
.to.emit(interchainAddressTracker, 'TrustedAddressRemoved')
.withArgs(otherChain);
expect(await interchainRouter.getTrustedAddress(otherChain)).to.equal('');
expect(await interchainAddressTracker.getTrustedAddress(otherChain)).to.equal('');
});

it('Should revert on removing a custom remote address with an empty chain name', async () => {
await expect(
interchainRouter.removeTrustedAddress(''),
).to.be.revertedWithCustomError(interchainRouter, 'ZeroStringLength');
interchainAddressTracker.removeTrustedAddress(''),
).to.be.revertedWithCustomError(interchainAddressTracker, 'ZeroStringLength');
});

it('Should be able to validate remote addresses properly.', async () => {
expect(
await interchainRouter.validateSender(otherChain, otherRemoteAddress),
await interchainAddressTracker.validateSender(otherChain, otherRemoteAddress),
).to.equal(false);
});
});