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

OpenZeppelin Audit Cleanup Items #106

Merged
merged 41 commits into from
Nov 9, 2023

Conversation

michaelkaplan13
Copy link
Collaborator

Why this should be merged

Addresses clean up items from the first version of the OpenZeppelin audit report (to be published at a later date).

How this works

  • Sets the visibility level to private for non-constant and non-immutable state variables in abstract contracts to avoid inheriting contracts from being able to override their behavior.
  • Adds docstrings to all structs.
  • Adds security contact link to contract source code.
  • Removes unused state variables.
  • Adds named parameters of mappings.
  • Removes unused named return variables in favor of explicitly returned values.
  • Uses explicit imports for contracts under Teleporter/
  • Makes relayerRewardAddresses and relayerRewardAmounts mappings internal to avoid redundant getter functions. Preferable than removing the explicit getter functions which are defined in the interface.
  • Fixes typos.
  • Adds getNextMessageID to the ITeleporterMessenger interface.
  • Updates documentation comments of SafeERC20TransferFrom
  • Removes unused external checkIsAllowedRelayer function.
  • Uses Math library for min calculation in receipt array sizes

How this was tested

Unit tests and CI.

How is this documented

N/A

Comment on lines 8 to 10
// A message receipt identifies the message ID that was
// delivered and address that should be able to redeem the
// reward for that message.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// A message receipt identifies the message ID that was
// delivered and address that should be able to redeem the
// reward for that message.
// A message receipt identifies the message ID that was
// delivered and the address that can redeem the
// rewards for that message.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. I think singular "reward" is correct in this case, but fixed the other.

// to be sent to the given destination chain ID and address. Includes the fee
// information for the message, the amount of gas the relayer must provide to execute
// the message on the destination chain, the relayer accounts allowed to deliver the
// message, and the message data itself.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one of the points in the audit points out we only use this struct as a parameter, do we want to remove and just pass in arguments to functions?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you changed the _sendTeleporterMessage input to be TeleporterMessageInput, but thoughts on removing it as requirement for the interface, and moving to struct to TeleporterMessenger? Not a big deal either way imo

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of the TeleporterMessageInput struct is actually needed in order to reduce the depth of the stack in both _sendTeleporterMessage and sendTeleporterMessage.

contracts/src/Teleporter/ITeleporterMessenger.sol Outdated Show resolved Hide resolved
@@ -5,18 +5,26 @@

pragma solidity 0.8.18;

import "./ITeleporterMessenger.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a rule in solhint.json for no-global-imports we can remove, but would require us to handle explicit imports in the cross chain apps as well, and probably ignore linting the tests folders.

Looking into whether we can have lint rules different between directories/files.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@minghinmatthewlam We could ignore the tests folder for the current solhint run, and give the tests folder it's own solhint.json and check.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not opposed to enabling the no-global-imports linting rule and correcting everywhere needed now. It will put us in the best position moving forward I think.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated now. I think having different linting rules for different directories would likely cause more confusion that benefits.

