Skip to content

Commit

Permalink
Merge pull request #146 from ava-labs/refactor-fee-info-v2
Browse files Browse the repository at this point in the history
Refactor fee info v2
  • Loading branch information
michaelkaplan13 authored Nov 21, 2023
2 parents 75f352c + 1e59e31 commit 8b66551
Show file tree
Hide file tree
Showing 15 changed files with 69 additions and 69 deletions.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ contract ERC20Bridge is
destinationChainID: destinationChainID,
destinationAddress: destinationBridgeAddress,
feeInfo: TeleporterFeeInfo({
contractAddress: messageFeeAsset,
feeTokenAddress: messageFeeAsset,
amount: adjustedFeeAmount
}),
requiredGasLimit: CREATE_BRIDGE_TOKENS_REQUIRED_GAS,
Expand Down Expand Up @@ -598,7 +598,7 @@ contract ERC20Bridge is
destinationChainID: destinationChainID,
destinationAddress: destinationBridgeAddress,
feeInfo: TeleporterFeeInfo({
contractAddress: nativeContractAddress,
feeTokenAddress: nativeContractAddress,
amount: feeAmount
}),
requiredGasLimit: MINT_BRIDGE_TOKENS_REQUIRED_GAS,
Expand Down Expand Up @@ -692,7 +692,7 @@ contract ERC20Bridge is
destinationChainID: nativeChainID,
destinationAddress: nativeBridgeAddress,
feeInfo: TeleporterFeeInfo({
contractAddress: wrappedTransferInfo.wrappedContractAddress,
feeTokenAddress: wrappedTransferInfo.wrappedContractAddress,
amount: adjustedPrimaryFeeAmount
}),
requiredGasLimit: TRANSFER_BRIDGE_TOKENS_REQUIRED_GAS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ contract ERC20BridgeTest is Test {
destinationChainID: _DEFAULT_OTHER_CHAIN_ID,
destinationAddress: _DEFAULT_OTHER_BRIDGE_ADDRESS,
feeInfo: TeleporterFeeInfo({
contractAddress: address(mockERC20),
feeTokenAddress: address(mockERC20),
amount: 0
}),
requiredGasLimit: erc20Bridge.MINT_BRIDGE_TOKENS_REQUIRED_GAS(),
Expand Down Expand Up @@ -321,7 +321,7 @@ contract ERC20BridgeTest is Test {
destinationChainID: _DEFAULT_OTHER_CHAIN_ID,
destinationAddress: _DEFAULT_OTHER_BRIDGE_ADDRESS,
feeInfo: TeleporterFeeInfo({
contractAddress: address(mockERC20),
feeTokenAddress: address(mockERC20),
amount: feeAmount
}),
requiredGasLimit: erc20Bridge.MINT_BRIDGE_TOKENS_REQUIRED_GAS(),
Expand Down Expand Up @@ -424,7 +424,7 @@ contract ERC20BridgeTest is Test {
destinationChainID: _DEFAULT_OTHER_CHAIN_ID,
destinationAddress: _DEFAULT_OTHER_BRIDGE_ADDRESS,
feeInfo: TeleporterFeeInfo({
contractAddress: address(mockERC20),
feeTokenAddress: address(mockERC20),
amount: bridgeFeeAmount
}),
requiredGasLimit: erc20Bridge.MINT_BRIDGE_TOKENS_REQUIRED_GAS(),
Expand Down Expand Up @@ -705,7 +705,7 @@ contract ERC20BridgeTest is Test {
destinationChainID: destinationChainID,
destinationAddress: destinationBridgeAddress,
feeInfo: TeleporterFeeInfo({
contractAddress: address(0),
feeTokenAddress: address(0),
amount: 0
}),
requiredGasLimit: erc20Bridge
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ contract ExampleCrossChainMessenger is
event SendMessage(
bytes32 indexed destinationChainID,
address indexed destinationAddress,
address feeAsset,
address feeTokenAddress,
uint256 feeAmount,
uint256 requiredGasLimit,
string message
Expand Down Expand Up @@ -79,7 +79,7 @@ contract ExampleCrossChainMessenger is
function sendMessage(
bytes32 destinationChainID,
address destinationAddress,
address feeContractAddress,
address feeTokenAddress,
uint256 feeAmount,
uint256 requiredGasLimit,
string calldata message
Expand All @@ -91,10 +91,10 @@ contract ExampleCrossChainMessenger is
uint256 adjustedFeeAmount = 0;
if (feeAmount > 0) {
adjustedFeeAmount = SafeERC20TransferFrom.safeTransferFrom(
IERC20(feeContractAddress),
IERC20(feeTokenAddress),
feeAmount
);
IERC20(feeContractAddress).safeIncreaseAllowance(
IERC20(feeTokenAddress).safeIncreaseAllowance(
address(teleporterMessenger),
adjustedFeeAmount
);
Expand All @@ -103,7 +103,7 @@ contract ExampleCrossChainMessenger is
emit SendMessage({
destinationChainID: destinationChainID,
destinationAddress: destinationAddress,
feeAsset: feeContractAddress,
feeTokenAddress: feeTokenAddress,
feeAmount: adjustedFeeAmount,
requiredGasLimit: requiredGasLimit,
message: message
Expand All @@ -114,7 +114,7 @@ contract ExampleCrossChainMessenger is
destinationChainID: destinationChainID,
destinationAddress: destinationAddress,
feeInfo: TeleporterFeeInfo({
contractAddress: feeContractAddress,
feeTokenAddress: feeTokenAddress,
amount: adjustedFeeAmount
}),
requiredGasLimit: requiredGasLimit,
Expand Down
12 changes: 6 additions & 6 deletions contracts/src/CrossChainApplications/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ To start, create the function declarations for `sendMessage`, which will send st
function sendMessage(
bytes32 destinationChainID,
address destinationAddress,
address feeContractAddress,
address feeTokenAddress,
uint256 feeAmount,
uint256 requiredGasLimit,
string calldata message
Expand All @@ -86,19 +86,19 @@ 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. 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 a relayer is willing to relay messages with no fee, such as with a self-hosted relayer.
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 `feeTokenAddress` 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 a relayer is willing to relay messages with no fee, 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
// allow the Teleporter contract to spend it.
if (feeAmount > 0) {
IERC20 feeAsset = IERC20(feeContractAddress);
IERC20 feeToken = IERC20(feeTokenAddress);
require(
feeAsset.transferFrom(msg.sender, address(this), feeAmount),
feeToken.transferFrom(msg.sender, address(this), feeAmount),
"Failed to transfer fee amount"
);
require(
feeAsset.approve(address(teleporterMessenger), feeAmount),
feeToken.approve(address(teleporterMessenger), feeAmount),
"Failed to approve fee amount"
);
}
Expand All @@ -116,7 +116,7 @@ return
destinationChainID: destinationChainID,
destinationAddress: destinationAddress,
feeInfo: TeleporterFeeInfo({
contractAddress: feeContractAddress,
feeTokenAddress: feeTokenAddress,
amount: feeAmount
}),
requiredGasLimit: requiredGasLimit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ contract BlockHashPublisher {
destinationChainID: destinationChainID,
destinationAddress: destinationAddress,
feeInfo: TeleporterFeeInfo({
contractAddress: address(0),
feeTokenAddress: address(0),
amount: 0
}),
requiredGasLimit: RECEIVE_BLOCK_HASH_REQUIRED_GAS_LIMIT,
Expand Down
14 changes: 7 additions & 7 deletions contracts/src/Teleporter/ITeleporterMessenger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct TeleporterMessage {
// The contract address is the asset contract the fee will be paid in, and
// the amount is the amount of that specified asset.
struct TeleporterFeeInfo {
address contractAddress;
address feeTokenAddress;
uint256 amount;
}

Expand Down Expand Up @@ -140,14 +140,14 @@ interface ITeleporterMessenger {
* @dev Adds the additional fee amount to the amount to be paid to the relayer that delivers
* the given message ID to the destination chain.
*
* The fee contract address must be the same asset type as the fee asset specified in the original
* The fee token address must be the same asset type as the fee asset specified in the original
* call to sendCrossChainMessage. Reverts if the message doesn't exist or there is already
* receipt of delivery of the message.
*/
function addFeeAmount(
bytes32 destinationChainID,
uint256 messageID,
address feeContractAddress,
address feeTokenAddress,
uint256 additionalFeeAmount
) external;

Expand Down Expand Up @@ -194,7 +194,7 @@ interface ITeleporterMessenger {
/**
* @dev Sends any fee amount rewards for the given fee asset out to the caller.
*/
function redeemRelayerRewards(address feeAsset) external;
function redeemRelayerRewards(address feeTokenAddress) external;

/**
* @dev Gets the hash of a given message stored in the EVM state, if the message exists.
Expand Down Expand Up @@ -230,12 +230,12 @@ interface ITeleporterMessenger {
*/
function checkRelayerRewardAmount(
address relayer,
address feeAsset
address feeTokenAddress
) external view returns (uint256);

/**
* @dev Gets the fee asset and amount for a given message.
* @return The fee asset address and fee amount for a the given message.
* @dev Gets the fee token address and amount for a given message.
* @return The fee token address and fee amount for a the given message.
*/
function getFeeInfo(
bytes32 destinationChainID,
Expand Down
20 changes: 10 additions & 10 deletions contracts/src/Teleporter/TeleporterMessenger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,12 @@ contract TeleporterMessenger is ITeleporterMessenger, ReentrancyGuards {
*
* - `additionalFeeAmount` must be non-zero.
* - `message` must exist and not have been delivered yet.
* - `feeContractAddress` must match the fee asset contract address used in the original call to `sendCrossChainMessage`.
* - `feeTokenAddress` must match the fee asset contract address used in the original call to `sendCrossChainMessage`.
*/
function addFeeAmount(
bytes32 destinationChainID,
uint256 messageID,
address feeContractAddress,
address feeTokenAddress,
uint256 additionalFeeAmount
) external senderNonReentrant {
// The additional fee amount must be non-zero.
Expand All @@ -169,7 +169,7 @@ contract TeleporterMessenger is ITeleporterMessenger, ReentrancyGuards {

// Do not allow adding a fee asset with contract address zero.
require(
feeContractAddress != address(0),
feeTokenAddress != address(0),
"TeleporterMessenger: zero fee asset contract address"
);

Expand All @@ -190,13 +190,13 @@ contract TeleporterMessenger is ITeleporterMessenger, ReentrancyGuards {
require(
sentMessageInfo[destinationChainID][messageID]
.feeInfo
.contractAddress == feeContractAddress,
.feeTokenAddress == feeTokenAddress,
"TeleporterMessenger: invalid fee asset contract address"
);

// Transfer the additional fee amount to this Teleporter instance.
uint256 adjustedAmount = SafeERC20TransferFrom.safeTransferFrom(
IERC20(feeContractAddress),
IERC20(feeTokenAddress),
additionalFeeAmount
);

Expand Down Expand Up @@ -530,7 +530,7 @@ contract TeleporterMessenger is ITeleporterMessenger, ReentrancyGuards {
TeleporterFeeInfo memory feeInfo = sentMessageInfo[destinationChainID][
messageID
].feeInfo;
return (feeInfo.contractAddress, feeInfo.amount);
return (feeInfo.feeTokenAddress, feeInfo.amount);
}

/**
Expand Down Expand Up @@ -629,20 +629,20 @@ contract TeleporterMessenger is ITeleporterMessenger, ReentrancyGuards {
if (messageInput.feeInfo.amount > 0) {
// If the fee amount is non-zero, check that the contract address is not address(0)
require(
messageInput.feeInfo.contractAddress != address(0),
messageInput.feeInfo.feeTokenAddress != address(0),
"TeleporterMessenger: zero fee asset contract address"
);

adjustedFeeAmount = SafeERC20TransferFrom.safeTransferFrom(
IERC20(messageInput.feeInfo.contractAddress),
IERC20(messageInput.feeInfo.feeTokenAddress),
messageInput.feeInfo.amount
);
}

// Store the fee asset and amount to be paid to the relayer of this message upon receiving the receipt.
// Also store the message hash so that it can be retried until a receipt of its delivery is received back.
TeleporterFeeInfo memory adjustedFeeInfo = TeleporterFeeInfo({
contractAddress: messageInput.feeInfo.contractAddress,
feeTokenAddress: messageInput.feeInfo.feeTokenAddress,
amount: adjustedFeeAmount
});
sentMessageInfo[messageInput.destinationChainID][
Expand Down Expand Up @@ -695,7 +695,7 @@ contract TeleporterMessenger is ITeleporterMessenger, ReentrancyGuards {
// Increment the fee/reward amount owed to the relayer for having delivered
// the message identified in this receipt.
_relayerRewardAmounts[relayerRewardAddress][
messageInfo.feeInfo.contractAddress
messageInfo.feeInfo.feeTokenAddress
] += messageInfo.feeInfo.amount;
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/src/Teleporter/tests/AddFeeAmountTests.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ contract AddFeeAmountTest is TeleporterMessengerTest {
DEFAULT_DESTINATION_CHAIN_ID,
messageID,
TeleporterFeeInfo({
contractAddress: address(_mockFeeAsset),
feeTokenAddress: address(_mockFeeAsset),
amount: totalFeeAmount
})
);
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/Teleporter/tests/GetNextMessageIdTests.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ contract GetNextMessageIDTest is TeleporterMessengerTest {
destinationChainID: chainID,
destinationAddress: address(0),
feeInfo: TeleporterFeeInfo({
contractAddress: address(0),
feeTokenAddress: address(0),
amount: uint256(0)
}),
requiredGasLimit: 1e6,
Expand Down Expand Up @@ -69,7 +69,7 @@ contract GetNextMessageIDTest is TeleporterMessengerTest {
destinationChainID: chainID,
destinationAddress: address(0),
feeInfo: TeleporterFeeInfo({
contractAddress: address(0),
feeTokenAddress: address(0),
amount: uint256(0)
}),
requiredGasLimit: 1e6,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ contract SendCrossChainMessageTest is TeleporterMessengerTest {

// Expect the ERC20 contract transferFrom method to be called to transfer the fee.
vm.expectCall(
messageInput.feeInfo.contractAddress,
messageInput.feeInfo.feeTokenAddress,
abi.encodeCall(
IERC20.transferFrom,
(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ contract SendSpecifiedReceiptsTest is TeleporterMessengerTest {
}

TeleporterFeeInfo memory feeInfo = TeleporterFeeInfo({
contractAddress: feeAddress,
feeTokenAddress: feeAddress,
amount: feeAmount
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ contract TeleporterMessengerTest is Test {
feeAsset = address(_mockFeeAsset);
}
TeleporterFeeInfo memory feeInfo = TeleporterFeeInfo({
contractAddress: feeAsset,
feeTokenAddress: feeAsset,
amount: feeAmount
});

Expand Down
2 changes: 1 addition & 1 deletion tests/basic_one_way_send.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func BasicOneWaySend() {
DestinationChainID: subnetBInfo.BlockchainID,
DestinationAddress: fundedAddress,
FeeInfo: teleportermessenger.TeleporterFeeInfo{
ContractAddress: fundedAddress,
FeeTokenAddress: fundedAddress,
Amount: big.NewInt(0),
},
RequiredGasLimit: big.NewInt(1),
Expand Down

0 comments on commit 8b66551

Please sign in to comment.