Skip to content

Commit

Permalink
hardcode erc20 asset string to align with foreign coin store data
Browse files Browse the repository at this point in the history
  • Loading branch information
ws4charlie committed Dec 10, 2024
1 parent ff5d8e3 commit 79ac5ef
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 5 deletions.
81 changes: 78 additions & 3 deletions zetaclient/chains/evm/observer/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/evm/erc20custody.sol"
"github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/evm/zetaconnector.non-eth.sol"

"github.com/zeta-chain/node/pkg/chains"
"github.com/zeta-chain/node/pkg/coin"
"github.com/zeta-chain/node/pkg/constant"
"github.com/zeta-chain/node/pkg/memo"
Expand All @@ -34,6 +35,76 @@ import (
"github.com/zeta-chain/node/zetaclient/zetacore"
)

var (
// erc20AddressToForeignCoinAssetMap maps the chain id and foreign ERC20 address to the coin asset string
erc20AddressToForeignCoinAssetMap = map[int64]map[ethcommon.Address]string{
// Ethereum mainnet
chains.Ethereum.ChainId: {
// USDC.ETH
ethcommon.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"): "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
// PEPE.ETH
ethcommon.HexToAddress("0x6982508145454ce325ddbe47a25d4ec3d2311933"): "0x6982508145454ce325ddbe47a25d4ec3d2311933",
// SHIB.ETH
ethcommon.HexToAddress("0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce"): "0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce",
// USDT.ETH
ethcommon.HexToAddress("0xdac17f958d2ee523a2206206994597c13d831ec7"): "0xdac17f958d2ee523a2206206994597c13d831ec7",
// DAI.ETH
ethcommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f"): "0x6b175474e89094c44da98b954eedeac495271d0f",
// ULTI.ETH
ethcommon.HexToAddress("0x0E7779e698052f8fe56C415C3818FCf89de9aC6D"): "0x0E7779e698052f8fe56C415C3818FCf89de9aC6D",
},

// BSC mainnet
chains.BscMainnet.ChainId: {
// USDC.BSC
ethcommon.HexToAddress("0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d"): "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
// USDT.BSC
ethcommon.HexToAddress("0x55d398326f99059ff775485246999027b3197955"): "0x55d398326f99059ff775485246999027b3197955",
// ULTI.BSC
ethcommon.HexToAddress("0x0E7779e698052f8fe56C415C3818FCf89de9aC6D"): "0x0E7779e698052f8fe56C415C3818FCf89de9aC6D",
},

// Polygon mainnet
chains.Polygon.ChainId: {
// USDT.POL
ethcommon.HexToAddress("0xc2132d05d31c914a87c6611c10748aeb04b58e8f"): "0xc2132d05d31c914a87c6611c10748aeb04b58e8f",
// USDC.POL
ethcommon.HexToAddress("0x3c499c542cef5e3811e1192ce70d8cc03d5c3359"): "0x3c499c542cef5e3811e1192ce70d8cc03d5c3359",
},

// Polygon Amoy
chains.Amoy.ChainId: {
// USDC.AMOY
ethcommon.HexToAddress("0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582"): "0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582",
},

// Base mainnet
chains.BaseMainnet.ChainId: {
// USDC.BASE
ethcommon.HexToAddress("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"): "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
},
}
)

// ERC20AddressToForeignCoinAsset
func ERC20AddressToForeignCoinAsset(chainID int64, erc20Address ethcommon.Address) string {
addressToAsset, found := erc20AddressToForeignCoinAssetMap[chainID]
switch {
case found:
// if found, convert the address to asset in foreigh coin store
asset, found := addressToAsset[erc20Address]
if found {
return asset
}

// use the checksum address as asset string by default
return erc20Address.Hex()
default:
// use the checksum address as asset string by default
return erc20Address.Hex()
}
}

// WatchInbound watches evm chain for incoming txs and post votes to zetacore
// TODO(revamp): move ticker function to a separate file
func (ob *Observer) WatchInbound(ctx context.Context) error {
Expand Down Expand Up @@ -672,11 +743,15 @@ func (ob *Observer) BuildInboundVoteMsgForDepositedEvent(
Msgf("thank you rich folk for your donation! tx %s chain %d", event.Raw.TxHash.Hex(), ob.Chain().ChainId)
return nil
}

// convert erc20Address to asset in foreign coin store to avoid checksum mismatch
asset := ERC20AddressToForeignCoinAsset(ob.Chain().ChainId, event.Asset)

message := hex.EncodeToString(event.Message)
ob.Logger().Inbound.Info().
Msgf("ERC20CustodyDeposited inbound detected on chain %d tx %s block %d from %s value %s message %s",
Msgf("ERC20CustodyDeposited inbound detected on chain %d tx %s block %d from %s value %s asset %s message %s",
ob.Chain().
ChainId, event.Raw.TxHash.Hex(), event.Raw.BlockNumber, sender.Hex(), event.Amount.String(), message)
ChainId, event.Raw.TxHash.Hex(), event.Raw.BlockNumber, sender.Hex(), event.Amount.String(), asset, message)

return zetacore.GetInboundVoteMessage(
sender.Hex(),
Expand All @@ -690,7 +765,7 @@ func (ob *Observer) BuildInboundVoteMsgForDepositedEvent(
event.Raw.BlockNumber,
1_500_000,
coin.CoinType_ERC20,
event.Asset.String(),
asset,
ob.ZetacoreClient().GetKeys().GetOperatorAddress().String(),
event.Raw.Index,
)
Expand Down
101 changes: 101 additions & 0 deletions zetaclient/chains/evm/observer/inbound_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,114 @@ import (
"github.com/zeta-chain/node/pkg/coin"
"github.com/zeta-chain/node/pkg/constant"
"github.com/zeta-chain/node/zetaclient/chains/evm"
"github.com/zeta-chain/node/zetaclient/chains/evm/observer"
"github.com/zeta-chain/node/zetaclient/chains/interfaces"
"github.com/zeta-chain/node/zetaclient/config"
"github.com/zeta-chain/node/zetaclient/testutils"
"github.com/zeta-chain/node/zetaclient/testutils/mocks"
clienttypes "github.com/zeta-chain/node/zetaclient/types"
)

func Test_ERC20AddressToForeignCoinAsset(t *testing.T) {
tests := []struct {
name string
chainID int64
erc20Address ethcommon.Address
assetString string
}{
// Ethereum Mainnet
{
name: "USDC.ETH",
chainID: chains.Ethereum.ChainId,
erc20Address: ethcommon.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"),
assetString: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
},
{
name: "PEPE.ETH",
chainID: chains.Ethereum.ChainId,
erc20Address: ethcommon.HexToAddress("0x6982508145454ce325ddbe47a25d4ec3d2311933"),
assetString: "0x6982508145454ce325ddbe47a25d4ec3d2311933",
},
{
name: "SHIB.ETH",
chainID: chains.Ethereum.ChainId,
erc20Address: ethcommon.HexToAddress("0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce"),
assetString: "0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce",
},
{
name: "USDT.ETH",
chainID: chains.Ethereum.ChainId,
erc20Address: ethcommon.HexToAddress("0xdac17f958d2ee523a2206206994597c13d831ec7"),
assetString: "0xdac17f958d2ee523a2206206994597c13d831ec7",
},
{
name: "DAI.ETH",
chainID: chains.Ethereum.ChainId,
erc20Address: ethcommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f"),
assetString: "0x6b175474e89094c44da98b954eedeac495271d0f",
},
{
name: "ULTI.ETH",
chainID: chains.Ethereum.ChainId,
erc20Address: ethcommon.HexToAddress("0x0E7779e698052f8fe56C415C3818FCf89de9aC6D"),
assetString: "0x0E7779e698052f8fe56C415C3818FCf89de9aC6D",
},
// BSC Mainnet
{
name: "USDC.BSC",
chainID: chains.BscMainnet.ChainId,
erc20Address: ethcommon.HexToAddress("0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d"),
assetString: "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
},
{
name: "USDT.BSC",
chainID: chains.BscMainnet.ChainId,
erc20Address: ethcommon.HexToAddress("0x55d398326f99059ff775485246999027b3197955"),
assetString: "0x55d398326f99059ff775485246999027b3197955",
},
{
name: "ULTI.BSC",
chainID: chains.BscMainnet.ChainId,
erc20Address: ethcommon.HexToAddress("0x0E7779e698052f8fe56C415C3818FCf89de9aC6D"),
assetString: "0x0E7779e698052f8fe56C415C3818FCf89de9aC6D",
},
// Polygon Mainnet
{
name: "USDT.POL",
chainID: chains.Polygon.ChainId,
erc20Address: ethcommon.HexToAddress("0xc2132d05d31c914a87c6611c10748aeb04b58e8f"),
assetString: "0xc2132d05d31c914a87c6611c10748aeb04b58e8f",
},
{
name: "USDC.POL",
chainID: chains.Polygon.ChainId,
erc20Address: ethcommon.HexToAddress("0x3c499c542cef5e3811e1192ce70d8cc03d5c3359"),
assetString: "0x3c499c542cef5e3811e1192ce70d8cc03d5c3359",
},
// Polygon Amoy
{
name: "USDC.AMOY",
chainID: chains.Amoy.ChainId,
erc20Address: ethcommon.HexToAddress("0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582"),
assetString: "0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582",
},
// Base Mainnet
{
name: "USDC.BASE",
chainID: chains.BaseMainnet.ChainId,
erc20Address: ethcommon.HexToAddress("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"),
assetString: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
asset := observer.ERC20AddressToForeignCoinAsset(tt.chainID, tt.erc20Address)
require.Equal(t, tt.assetString, asset)
})
}
}

func Test_CheckAndVoteInboundTokenZeta(t *testing.T) {
// load archived ZetaSent inbound, receipt and cctx
// https://etherscan.io/tx/0xf3935200c80f98502d5edc7e871ffc40ca898e134525c42c2ae3cbc5725f9d76
Expand Down
20 changes: 18 additions & 2 deletions zetaclient/chains/evm/observer/v2_inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ func (ob *Observer) newDepositInboundVote(event *gatewayevm.GatewayEVMDeposited)
isCrossChainCall = true
}

// convert erc20Address to asset in foreign coin store to avoid checksum mismatch
asset := ERC20AddressToForeignCoinAsset(ob.Chain().ChainId, event.Asset)
if asset != event.Asset.Hex() {
ob.Logger().
Inbound.Info().
Msgf("newDepositInboundVote converted asset %s to %s for chain %d", event.Asset.Hex(), asset, ob.Chain().ChainId)
}

return *types.NewMsgVoteInbound(
ob.ZetacoreClient().GetKeys().GetOperatorAddress().String(),
event.Sender.Hex(),
Expand All @@ -194,7 +202,7 @@ func (ob *Observer) newDepositInboundVote(event *gatewayevm.GatewayEVMDeposited)
event.Raw.BlockNumber,
zetacore.PostVoteInboundCallOptionsGasLimit,
coinType,
event.Asset.Hex(),
asset,
event.Raw.Index,
types.ProtocolContractVersion_V2,
false, // currently not relevant since calls are not arbitrary
Expand Down Expand Up @@ -454,6 +462,14 @@ func (ob *Observer) newDepositAndCallInboundVote(event *gatewayevm.GatewayEVMDep
coinType = coin.CoinType_Gas
}

// convert erc20Address to asset in foreign coin store to avoid checksum mismatch
asset := ERC20AddressToForeignCoinAsset(ob.Chain().ChainId, event.Asset)
if asset != event.Asset.Hex() {
ob.Logger().
Inbound.Info().
Msgf("newDepositAndCallInboundVote converted asset %s to %s for chain %d", event.Asset.Hex(), asset, ob.Chain().ChainId)
}

return *types.NewMsgVoteInbound(
ob.ZetacoreClient().GetKeys().GetOperatorAddress().String(),
event.Sender.Hex(),
Expand All @@ -467,7 +483,7 @@ func (ob *Observer) newDepositAndCallInboundVote(event *gatewayevm.GatewayEVMDep
event.Raw.BlockNumber,
1_500_000,
coinType,
event.Asset.Hex(),
asset,
event.Raw.Index,
types.ProtocolContractVersion_V2,
false, // currently not relevant since calls are not arbitrary
Expand Down

0 comments on commit 79ac5ef

Please sign in to comment.