diff --git a/contracts/README.md b/contracts/README.md index 4c5d5e8b..cabe1889 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -65,6 +65,6 @@ Note that the value returned by `totalNativeAssetSupply` is an upper bound on th ## Teleporter Message Fees -Fees can be optionally added to Teleporter messages in order to incentivize relayers to deliver them, as documented [here](https://github.com/ava-labs/teleporter/tree/main/contracts/src/Teleporter#fees). The token transfer contracts in this repository allow for specifying any ERC20 token and amount to be used as the Teleporter message fee for single-hop transfers in either direction between `TokenHome` and `TokenRemote` instances. Fee amounts must be pre-approved to be spent by the token transfer contract before initiating a transfer. +Fees can be optionally added to Teleporter messages in order to incentivize relayers to deliver them, as documented [here](https://github.com/ava-labs/teleporter/tree/main/contracts/teleporter#fees). The token transfer contracts in this repository allow for specifying any ERC20 token and amount to be used as the Teleporter message fee for single-hop transfers in either direction between `TokenHome` and `TokenRemote` instances. Fee amounts must be pre-approved to be spent by the token transfer contract before initiating a transfer. Multi-hop transfers between two `TokenRemote` instances involve two Teleporter messages: the first from the initiating `TokenRemote` instance to its home, and the second from its home to the destination `TokenRemote` instance. In the multi-hop case, the first message fee can be paid in any ERC20 token and amount (similar to the single-hop case), but the second message fee must be paid in-kind of the asset being transferred and is deducted from the amount being transferred. This restriction on the secondary message fee is necessary because the transaction on the intermediate chain routing the funds to the destination `TokenRemote` instance is not sent by the wallet performing the transfer. Because of this, it can not directly spend an arbitrary ERC20 token from that wallet. Using the asset being transferred for the optional secondary fee allows users to perform an incentivized multi-hop transfer without needing to make any interaction with the home themselves. If there is a need for the second message from the home to the destination `TokenRemote` instance to pay a fee in another asset, it is recommended to perform two single-hop transfers, which allows for specifying an arbitrary ERC20 token to be used for the fee of each. diff --git a/contracts/lib/teleporter b/contracts/lib/teleporter index e63caa7f..d0431354 160000 --- a/contracts/lib/teleporter +++ b/contracts/lib/teleporter @@ -1 +1 @@ -Subproject commit e63caa7ff53045a28f69affa333600f67e2fbec5 +Subproject commit d04313542b05d87502433d6d72c6f4ca49d648dd diff --git a/contracts/remappings.txt b/contracts/remappings.txt index 9c0ffe03..955236e2 100644 --- a/contracts/remappings.txt +++ b/contracts/remappings.txt @@ -1,5 +1,5 @@ @openzeppelin/contracts@5.0.2/=lib/openzeppelin-contracts/contracts/ @openzeppelin/contracts-upgradeable@5.0.2/=lib/openzeppelin-contracts-upgradeable/contracts/ -@avalabs/subnet-evm-contracts@1.2.0/=lib/teleporter/contracts/lib/subnet-evm/contracts/ -@teleporter/=lib/teleporter/contracts/src/teleporter/ -@teleporter-mocks/=lib/teleporter/contracts/src/mocks +@avalabs/subnet-evm-contracts@1.2.0/=lib/teleporter/lib/subnet-evm/contracts/ +@teleporter/=lib/teleporter/contracts/teleporter/ +@teleporter-mocks/=lib/teleporter/contracts/mocks diff --git a/contracts/src/TokenHome/ERC20TokenHomeUpgradeable.sol b/contracts/src/TokenHome/ERC20TokenHomeUpgradeable.sol index 5dc7d168..2260611f 100644 --- a/contracts/src/TokenHome/ERC20TokenHomeUpgradeable.sol +++ b/contracts/src/TokenHome/ERC20TokenHomeUpgradeable.sol @@ -65,7 +65,7 @@ contract ERC20TokenHomeUpgradeable is IERC20TokenHome, TokenHome { /** * @notice Initializes the token TokenHome instance to send ERC20 tokens to TokenRemote instances on other chains. * @param teleporterRegistryAddress The current blockchain ID's Teleporter registry - * address. See here for details: https://github.com/ava-labs/teleporter/tree/main/contracts/src/Teleporter/upgrades + * address. See here for details: https://github.com/ava-labs/teleporter/tree/main/contracts/teleporter/registry * @param teleporterManager Address that manages this contract's integration with the * Teleporter registry and Teleporter versions. * @param tokenAddress The ERC20 token contract address to be transferred by the home. diff --git a/contracts/src/TokenHome/NativeTokenHomeUpgradeable.sol b/contracts/src/TokenHome/NativeTokenHomeUpgradeable.sol index 140b7873..94d33fae 100644 --- a/contracts/src/TokenHome/NativeTokenHomeUpgradeable.sol +++ b/contracts/src/TokenHome/NativeTokenHomeUpgradeable.sol @@ -68,7 +68,7 @@ contract NativeTokenHomeUpgradeable is INativeTokenHome, TokenHome { * @notice Initializes this token TokenHome instance to send native tokens to TokenRemote instances on other chains. * Always uses a {tokenDecimals} value of 18 since it is the denomination of the native token of EVM instances. * @param teleporterRegistryAddress The current blockchain ID's Teleporter registry - * address. See here for details: https://github.com/ava-labs/teleporter/tree/main/contracts/src/Teleporter/upgrades + * address. See here for details: https://github.com/ava-labs/teleporter/tree/main/contracts/teleporter/registry * @param teleporterManager Address that manages this contract's integration with the * Teleporter registry and Teleporter versions. * @param wrappedTokenAddress The wrapped native token contract address of the native asset diff --git a/contracts/src/TokenRemote/interfaces/ITokenRemote.sol b/contracts/src/TokenRemote/interfaces/ITokenRemote.sol index cbaf51b0..01a866f5 100644 --- a/contracts/src/TokenRemote/interfaces/ITokenRemote.sol +++ b/contracts/src/TokenRemote/interfaces/ITokenRemote.sol @@ -11,7 +11,7 @@ import {TeleporterFeeInfo} from "@teleporter/ITeleporterMessenger.sol"; /** * @notice Settings for constructing a {ITokenRemote} contract. * @param teleporterRegistryAddress The current blockchain ID's Teleporter registry - * address. See here for details: https://github.com/ava-labs/teleporter/tree/main/contracts/src/Teleporter/upgrades. + * address. See here for details: https://github.com/ava-labs/teleporter/tree/main/contracts/teleporter/registry. * @param teleporterManager Address that manages this contract's integration with the * Teleporter registry and Teleporter versions. * @param tokenHomeBlockchainID The blockchain ID of the associated TokenHome instance. diff --git a/contracts/src/utils/SafeERC20TransferFrom.sol b/contracts/src/utils/SafeERC20TransferFrom.sol index e04e536e..3f36f954 100644 --- a/contracts/src/utils/SafeERC20TransferFrom.sol +++ b/contracts/src/utils/SafeERC20TransferFrom.sol @@ -11,7 +11,7 @@ import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC /** * @dev Provides a wrapper used for calling an ERC20 transferFrom method to receive tokens to a contract * from a specified sender. Differs from the "SafeERC20TransferFrom" implementation found here - * https://github.com/ava-labs/teleporter/blob/main/contracts/src/Teleporter/SafeERC20TransferFrom.sol in that + * https://github.com/ava-labs/teleporter/blob/main/contracts/utilities/SafeERC20TransferFrom.sol in that * it supports passing arbitrary sender address values, allowing its use in ERC-2771 compliant meta-transactions. * * Checks the balance of the contract using the library before and after the call to safeTransferFrom, and diff --git a/contracts/test/ERC20TokenHomeTests.t.sol b/contracts/test/ERC20TokenHomeTests.t.sol index 63c67203..0a56ccf2 100644 --- a/contracts/test/ERC20TokenHomeTests.t.sol +++ b/contracts/test/ERC20TokenHomeTests.t.sol @@ -12,7 +12,7 @@ import {SendTokensInput} from "../src/interfaces/ITokenTransferrer.sol"; import {ERC20TokenHomeUpgradeable} from "../src/TokenHome/ERC20TokenHomeUpgradeable.sol"; import {ERC20TokenHome} from "../src/TokenHome/ERC20TokenHome.sol"; import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; -import {ExampleERC20} from "../lib/teleporter/contracts/src/mocks/ExampleERC20.sol"; +import {ExampleERC20} from "../lib/teleporter/contracts/mocks/ExampleERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; import {TeleporterMessageInput, TeleporterFeeInfo} from "@teleporter/ITeleporterMessenger.sol"; import {TokenScalingUtils} from "../src/utils/TokenScalingUtils.sol"; diff --git a/contracts/test/ERC20TokenRemoteTests.t.sol b/contracts/test/ERC20TokenRemoteTests.t.sol index e684dffc..5e2f564e 100644 --- a/contracts/test/ERC20TokenRemoteTests.t.sol +++ b/contracts/test/ERC20TokenRemoteTests.t.sol @@ -14,7 +14,7 @@ import {ERC20TokenRemoteUpgradeable} from "../src/TokenRemote/ERC20TokenRemoteUp import {ERC20TokenRemote} from "../src/TokenRemote/ERC20TokenRemote.sol"; import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; -import {ExampleERC20} from "../lib/teleporter/contracts/src/mocks/ExampleERC20.sol"; +import {ExampleERC20} from "../lib/teleporter/contracts/mocks/ExampleERC20.sol"; import {SendTokensInput} from "../src/interfaces/ITokenTransferrer.sol"; import {Ownable} from "@openzeppelin/contracts@5.0.2/access/Ownable.sol"; import {ICTTInitializable} from "../src/utils/ICTTInitializable.sol"; diff --git a/contracts/test/MockSendAndCallReceiverTest.t.sol b/contracts/test/MockSendAndCallReceiverTest.t.sol index 7c40d214..975cf9e6 100644 --- a/contracts/test/MockSendAndCallReceiverTest.t.sol +++ b/contracts/test/MockSendAndCallReceiverTest.t.sol @@ -9,7 +9,7 @@ import {Test} from "forge-std/Test.sol"; import {MockERC20SendAndCallReceiver} from "../src/mocks/MockERC20SendAndCallReceiver.sol"; import {MockNativeSendAndCallReceiver} from "../src/mocks/MockNativeSendAndCallReceiver.sol"; import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; -import {ExampleERC20} from "../lib/teleporter/contracts/src/mocks/ExampleERC20.sol"; +import {ExampleERC20} from "../lib/teleporter/contracts/mocks/ExampleERC20.sol"; contract MockERC20SendAndCallReceiverTest is Test { IERC20 public erc20; diff --git a/contracts/test/NativeTokenRemoteTests.t.sol b/contracts/test/NativeTokenRemoteTests.t.sol index 4102a93e..d713438f 100644 --- a/contracts/test/NativeTokenRemoteTests.t.sol +++ b/contracts/test/NativeTokenRemoteTests.t.sol @@ -22,7 +22,7 @@ import { import {SendTokensInput} from "../src/interfaces/ITokenTransferrer.sol"; import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; -import {ExampleERC20} from "../lib/teleporter/contracts/src/mocks/ExampleERC20.sol"; +import {ExampleERC20} from "../lib/teleporter/contracts/mocks/ExampleERC20.sol"; import {ICTTInitializable} from "../src/utils/ICTTInitializable.sol"; import {Initializable} from "@openzeppelin/contracts@5.0.2/proxy/utils/Initializable.sol"; diff --git a/contracts/test/TokenRemoteTests.t.sol b/contracts/test/TokenRemoteTests.t.sol index b6545158..cee7c2fc 100644 --- a/contracts/test/TokenRemoteTests.t.sol +++ b/contracts/test/TokenRemoteTests.t.sol @@ -20,7 +20,7 @@ import { RegisterRemoteMessage } from "../src/interfaces/ITokenTransferrer.sol"; import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; -import {ExampleERC20} from "../lib/teleporter/contracts/src/mocks/ExampleERC20.sol"; +import {ExampleERC20} from "../lib/teleporter/contracts/mocks/ExampleERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; abstract contract TokenRemoteTest is TokenTransferrerTest { diff --git a/go.mod b/go.mod index 43f27375..fd00eb3b 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/ava-labs/avalanche-interchain-token-transfer -go 1.21.13 +go 1.22.6 require ( github.com/ava-labs/avalanchego v1.11.10 github.com/ava-labs/subnet-evm v0.6.8 - github.com/ava-labs/teleporter v1.0.4 + github.com/ava-labs/teleporter v1.0.5 github.com/ethereum/go-ethereum v1.13.8 github.com/onsi/ginkgo/v2 v2.20.0 github.com/onsi/gomega v1.34.1 diff --git a/go.sum b/go.sum index c3183336..e5be90b1 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/ava-labs/coreth v0.13.7 h1:k8T9u/ROifl8f7oXjHRc1KvSISRl9txvy7gGVmHEz6 github.com/ava-labs/coreth v0.13.7/go.mod h1:tXDujonxXFOF6oK5HS2EmgtSXJK3Gy6RpZxb5WzR9rM= github.com/ava-labs/subnet-evm v0.6.8 h1:IrHGajBYWs692YIYdd5J0oVWWt88Q/XAZQq/dOtkHFw= github.com/ava-labs/subnet-evm v0.6.8/go.mod h1:qt8DXyGm40CY9yffNOe1+4yUyL9mD3v5RPWqAuGj5u4= -github.com/ava-labs/teleporter v1.0.4 h1:+OAS3YyPc/LijR29qu3EqU6xAnQnjOgf4EtDlCMcDsc= -github.com/ava-labs/teleporter v1.0.4/go.mod h1:bUiOSIGjFktkYg01XDjeaZdgLEx0ZpUDfJXI6Z0rHY8= +github.com/ava-labs/teleporter v1.0.5 h1:51fRzvo7eo9VotYq6cldx+yoAkEk5o9yCXOJ6q3tSEo= +github.com/ava-labs/teleporter v1.0.5/go.mod h1:C5/ETmPQh/MxZOCARrhPV+J40y4R3TOeT0lvQrjz/RE= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= diff --git a/scripts/abi_bindings.sh b/scripts/abi_bindings.sh index 2f6789d5..2b8fd7b5 100755 --- a/scripts/abi_bindings.sh +++ b/scripts/abi_bindings.sh @@ -88,9 +88,9 @@ generate_bindings "${contract_names[@]}" contract_names=($PROXY_LIST) cd $AVALANCHE_INTERCHAIN_TOKEN_TRANSFER_PATH/contracts -forge build --skip test --force --extra-output-files abi bin --contracts lib/teleporter/contracts/lib/openzeppelin-contracts/contracts/proxy/transparent +forge build --skip test --force --extra-output-files abi bin --contracts lib/openzeppelin-contracts/contracts/proxy/transparent -cd $AVALANCHE_INTERCHAIN_TOKEN_TRANSFER_PATH/contracts/lib/teleporter/contracts/lib/openzeppelin-contracts/contracts/proxy/transparent +cd $AVALANCHE_INTERCHAIN_TOKEN_TRANSFER_PATH/contracts/lib/openzeppelin-contracts/contracts/proxy/transparent generate_bindings "${contract_names[@]}" exit 0 diff --git a/tests/local/e2e_test.go b/tests/local/e2e_test.go index 3b111e15..7d2b2f8e 100644 --- a/tests/local/e2e_test.go +++ b/tests/local/e2e_test.go @@ -17,7 +17,7 @@ import ( ) const ( - teleporterByteCodeFile = "./contracts/lib/teleporter/contracts/out/TeleporterMessenger.sol/TeleporterMessenger.json" + teleporterByteCodeFile = "./contracts/lib/teleporter/out/TeleporterMessenger.sol/TeleporterMessenger.json" warpGenesisTemplateFile = "./tests/utils/warp-genesis-template.json" erc20TokenHomeLabel = "ERC20TokenHome" @@ -44,51 +44,58 @@ func TestE2E(t *testing.T) { // Define the Teleporter before and after suite functions. var _ = ginkgo.BeforeSuite(func() { + // Generate the Teleporter deployment values + teleporterDeployerTransaction, teleporterDeployedBytecode, teleporterDeployerAddress, + teleporterContractAddress, err := deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + deploymentUtils.GetDefaultContractCreationGasPrice(), + ) + Expect(err).Should(BeNil()) + // Create the local network instance LocalNetworkInstance = local.NewLocalNetwork( "interchain-token-transfer-test", warpGenesisTemplateFile, []local.SubnetSpec{ { - Name: "A", - EVMChainID: 12345, - NodeCount: 1, + Name: "A", + EVMChainID: 12345, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 1, }, { - Name: "B", - EVMChainID: 54321, - NodeCount: 1, + Name: "B", + EVMChainID: 54321, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 1, }, }, 0, ) - // Generate the Teleporter deployment values - teleporterDeployerTransaction, teleporterDeployerAddress, - teleporterContractAddress, err := deploymentUtils.ConstructKeylessTransaction( - teleporterByteCodeFile, - false, - deploymentUtils.GetDefaultContractCreationGasPrice(), - ) - Expect(err).Should(BeNil()) - _, fundedKey := LocalNetworkInstance.GetFundedAccountInfo() - LocalNetworkInstance.DeployTeleporterContracts( + LocalNetworkInstance.DeployTeleporterContractToCChain( teleporterDeployerTransaction, teleporterDeployerAddress, teleporterContractAddress, fundedKey, - true, ) + LocalNetworkInstance.SetTeleporterContractAddress(teleporterContractAddress) LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) - log.Info("Set up ginkgo before suite") ginkgo.AddReportEntry( "network directory with node logs & configs; useful in the case of failures", LocalNetworkInstance.Dir(), ginkgo.ReportEntryVisibilityFailureOrVerbose, ) + + log.Info("Finished ginkgo before suite set up") }) var _ = ginkgo.AfterSuite(func() { diff --git a/tests/utils/warp-genesis-template.json b/tests/utils/warp-genesis-template.json index a1b04796..93739a2b 100644 --- a/tests/utils/warp-genesis-template.json +++ b/tests/utils/warp-genesis-template.json @@ -39,6 +39,19 @@ } }, "alloc": { + "": { + "balance": "0x0", + "code": "", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "nonce": 1 + }, + "": { + "balance": "0x0", + "nonce": 1 + }, "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC": { "balance": "0x52B7D2DCC80CD2E4000000" },