contracts/src/Teleporter/ReceiptQueue.sol Outdated Show resolved Hide resolved
@@ -287,7 +282,7 @@ contract TeleporterMessenger is ITeleporterMessenger, ReentrancyGuards {
// Check the message has not been delivered before by checking that there is no relayer reward
// address stored for it already.
require(
relayerRewardAddresses[warpMessage.sourceChainID][
_relayerRewardAddresses[warpMessage.sourceChainID][

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think instead of checking _relayerRewardAddresses directly here, we should make an internal _messageReceived and use that check here to make it more clear.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That wasn't an item called out in the audit, so I think it's out of scope for this PR.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it falls under L-08 Semantic Overload for relayerRewardAddress

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, I personally am not super inclined to make the change given it increases overall contract size and gas costs and the check is properly described in the comment directly above here. If others feel strongly though I'm open to it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you say gas costs do you mean the increase in gas for deployment, or are you expecting an increase in gas for wrappign the check now in a function call?

Either way think the gas cost is minor in favor of more readable code so would be my vote.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, yeah I checked the forge test --gas-report before and after making those change, and it was a very minor increase.

I added an internal _messageReceived now.

contracts/src/Teleporter/TeleporterMessenger.sol Outdated Show resolved Hide resolved
TeleporterMessengerTest.setUp();
}

contract CheckIsAllowedRelayerTest is TeleporterMessenger, Test {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to test internal functions of TeleproterMessenger by making derived contracts? I would lean towards _checkIsAllowedRealyer being tested in TeleporterMessengerTests

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the motivation for not wanting it to be in its own test suite? It makes it easier to find and isolate IMO.

I don't love making a derived contract to test internal functions, but I think it's the easy option that provides the needed coverage.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good with the derived contract and own test suite, just want to make sure consistent with how other internal functions were tested.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was actually the first internal method in the TeleporterMessenger contract. 👍

They theoretically could be tested through various inputs to the public/external methods that call them, but in this case I think I'd rather keep the isolated test coverage for it specifically.

@@ -5,7 +5,7 @@

pragma solidity 0.8.18;

import "./TeleporterRegistry.sol";
import {TeleporterRegistry} from "./TeleporterRegistry.sol";

/**
* @dev TeleporterUpgradeable provides upgrade utility for applications built on top

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't comment on line, but confirming for minTeleporterVersion we can't change visbility, since derived contracts will need to implement updateMinTeleporterVersion and have access to the state variable. Trying to think how we can only allow updating in updateMinTeleporterVersion

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should add a comment at that state variable explaining this special case and why it diverges from Solidity best practices.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Adding now

contracts/src/WarpProtocolRegistry.sol Show resolved Hide resolved
contracts/src/Teleporter/ITeleporterMessenger.sol Outdated Show resolved Hide resolved
@@ -5,18 +5,26 @@

pragma solidity 0.8.18;

import "./ITeleporterMessenger.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@minghinmatthewlam We could ignore the tests folder for the current solhint run, and give the tests folder it's own solhint.json and check.

contracts/src/Teleporter/TeleporterMessenger.sol Outdated Show resolved Hide resolved
michaelkaplan13 and others added 12 commits November 6, 2023 11:31
Co-authored-by: minghinmatthewlam <matthew.lam@avalabs.org>
Signed-off-by: Michael Kaplan <55204436+michaelkaplan13@users.noreply.github.com>
Co-authored-by: minghinmatthewlam <matthew.lam@avalabs.org>
Signed-off-by: Michael Kaplan <55204436+michaelkaplan13@users.noreply.github.com>
…bs/teleporter into open-zeppelin-audit-cleanup-items
Copy link
Contributor

@cam-schultz cam-schultz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of small comments, including an amendment to a suggestion I previously made.

# Use lower_case variables in the scripts and UPPER_CASE variables for override
# Use the constants.sh for env overrides

TELEPORTER_PATH=$(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for removing this and putting it in the other scripts? My thinking was that we could put this here and source constants.sh everywhere that needs it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my originally thinking also, but then I realized having TELEPORTER_PATH set in each individual script is consistent with the pattern used in the subnet-evm scripts.

The reason is that sourcing the constants.sh file from a script requires knowing where the script is in relation to to the current working directory the script is being called from. So it's less error prone to set the relative path to the base of the repo from each script individual (no matter where it's called from), and then source constants.sh relative from there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pesky chickens and eggs 😆 Makes sense

#
# We use "export" here instead of just setting a bash variable because we need
# to pass this flag to all child processes spawned by the shell.
export CGO_CFLAGS="-O -D__BLST_PORTABLE__"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this still need to be here now that it's included in constants.sh?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, thanks for catching.

contracts/src/Teleporter/TeleporterMessenger.sol Outdated Show resolved Hide resolved
michaelkaplan13 and others added 2 commits November 8, 2023 12:46
Co-authored-by: cam-schultz <78878559+cam-schultz@users.noreply.github.com>
Signed-off-by: Michael Kaplan <55204436+michaelkaplan13@users.noreply.github.com>
cam-schultz
cam-schultz previously approved these changes Nov 8, 2023
Copy link
Contributor

@cam-schultz cam-schultz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@@ -9,7 +9,7 @@ on:
- "*"

env:
RELAYER_VERSION: v0.2.2
RELAYER_VERSION: v0.2.3

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also update the other references to relayer version v0.2.2. in docker run/test

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch 👍

Copy link

@minghinmatthewlam minghinmatthewlam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

cam-schultz
cam-schultz previously approved these changes Nov 8, 2023
bernard-avalabs
bernard-avalabs previously approved these changes Nov 9, 2023
Copy link
Contributor

@bernard-avalabs bernard-avalabs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

// case where there is no fee to be paid for the given message.
if (messageInfo.messageHash == bytes32(0)) {
return;
}

// Delete the message information from state now that we know it has been delivered.
// Delete the message information from state now that it is known to be delivered.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "it is known to be" seems a bit awkward. Can we just say "... now that the message has been delivered"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to leave it as because technically the fact that the message is delivered isn't enough to delete it from state here. The sending chain has to be informed of the delivery via a receipt.


/**
* @dev The minimum required Teleporter version that the contract is allowed
* to receive messages from. Should only be update through the `updateMinTeleporterVersion`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: update -> updated

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed 👍

@michaelkaplan13 michaelkaplan13 merged commit 8822b97 into main Nov 9, 2023
@michaelkaplan13 michaelkaplan13 deleted the open-zeppelin-audit-cleanup-items branch November 9, 2023 17:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants