Skip to content

Commit

Permalink
Merge pull request #515 from ava-labs/set-min-version
Browse files Browse the repository at this point in the history
L-02 No Ability to Specify the Initial _minTeleporterVersion
  • Loading branch information
geoff-vball authored Aug 30, 2024
2 parents 1e7d35c + 6cb3539 commit c8ca48a
Show file tree
Hide file tree
Showing 14 changed files with 149 additions and 78 deletions.

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions contracts/teleporter/registry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ contract ExampleApp is
// Constructor passes in the Teleporter registry address
// to the TeleporterRegistryApp contract.
constructor(
address teleporterRegistryAddress
) TeleporterRegistryApp(teleporterRegistryAddress) {
address teleporterRegistryAddress,
uint256 minTeleporterVersion
) TeleporterRegistryApp(teleporterRegistryAddress, minTeleporterVersion) {
currentBlockchainID = IWarpMessenger(WARP_PRECOMPILE_ADDRESS)
.getBlockchainID();
}
Expand Down
14 changes: 11 additions & 3 deletions contracts/teleporter/registry/TeleporterRegistryApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,23 @@ abstract contract TeleporterRegistryApp is Context, ITeleporterReceiver, Reentra
/**
* @dev Initializes the {TeleporterRegistryApp} contract by getting `teleporterRegistry`
* instance and setting `_minTeleporterVersion`.
* @param teleporterRegistryAddress The address of the Teleporter registry contract.
* The Teleporter registry contract should be deployed, and have at least one Teleporter version.
* @param minTeleporterVersion The minimum Teleporter version allowed for delivering messages.
* The minimum version should be less than or equal to the latest Teleporter version, and greater than 0.
*/
constructor(address teleporterRegistryAddress) {
constructor(address teleporterRegistryAddress, uint256 minTeleporterVersion) {
require(
teleporterRegistryAddress != address(0),
"TeleporterRegistryApp: zero teleporter registry address"
"TeleporterRegistryApp: zero Teleporter registry address"
);

teleporterRegistry = TeleporterRegistry(teleporterRegistryAddress);
_minTeleporterVersion = teleporterRegistry.latestVersion();
require(
teleporterRegistry.latestVersion() > 0,
"TeleporterRegistryApp: invalid Teleporter registry"
);
_setMinTeleporterVersion(minTeleporterVersion);
}

/**
Expand Down
27 changes: 16 additions & 11 deletions contracts/teleporter/registry/TeleporterRegistryAppUpgradeable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,32 +94,37 @@ abstract contract TeleporterRegistryAppUpgradeable is
/**
* @dev Initializes the {TeleporterRegistryApp} contract by getting `teleporterRegistry`
* instance and setting `_minTeleporterVersion`.
* @param teleporterRegistryAddress The address of the Teleporter registry contract.
* The Teleporter registry contract should be deployed, and have at least one Teleporter version.
* @param minTeleporterVersion The minimum Teleporter version allowed for delivering messages.
* The minimum version should be less than or equal to the latest Teleporter version, and greater than 0.
*/
// solhint-disable ordering
// solhint-disable-next-line func-name-mixedcase
function __TeleporterRegistryApp_init(address teleporterRegistryAddress)
internal
onlyInitializing
{
function __TeleporterRegistryApp_init(
address teleporterRegistryAddress,
uint256 minTeleporterVersion
) internal onlyInitializing {
__ReentrancyGuard_init();
__Context_init();
__TeleporterRegistryApp_init_unchained(teleporterRegistryAddress);
__TeleporterRegistryApp_init_unchained(teleporterRegistryAddress, minTeleporterVersion);
}

// solhint-disable-next-line func-name-mixedcase
function __TeleporterRegistryApp_init_unchained(address teleporterRegistryAddress)
internal
onlyInitializing
{
function __TeleporterRegistryApp_init_unchained(
address teleporterRegistryAddress,
uint256 minTeleporterVersion
) internal onlyInitializing {
require(
teleporterRegistryAddress != address(0),
"TeleporterRegistryApp: zero teleporter registry address"
"TeleporterRegistryApp: zero Teleporter registry address"
);

TeleporterRegistryAppStorage storage $ = _getTeleporterRegistryAppStorage();
TeleporterRegistry registry = TeleporterRegistry(teleporterRegistryAddress);
require(registry.latestVersion() > 0, "TeleporterRegistryApp: invalid Teleporter registry");
$._teleporterRegistry = registry;
$._minTeleporterVersion = registry.latestVersion();
_setMinTeleporterVersion(minTeleporterVersion);
}
// solhint-enable ordering

Expand Down
11 changes: 8 additions & 3 deletions contracts/teleporter/registry/TeleporterRegistryOwnableApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ import {Ownable} from "@openzeppelin/[email protected]/access/Ownable.sol";
abstract contract TeleporterRegistryOwnableApp is TeleporterRegistryApp, Ownable {
constructor(
address teleporterRegistryAddress,
address initialOwner
) TeleporterRegistryApp(teleporterRegistryAddress) Ownable(initialOwner) {}
address initialOwner,
uint256 minTeleporterVersion
)
TeleporterRegistryApp(teleporterRegistryAddress, minTeleporterVersion)
Ownable(initialOwner)
{}

/**
* @dev See {TeleporterRegistryApp-_checkTeleporterRegistryAppAccess}
*
* Checks that the caller is the owner of the contract for upgrade access.
* Checks that the caller is the owner of the contract for updating {minTeleporterVersion},
* and pausing/unpausing specific Teleporter version interactions.
*/
function _checkTeleporterRegistryAppAccess() internal view virtual override {
_checkOwner();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ abstract contract TeleporterRegistryOwnableAppUpgradeable is
// solhint-disable-next-line func-name-mixedcase
function __TeleporterRegistryOwnableApp_init(
address teleporterRegistryAddress,
address initialOwner
address initialOwner,
uint256 minTeleporterVersion
) internal onlyInitializing {
__TeleporterRegistryApp_init(teleporterRegistryAddress);
__TeleporterRegistryApp_init(teleporterRegistryAddress, minTeleporterVersion);
__Ownable_init(initialOwner);
}

Expand All @@ -34,7 +35,8 @@ abstract contract TeleporterRegistryOwnableAppUpgradeable is
/**
* @dev See {TeleporterRegistryAppUpgradeable-_checkTeleporterRegistryAppAccess}
*
* Checks that the caller is the owner of the contract for upgrade access.
* Checks that the caller is the owner of the contract for updating {minTeleporterVersion},
* and pausing/unpausing specific Teleporter version interactions.
*/
function _checkTeleporterRegistryAppAccess() internal view virtual override {
_checkOwner();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ import {TeleporterMessenger} from "@teleporter/TeleporterMessenger.sol";
import {UnitTestMockERC20} from "@mocks/UnitTestMockERC20.sol";

contract ExampleRegistryAppUpgradeable is TeleporterRegistryAppUpgradeable {
function initialize(address teleporterRegistryAddress) public initializer {
__TeleporterRegistryApp_init(teleporterRegistryAddress);
function initialize(
address teleporterRegistryAddress,
uint256 minTeleporterVersion
) public initializer {
__TeleporterRegistryApp_init(teleporterRegistryAddress, minTeleporterVersion);
}

function setMinTeleporterVersion(uint256 version) public {
Expand All @@ -40,9 +43,10 @@ contract ExampleRegistryAppUpgradeable is TeleporterRegistryAppUpgradeable {
}

contract ExampleRegistryApp is TeleporterRegistryApp {
constructor(address teleporterRegistryAddress)
TeleporterRegistryApp(teleporterRegistryAddress)
{}
constructor(
address teleporterRegistryAddress,
uint256 minTeleporterVersion
) TeleporterRegistryApp(teleporterRegistryAddress, minTeleporterVersion) {}

function setMinTeleporterVersion(uint256 version) public {
_setMinTeleporterVersion(version);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ import {ITeleporterMessenger, TeleporterMessageInput} from "@teleporter/ITelepor
contract ExampleRegistryOwnableAppUpgradeable is TeleporterRegistryOwnableAppUpgradeable {
function initialize(
address teleporterRegistryAddress,
address initialOwner
address initialOwner,
uint256 minTeleporterVersion
) public initializer {
__TeleporterRegistryOwnableApp_init(teleporterRegistryAddress, initialOwner);
__TeleporterRegistryOwnableApp_init(
teleporterRegistryAddress, initialOwner, minTeleporterVersion
);
}

function setMinTeleporterVersion(uint256 version) public {
Expand Down Expand Up @@ -48,8 +51,9 @@ contract ExampleRegistryOwnableAppUpgradeable is TeleporterRegistryOwnableAppUpg
contract ExampleRegistryOwnableApp is TeleporterRegistryOwnableApp {
constructor(
address teleporterRegistryAddress,
address initialOwner
) TeleporterRegistryOwnableApp(teleporterRegistryAddress, initialOwner) {}
address initialOwner,
uint256 minTeleporterVersion
) TeleporterRegistryOwnableApp(teleporterRegistryAddress, initialOwner, minTeleporterVersion) {}

function setMinTeleporterVersion(uint256 version) public {
_setMinTeleporterVersion(version);
Expand Down Expand Up @@ -225,7 +229,9 @@ abstract contract BaseTeleporterRegistryOwnableAppTest is BaseTeleporterRegistry
// Create a new Ownable app with a passed in teleporterManager
ExampleRegistryOwnableAppUpgradeable newOwnerApp =
new ExampleRegistryOwnableAppUpgradeable();
newOwnerApp.initialize(address(teleporterRegistry), DEFAULT_OWNER_ADDRESS);
newOwnerApp.initialize(
address(teleporterRegistry), DEFAULT_OWNER_ADDRESS, teleporterRegistry.latestVersion()
);

// Check that the teleporterManager is set correctly
assertEq(newOwnerApp.owner(), DEFAULT_OWNER_ADDRESS);
Expand Down
9 changes: 6 additions & 3 deletions contracts/teleporter/registry/tests/NonReentrantTests.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ import {TeleporterMessenger} from "@teleporter/TeleporterMessenger.sol";
uint32 constant warpMessageIndex = 2;

contract NonReentrantUpgradeableApp is TeleporterRegistryAppUpgradeable {
function initialize(address teleporterRegistryAddress) public initializer {
__TeleporterRegistryApp_init(teleporterRegistryAddress);
function initialize(
address teleporterRegistryAddress,
uint256 minTeleporterVersion
) public initializer {
__TeleporterRegistryApp_init(teleporterRegistryAddress, minTeleporterVersion);
}

function setMinTeleporterVersion(uint256 version) public {
Expand Down Expand Up @@ -65,7 +68,7 @@ abstract contract NonReentrantTest is BaseTeleporterRegistryAppTest {

function setUp() public virtual override {
nonReentrantApp = new NonReentrantUpgradeableApp();
nonReentrantApp.initialize(address(teleporterRegistry));
nonReentrantApp.initialize(address(teleporterRegistry), teleporterRegistry.latestVersion());
}

function testNonReentrantSameTeleporter() public {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@

pragma solidity 0.8.25;

import {
BaseTeleporterRegistryAppTest,
ExampleRegistryApp
} from "./BaseTeleporterRegistryAppTests.t.sol";
import {BaseTeleporterRegistryAppTest} from "./BaseTeleporterRegistryAppTests.t.sol";
import {
ITeleporterMessenger,
TeleporterMessageInput,
TeleporterFeeInfo
} from "@teleporter/ITeleporterMessenger.sol";
import {TeleporterRegistry, ProtocolRegistryEntry} from "../TeleporterRegistry.sol";
import {IERC20} from "@teleporter/TeleporterMessenger.sol";

abstract contract SendTeleporterMessageTest is BaseTeleporterRegistryAppTest {
Expand All @@ -37,28 +33,6 @@ abstract contract SendTeleporterMessageTest is BaseTeleporterRegistryAppTest {
);
}

function testNoRegisteredTeleporterSend() public {
// Create a new Teleporter registry with no registered Teleporters
TeleporterRegistry teleporterRegistry =
new TeleporterRegistry(new ProtocolRegistryEntry[](0));

// Create a new app with the new Teleporter registry
ExampleRegistryApp app = new ExampleRegistryApp(address(teleporterRegistry));

// Check that the app reverts when trying to send a message with no registered Teleporter
vm.expectRevert(_formatRegistryErrorMessage("zero version"));
app.sendTeleporterMessage(
TeleporterMessageInput({
destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID,
destinationAddress: DEFAULT_DESTINATION_ADDRESS,
feeInfo: TeleporterFeeInfo(address(0), 0),
requiredGasLimit: 0,
allowedRelayerAddresses: new address[](0),
message: hex"deadbeef"
})
);
}

function testSendNoFee() public {
TeleporterMessageInput memory messageInput = TeleporterMessageInput({
destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
ExampleRegistryAppUpgradeable
} from "./BaseTeleporterRegistryAppTests.t.sol";
import {NonReentrantTest} from "./NonReentrantTests.t.sol";
import {TeleporterRegistry, ProtocolRegistryEntry} from "../TeleporterRegistry.sol";

contract TeleporterRegistryAppTest is
GetTeleporterMessengerTest,
Expand All @@ -27,28 +28,73 @@ contract TeleporterRegistryAppTest is
{
function setUp() public virtual override (BaseTeleporterRegistryAppTest, NonReentrantTest) {
BaseTeleporterRegistryAppTest.setUp();
app = new ExampleRegistryApp(address(teleporterRegistry));
app =
new ExampleRegistryApp(address(teleporterRegistry), teleporterRegistry.latestVersion());
NonReentrantTest.setUp();
}

function testZeroRegistryAddress() public virtual {
vm.expectRevert(_formatErrorMessage("zero Teleporter registry address"));
app = new ExampleRegistryApp(address(0), 0);
}

function testInvalidRegistryAddress() public virtual {
vm.expectRevert(_formatErrorMessage("zero teleporter registry address"));
app = new ExampleRegistryApp(address(0));
// Create a new Teleporter registry with no registered Teleporters
TeleporterRegistry teleporterRegistry =
new TeleporterRegistry(new ProtocolRegistryEntry[](0));
vm.expectRevert(_formatErrorMessage("invalid Teleporter registry"));
app = new ExampleRegistryApp(address(teleporterRegistry), 0);
}

function testGreaterThanLatestVersion() public virtual {
uint256 minTeleporterVersion = teleporterRegistry.latestVersion() + 1;
vm.expectRevert(_formatErrorMessage("invalid Teleporter version"));
app = new ExampleRegistryApp(address(teleporterRegistry), minTeleporterVersion);
}

function testZeroMinTeleporterVersion() public virtual {
vm.expectRevert(_formatErrorMessage("not greater than current minimum version"));
app = new ExampleRegistryApp(address(teleporterRegistry), 0);
}
}

contract TeleporterRegistryAppUpgradeableTest is TeleporterRegistryAppTest {
function setUp() public virtual override {
TeleporterRegistryAppTest.setUp();
ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable();
upgradeableApp.initialize(address(teleporterRegistry));
upgradeableApp.initialize(address(teleporterRegistry), teleporterRegistry.latestVersion());
app = ExampleRegistryApp(address(upgradeableApp));
}

function testZeroRegistryAddress() public override {
ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable();
vm.expectRevert(_formatErrorMessage("zero Teleporter registry address"));
upgradeableApp.initialize(address(0), 0);
}

function testInvalidRegistryAddress() public override {
ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable();
vm.expectRevert(_formatErrorMessage("zero teleporter registry address"));
upgradeableApp.initialize(address(0));

// Create a new Teleporter registry with no registered Teleporters
TeleporterRegistry teleporterRegistry =
new TeleporterRegistry(new ProtocolRegistryEntry[](0));
vm.expectRevert(_formatErrorMessage("invalid Teleporter registry"));
upgradeableApp.initialize(address(teleporterRegistry), 0);
}

function testGreaterThanLatestVersion() public override {
ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable();

uint256 minTeleporterVersion = teleporterRegistry.latestVersion() + 1;
vm.expectRevert(_formatErrorMessage("invalid Teleporter version"));
upgradeableApp.initialize(address(teleporterRegistry), minTeleporterVersion);
}

function testZeroMinTeleporterVersion() public override {
ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable();

vm.expectRevert(_formatErrorMessage("not greater than current minimum version"));
upgradeableApp.initialize(address(teleporterRegistry), 0);
}

function testStorageSlot() public {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@ import {Ownable} from "@openzeppelin/[email protected]/access/Ownable.sol";
contract TeleporterRegistryOwnableAppTest is BaseTeleporterRegistryOwnableAppTest {
function setUp() public virtual override {
BaseTeleporterRegistryOwnableAppTest.setUp();
ownerApp = new ExampleRegistryOwnableApp(address(teleporterRegistry), DEFAULT_OWNER_ADDRESS);
ownerApp = new ExampleRegistryOwnableApp(
address(teleporterRegistry), DEFAULT_OWNER_ADDRESS, teleporterRegistry.latestVersion()
);
app = ExampleRegistryApp(address(ownerApp));
}

function testZeroInitialOwner() public virtual {
uint256 minTeleporterVersion = teleporterRegistry.latestVersion();
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0)));
ownerApp = new ExampleRegistryOwnableApp(address(teleporterRegistry), address(0));
ownerApp = new ExampleRegistryOwnableApp(
address(teleporterRegistry), address(0), minTeleporterVersion
);
}
}

Expand All @@ -31,15 +36,18 @@ contract TeleporterRegistryOwnableAppUpgradeableTest is BaseTeleporterRegistryOw
BaseTeleporterRegistryOwnableAppTest.setUp();
ExampleRegistryOwnableAppUpgradeable upgradeableApp =
new ExampleRegistryOwnableAppUpgradeable();
upgradeableApp.initialize(address(teleporterRegistry), DEFAULT_OWNER_ADDRESS);
upgradeableApp.initialize(
address(teleporterRegistry), DEFAULT_OWNER_ADDRESS, teleporterRegistry.latestVersion()
);
ownerApp = ExampleRegistryOwnableApp(address(upgradeableApp));
app = ExampleRegistryApp(address(ownerApp));
}

function testZeroInitialOwner() public {
ExampleRegistryOwnableAppUpgradeable upgradeableApp =
new ExampleRegistryOwnableAppUpgradeable();
uint256 minTeleporterVersion = teleporterRegistry.latestVersion();
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0)));
upgradeableApp.initialize(address(teleporterRegistry), address(0));
upgradeableApp.initialize(address(teleporterRegistry), address(0), minTeleporterVersion);
}
}
Loading

0 comments on commit c8ca48a

Please sign in to comment.