Skip to content

Commit

Permalink
cleanup comments
Browse files Browse the repository at this point in the history
  • Loading branch information
cam-schultz committed Oct 31, 2023
1 parent 439b8da commit 975ada1
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 15 deletions.
12 changes: 6 additions & 6 deletions contracts/src/CrossChainApplications/ERC20Bridge/ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ contract ERC20Bridge is
uint256 public constant TRANSFER_BRIDGE_TOKENS_REQUIRED_GAS = 300_000;

/**
* @dev Initializes the Teleporter messenger used for sending and receiving messages,
* @dev Initializes the Teleporter Messenger used for sending and receiving messages,
* and initializes the current chain ID.
*/
constructor(
Expand Down Expand Up @@ -410,7 +410,7 @@ contract ERC20Bridge is
* Emits a {CreateBridgeToken} event.
*
* Note: This function is only called within `receiveTeleporterMessage`, which can only be
* called by the Teleporter messenger.
* called by the Teleporter Messenger.
*/
function _createBridgeToken(
bytes32 nativeChainID,
Expand Down Expand Up @@ -458,7 +458,7 @@ contract ERC20Bridge is
* Emits a {MintBridgeTokens} event.
*
* Note: This function is only called within `receiveTeleporterMessage`, which can only be
* called by the Teleporter messenger.
* called by the Teleporter Messenger.
*/
function _mintBridgeTokens(
bytes32 nativeChainID,
Expand Down Expand Up @@ -492,7 +492,7 @@ contract ERC20Bridge is
* and optionally routing them to a different third chain.
*
* Note: This function is only called within `receiveTeleporterMessage`, which can only be
* called by the Teleporter messenger.
* called by the Teleporter Messenger.
*/
function _transferBridgeTokens(
bytes32 sourceChainID,
Expand Down Expand Up @@ -591,7 +591,7 @@ contract ERC20Bridge is
ITeleporterMessenger teleporterMessenger = teleporterRegistry
.getLatestTeleporter();

// Allow the Teleporter messenger to spend the fee amount.
// Allow the Teleporter Messenger to spend the fee amount.
if (feeAmount > 0) {
IERC20(nativeContractAddress).safeIncreaseAllowance(
address(teleporterMessenger),
Expand Down Expand Up @@ -650,7 +650,7 @@ contract ERC20Bridge is
.getLatestTeleporter();

// If necessary, transfer the primary fee amount to this contract and approve the
// Teleporter messenger to spend it when the first message back to the native subnet
// Teleporter Messenger to spend it when the first message back to the native subnet
// is submitted. The secondary fee amount is then handled by the native subnet when
// submitting a message to the destination chain, if applicable.
uint256 adjustedPrimaryFeeAmount = 0;
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/CrossChainApplications/ERC20Bridge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The generic ERC20 bridge is implemented using two primary contracts.
- Bridge contract that uses Teleporter to facilitate the bridging operations of adding new supported tokens and moving tokens between chains.
- The bridge contract tracks the balances of each token sent to other bridge instances, and only allows those bridge instances to redeem up to the amount of tokens that has been previously sent to them.
- Primary functions include:
- `submitCreateBridgeToken`: Called on the origin chain to add support for an ERC20 native to the chain to a bridge instance on a different chain. Submits a Teleporter message that invokes `createBridgeToken` on the destination chain.
- `submitCreateBridgeToken`: Called on the origin chain to add support for an ERC20 on a different chain's bridge instance. Submits a Teleporter message that invokes `createBridgeToken` on the destination chain.
- `createBridgeToken`: Called by cross-chain messages to add support for a new bridge token from another chain. Assuming the token is not already supported, deploys a new `BridgeToken` contract instance to represent the tokens on this chain.
- `bridgeTokens`: Called to move supported tokens from one chain to another. This includes both "wrapping" of tokens native to the chain and also "unwrapping" of bridge tokens on the chain to other chains. In the case of unwrapping or moving of a bridge token, if the destination chain ID is the native chain for the given token, the original token is sent to the recipient on the destination. If the destination chain ID is another non-native chain for the underlying token, a Teleporter message is first sent to the native chain, which then subsequently updates its accounting of balances and sends a Teleporter message on the destination chain to re-wrap the given tokens. This multi-hop flow is illustrated below.
- `mintBridgeTokens`: Called by cross-chain messages in the event of new bridge transfers of tokens from their native chains.
Expand Down
6 changes: 3 additions & 3 deletions contracts/src/CrossChainApplications/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ contract MyExampleCrossChainMessenger {}

Now that the initial empty `MyExampleCrossChainMessenger` is defined, it's time to integrate the `ITeleporterMessenger` that will provide the functionality to deliver cross chain messages.

Create a state variable of `ITeleporterMessenger` type called `teleporterMessenger`. Then create a constructor for our contract that takes in an address where the Teleporter messenger would be deployed on this chain, and set our state variable with it.
Create a state variable of `ITeleporterMessenger` type called `teleporterMessenger`. Then create a constructor for our contract that takes in an address where the Teleporter Messenger would be deployed on this chain, and set our state variable with it.

```solidity
contract ExampleCrossChainMessenger {
Expand Down Expand Up @@ -85,7 +85,7 @@ function receiveTeleporterMessage(
) external {
```

Now it's time to implement the methods, starting with `sendMessage`. First, import OpenZeppelin's `IERC20` contract, then in `sendMessage` check whether `feeAmount` is greater than zero. If it is, transfer and approve the amount of IERC20 asset at `feeContractAddress` to the teleporter messenger saved as a state variable.
Now it's time to implement the methods, starting with `sendMessage`. First, import OpenZeppelin's `IERC20` contract, then in `sendMessage` check whether `feeAmount` is greater than zero. If it is, transfer and approve the amount of IERC20 asset at `feeContractAddress` to the Teleporter Messenger saved as a state variable. Relayer fees are an optional way to incentive relayers to deliver a Teleporter message to its destination. They are not strictly necessary, and may be omitted if relaying is guaranteed, such as with a self-hosted relayer.

```solidity
// For non-zero fee amounts, transfer the fee into the control of this contract first, and then
Expand Down Expand Up @@ -125,7 +125,7 @@ return
);
```

With the sending side complete, the next step is to implement `receiveTeleporterMessage`. The receiver in this example will just receive the arbitrary string data, and check that the message is sent through Teleporter.
With the sending side complete, the next step is to implement `ITeleporterReceiver.receiveTeleporterMessage`. The receiver in this example will just receive the arbitrary string data, and check that the message is sent through Teleporter.

```solidity
// Receive a new message from another chain.
Expand Down
8 changes: 5 additions & 3 deletions contracts/src/Teleporter/ITeleporterMessenger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ interface ITeleporterMessenger {

/**
* @dev Emitted when a Teleporter message is being delivered on the destination chain to an address,
* but message execution fails. Failed messages can then be retried.
* but message execution fails. Failed messages can then be retried with `retryMessageExecution`
*/
event MessageExecutionFailed(
bytes32 indexed originChainID,
Expand Down Expand Up @@ -151,8 +151,10 @@ interface ITeleporterMessenger {
* @dev Retries the execution of a previously delivered message by verifying the payload matches
* the hash of the payload originally delivered, and calling the destination address again.
*
* Intended to be used if the original required gas limit was not sufficient for the message
* execution. Messages are ensured to be successfully executed at most once.
* Intended to be used if message excution failed on initial delivery of the Teleporter message.
* For example, this may occur if the original required gas limit was not sufficient for the message
* execution, or if the destination address did not contain a contract, but a compatible contract
* was later deployed to that address. Messages are ensured to be successfully executed at most once.
*/
function retryMessageExecution(
bytes32 originChainID,
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/Teleporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Teleporter provides a handful of useful properties to cross-chain applications t
Fees can be paid on a per message basis by specifing the ERC20 asset and amount to be used to incentivize a relayer to deliver the message in the call to `sendCrossChainMessage`. The fee amount is transferred into the control of the Teleporter contract (i.e. locked) before the Warp message is sent. The Teleporter contract tracks the fee amount for each message ID it creates. When it subsquently receives a message back from the destination chain of the original message, the new message will have a list of receipts identifying the relayer that delivered the given message ID. At this point, the fee amount originally locked by Teleporter for the given message will be redeemable by the relayer identified in the receipt. If the initial fee amount was not sufficient to incentivize a relayer, it can be increased by calling `addFeeAmount`.

### Message Receipts and Fee Redemption
In order to confirm delivery of a Teleporter message from one chain to another, a receipt is included in the next Teleporter message sent in the opposite direction. This receipt contains the message ID of the original message, as well as the address of the relayer that delivered it. That address is then able to redeem the reward on the original chain by calling `redeemRelayerRewards`. The following example illustrates this flow:
In order to confirm delivery of a Teleporter message from a source chain to a destination chain, a receipt is included in the next Teleporter message sent in the opposite direction, from the destination chain back to the source chain. This receipt contains the message ID of the original message, as well as the reward address that the delivering relayer specified. That reward address is then able to redeem the corresponding reward on the original chain by calling `redeemRelayerRewards`. The following example illustrates this flow:
- A Teleporter message is sent from Chain A to Chain B, with a relayer incentive of `10` `USDC`. This message is assigned the ID `1` by the Teleporter contract on Chain A.
- On Chain A, this is done by calling `sendCrossChainMessage`, and providing the `USDC` contract address and amount in the function call.
- A relayer delivers the message on Chain B by calling `receiveCrossChainMessage` and providing its address, `0x123...`
Expand All @@ -49,7 +49,7 @@ In order to confirm delivery of a Teleporter message from one chain to another,
It is possible for receipts to get "stuck" on the destination chain in the event that Teleporter traffic between two chains is skewed in one direction. In such a scenario, incoming messages on one chain may cause the rate at which receipts are generated to outpace the rate at which they are sent back to the other chain. To mitigate this, the method `retryReceipts` can be called to immediately send the receipts associated with the given message IDs back to the original chain.

## Required Interface
Teleporter messages are delivered by calling the `receiveTeleporterMessage` function defined by the `ITeleporterReceiver` interface. Contracts must implement this interface in order to be able to receive messages. The first two paramaters of `receiveTeleporterMessage` identify the original sender of the given message on the origin chain and are set by the `TeleporterMessenger`. The third parameter to `receiveTeleporterMessage`, is the raw message payload. Applications using Teleporter are responsible for defining the exact format of this payload in a way that can be decoded on the receiving end. For example, applications may encode an action enum value along with the target method parameters on the sending side, then decode this data and route to the target method within `receiveTeleporterMessage`. See `ERC20Bridge.sol` for an example of this approach.
Teleporter messages are delivered by calling the `receiveTeleporterMessage` function defined by the `ITeleporterReceiver` interface. Contracts must implement this interface in order to be able to receive messages. The first two parameters of `receiveTeleporterMessage` identify the original sender of the given message on the origin chain and are set by the `TeleporterMessenger`. The third parameter to `receiveTeleporterMessage`, is the raw message payload. Applications using Teleporter are responsible for defining the exact format of this payload in a way that can be decoded on the receiving end. For example, applications may encode an action enum value along with the target method parameters on the sending side, then decode this data and route to the target method within `receiveTeleporterMessage`. See `ERC20Bridge.sol` for an example of this approach.

## Teleporter Contract Deployment
The `TeleporterMessenger` contract must be deployed to the same contract address on every chain. This is acheived using Nick's keyless transaction method as described [here](../../../utils/contract-deployment/README.md). As a result, Warp messages sent from the resulting contract address are ensured to have the same payload format as defined by the contract itself.
Expand Down
6 changes: 6 additions & 0 deletions contracts/src/Teleporter/TeleporterMessenger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,12 @@ contract TeleporterMessenger is ITeleporterMessenger, ReentrancyGuards {
/**
* @dev See {ITeleporterMessenger-retryMessageExecution}
*
* A Teleporter message has an associated `requiredGasLimit` that is used to execute the message.
* If the `requiredGasLimit` is too low, then the message execution will fail. This method allows
* for retrying the execution of a message with a higher gas limit. Contrary to `receiveCrossChainMessage`,
* which will only use `requiredGasLimit` in the sub-call to execute the message, this method may
* use all of the gas available in the transaction.
*
* Reverts if the message execution fails again on the specified message.
* Emits a {MessageExecuted} event if the retry is successful.
* Requirements:
Expand Down

0 comments on commit 975ada1

Please sign in to comment.