Skip to content

Commit

Permalink
ICTT Deployment Fixes (#2227)
Browse files Browse the repository at this point in the history
* Fix home key initialization

* Balance fetch logs

* Balance fetch logs

* Proper balance formatting

* Native token remote flow fixes

* Only use decimals if not using Gwei

---------

Co-authored-by: sukantoraymond <rsukanto@umich.edu>
  • Loading branch information
michaelkaplan13 and sukantoraymond authored Oct 8, 2024
1 parent efdbfbf commit 3ec8d93
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 63 deletions.
99 changes: 57 additions & 42 deletions cmd/interchaincmd/tokentransferrercmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import (
"time"

cmdflags "github.com/ava-labs/avalanche-cli/cmd/flags"
"github.com/ava-labs/avalanche-cli/pkg/application"
"github.com/ava-labs/avalanche-cli/pkg/cobrautils"
"github.com/ava-labs/avalanche-cli/pkg/constants"
"github.com/ava-labs/avalanche-cli/pkg/contract"
"github.com/ava-labs/avalanche-cli/pkg/ictt"
"github.com/ava-labs/avalanche-cli/pkg/models"
"github.com/ava-labs/avalanche-cli/pkg/networkoptions"
"github.com/ava-labs/avalanche-cli/pkg/precompiles"
"github.com/ava-labs/avalanche-cli/pkg/prompts"
Expand Down Expand Up @@ -101,6 +103,43 @@ func deploy(_ *cobra.Command, args []string) error {
return CallDeploy(args, deployFlags)
}

func getHomeKeyAndAddress(app *application.Avalanche, network models.Network, homeFlags HomeFlags) (string, string, error) {
// First check if there is a genesis key able to be used.
genesisAddress, genesisPrivateKey, err := contract.GetEVMSubnetPrefundedKey(
app,
network,
homeFlags.chainFlags,
)
if err != nil {
return "", "", err
}

// Propmt for the key to be used.
// Note that this key must have enough funds to cover gas cost on the
// home chain, and also enough of the token on the home chain to collateralize
// the remote chain if it is a native token remote.
homeKey, err := prompts.PromptPrivateKey(
app.Prompt,
"pay for home deployment fees, and collateralization (if necessary)",
app.GetKeyDir(),
app.GetKey,
genesisAddress,
genesisPrivateKey,
)
if err != nil {
return "", "", err
}

// Calculate the address for the key.
pk, err := crypto.HexToECDSA(homeKey)
if err != nil {
return "", "", err
}
homeKeyAddress := crypto.PubkeyToAddress(pk.PublicKey).Hex()

return homeKey, homeKeyAddress, nil
}

func CallDeploy(_ []string, flags DeployFlags) error {
if !ictt.FoundryIsInstalled() {
if err := ictt.InstallFoundry(); err != nil {
Expand Down Expand Up @@ -304,41 +343,11 @@ func CallDeploy(_ []string, flags DeployFlags) error {
}
}

var (
homeKey string
homeKeyAddress string
)
if flags.homeFlags.homeAddress == "" {
genesisAddress, genesisPrivateKey, err := contract.GetEVMSubnetPrefundedKey(
app,
network,
flags.homeFlags.chainFlags,
)
if err != nil {
return err
}
homeKey, err = flags.homeFlags.privateKeyFlags.GetPrivateKey(app, genesisPrivateKey)
if err != nil {
return err
}
if homeKey == "" {
homeKey, err = prompts.PromptPrivateKey(
app.Prompt,
"pay for home deploy fees",
app.GetKeyDir(),
app.GetKey,
genesisAddress,
genesisPrivateKey,
)
if err != nil {
return err
}
}
pk, err := crypto.HexToECDSA(homeKey)
if err != nil {
return err
}
homeKeyAddress = crypto.PubkeyToAddress(pk.PublicKey).Hex()
// Get the key to be used to deploy the token home contract and collateralize the remote
// in the case that it is a native token remote.
homeKey, homeKeyAddress, err := getHomeKeyAndAddress(app, network, flags.homeFlags)
if err != nil {
return err
}

// Home Contract Validations
Expand Down Expand Up @@ -483,7 +492,6 @@ func CallDeploy(_ []string, flags DeployFlags) error {
if err := ictt.BuildContracts(app); err != nil {
return err
}
ux.Logger.PrintToUser("")

// Home Deploy
icttSrcDir, err := ictt.RepoDir(app)
Expand Down Expand Up @@ -667,8 +675,10 @@ func CallDeploy(_ []string, flags DeployFlags) error {
return err
}
}
ux.Logger.PrintToUser("Remote Deployed to %s", remoteRPCEndpoint)
ux.Logger.PrintToUser("Remote Address: %s", remoteAddress)

if err := ictt.RegisterERC20Remote(
if err := ictt.RegisterRemote(
remoteRPCEndpoint,
remoteKey,
remoteAddress,
Expand All @@ -679,6 +689,7 @@ func CallDeploy(_ []string, flags DeployFlags) error {
checkInterval := 100 * time.Millisecond
checkTimeout := 10 * time.Second
t0 := time.Now()
var collateralNeeded *big.Int
for {
registeredRemote, err := ictt.TokenHomeGetRegisteredRemote(
homeRPCEndpoint,
Expand All @@ -690,6 +701,7 @@ func CallDeploy(_ []string, flags DeployFlags) error {
return err
}
if registeredRemote.Registered {
collateralNeeded = registeredRemote.CollateralNeeded
break
}
elapsed := time.Since(t0)
Expand All @@ -699,19 +711,21 @@ func CallDeploy(_ []string, flags DeployFlags) error {
time.Sleep(checkInterval)
}

if flags.remoteFlags.native {
// Collateralize the remote contract on the home contract if necessary
if collateralNeeded.Cmp(big.NewInt(0)) != 0 {
err = ictt.TokenHomeAddCollateral(
homeRPCEndpoint,
homeAddress,
homeKey,
remoteBlockchainID,
remoteAddress,
remoteSupply,
collateralNeeded,
)
if err != nil {
return err
}

// Check that the remote is collateralized on the home contract now.
registeredRemote, err := ictt.TokenHomeGetRegisteredRemote(
homeRPCEndpoint,
homeAddress,
Expand All @@ -724,7 +738,10 @@ func CallDeploy(_ []string, flags DeployFlags) error {
if registeredRemote.CollateralNeeded.Cmp(big.NewInt(0)) != 0 {
return fmt.Errorf("failure setting collateral in home endpoint: remaining collateral=%d", registeredRemote.CollateralNeeded)
}
}

if flags.remoteFlags.native {
ux.Logger.PrintToUser("Enabling native token remote contract to mint native tokens")
if err := precompiles.SetEnabled(
remoteRPCEndpoint,
precompiles.NativeMinterPrecompile,
Expand All @@ -734,6 +751,7 @@ func CallDeploy(_ []string, flags DeployFlags) error {
return err
}

// Send a single token unit to report that the remote is collateralized.
err = ictt.Send(
homeRPCEndpoint,
homeAddress,
Expand Down Expand Up @@ -785,8 +803,5 @@ func CallDeploy(_ []string, flags DeployFlags) error {
}
}

ux.Logger.PrintToUser("Remote Deployed to %s", remoteRPCEndpoint)
ux.Logger.PrintToUser("Remote Address: %s", remoteAddress)

return nil
}
56 changes: 36 additions & 20 deletions cmd/keycmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,28 +558,44 @@ func getEvmBasedChainAddrInfo(
if err != nil {
return addressInfos, err
}

// Ignore contract address access errors as those may depend on network
tokenSymbol, err := token.Symbol(nil)
if err == nil {
// just ignore contract address access errors as those may depend on network
balance, err := token.BalanceOf(nil, common.HexToAddress(cChainAddr))
if err != nil {
return addressInfos, err
}
formattedBalance, err := formatCChainBalance(balance)
if err != nil {
return addressInfos, err
}
info := addressInfo{
kind: kind,
name: name,
chain: chainName,
token: fmt.Sprintf("%s (%s.)", tokenSymbol, tokenAddress[:6]),
address: cChainAddr,
balance: formattedBalance,
network: network.Name(),
}
addressInfos = append(addressInfos, info)
if err != nil {
continue
}

// Get the raw balance for the given token.
balance, err := token.BalanceOf(nil, common.HexToAddress(cChainAddr))
if err != nil {
return addressInfos, err
}

// Get the decimal count for the token to format the balance.
// Note: decimals() is not officially part of the IERC20 interface, but is a common extension.
decimals, err := token.Decimals(nil)
if err != nil {
return addressInfos, err
}

// Format the balance to a human-readable string.
var formattedBalance string
if useGwei {
formattedBalance = fmt.Sprintf("%d", balance)
} else {
formattedBalance = utils.FormatAmount(balance, decimals)
}

info := addressInfo{
kind: kind,
name: name,
chain: chainName,
token: fmt.Sprintf("%s (%s.)", tokenSymbol, tokenAddress[:6]),
address: cChainAddr,
balance: formattedBalance,
network: network.Name(),
}
addressInfos = append(addressInfos, info)
}
}
return addressInfos, nil
Expand Down
4 changes: 3 additions & 1 deletion pkg/ictt/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/ava-labs/avalanche-cli/pkg/contract"
"github.com/ava-labs/avalanche-cli/pkg/utils"
"github.com/ava-labs/avalanche-cli/pkg/ux"
"github.com/ethereum/go-ethereum/common"
)

Expand All @@ -26,11 +27,12 @@ type TokenRemoteSettings struct {
TokenHomeDecimals uint8
}

func RegisterERC20Remote(
func RegisterRemote(
rpcURL string,
privateKey string,
remoteAddress common.Address,
) error {
ux.Logger.PrintToUser("Registering remote contract with home contract")
feeInfo := TeleporterFeeInfo{
Amount: big.NewInt(0),
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/ictt/operate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"math/big"

"github.com/ava-labs/avalanche-cli/pkg/contract"
"github.com/ava-labs/avalanche-cli/pkg/ux"
"github.com/ava-labs/avalanchego/ids"
"github.com/ethereum/go-ethereum/common"
)
Expand Down Expand Up @@ -458,6 +459,7 @@ func TokenHomeAddCollateral(
remoteAddress common.Address,
amount *big.Int,
) error {
ux.Logger.PrintToUser("Collateralizing remote contract on the home chain")
endpointKind, err := GetEndpointKind(
rpcURL,
homeAddress,
Expand Down

0 comments on commit 3ec8d93

Please sign in to comment.