Uniswap / token-lists

馃摎 The Token Lists specification
https://tokenlists.org
MIT License
1.4k stars 951 forks source link

Consider standardized representation of bridged asset relationships (L1 -> L2 or L1 -> L1) #51

Open moodysalem opened 3 years ago

moodysalem commented 3 years ago

Token lists may contain tokens on multiple chains, for example Ethereum Mainnet, Rinkeby and Optimism. These tokens can be 'bridged' versions of each other, e.g. DAI might be bridged from Ethereum Mainnet to Optimism. There could be a standard way to represent the relationship between these tokens.

One option for extending the schema:

 {
    "chainId": 1,
    "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "symbol": "USDC",
    "name": "USD Coin",
    "decimals": 6,
    "otherChainAddresses": { "420161": "0xAAAA...AAAA" }
}

Other things we may want to include in the token list specification:

How we do this depends on the intended usage in the interface. For now, since there is not an obvious way for us to use it as with other token metadata, it's may be ok to use extensions.

DannyDelott commented 3 years ago

It might be possible to address this with tags as well.

In your example, a consumer would have to know the mainnet token first before they could get at the otherChainAddresses. A tag-based alternative might look a bit flatter/easier to access depending on the consumer.

 {
    "chainId": 1,
    "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "symbol": "USDC",
    "name": "USD Coin",
    "decimals": 6,
    "tags": ["USDC", "L1"],
},
{
    "chainId": 420161,
    "address": "0xAAAA...AAAA",
    "symbol": "USDC",
    "name": "USD Coin",
    "decimals": 6,
    "tags": ["USDC", "L2"],
},
moodysalem commented 2 years ago

@uniswap/token-lists was updated to allow objects to be nested 2 levels deep as of 1.0.0-beta.26

here is a proposed schema for representing the cross chain token info in the extensions:

bridgeInfo is an extension that contains a map of other chain ID to an object containing other token info, like so

"tokens": [
  {
    // ...
    "chainId": "<source chain id>",
    "extensions": {
      "bridgeInfo": { 
        "<destination chain id>": {
          "tokenAddress": "<token address on destination chain id>",
          "originBridgeAddress": "<optional address of the bridge contract on the source chain id>",
          "destBridgeAddress": "<optional address of the bridge contract on the destination chain id>"
        }
      }
    }
  }, 
  {
    // ...
    "chainId": "<destination chain id>",
    "extensions": {
      "bridgeInfo": { 
        "<source chain id>": {
          "tokenAddress": "<token address on source chain id>",
          "originBridgeAddress": "<optional address of the bridge contract on the destination chain id>",
          "destBridgeAddress": "<optional address of the bridge contract on the source chain id>"
        }
      }
    }
  }, 
  // ...
]

e.g.: https://github.com/Uniswap/token-lists/blob/e2a796f3f021949b986b9ac9f84a17be92498702/test/schema/example-crosschain.tokenlist.json

DZGoldman commented 2 years ago

@moodysalem I like it! One thing to consider is the (inevitable) representation of one to many relationships for a bridged token between 2 given chains (i.e., USDC bridged from Ethereum to Arbitrum via the Arbitrum bridge vs. USCD bridged from Ethereum to Arbitrum via the Celer bridge). In the current proposal, to list both, you'd need 2 different entries of USDC w/ Chain ID 1 at the top level (I think), which doesn't spark joy. An alternative would be something like:

  "tokens": [
    {
      "chainId": "<source chain id>",
      "extensions": {
        "bridgeInfo": {
          "originBridgeAddress-1": {
            "tokenAddress": "<token address on destination chain id via bridge-1>",
            "destBridgeAddress-1": "<optional address of the bridge contract on the destination chain id>",
          },
          "originBridgeAddress-2": {
            "tokenAddress": "<token address on destination chain id via bridge-1>",
            "destBridgeAddress-2": "<optional address of the bridge contract on the destination chain id>",
          }
        }
      }
    }
  ]

Not sold on this either, and maybe there's a case that a given list should be opinionated towards a particular bridge, but just a thought.

moodysalem commented 2 years ago

Thanks for the input @DZGoldman! Definitely a valid consideration. I think most tokens will avoid fragmenting across multiple bridges but it may happen if one bridge supports features that another does not (e.g. voting with tokens held on layer 2)

Brought it up with one team and they said they only expect one bridge per token combo. Will bring it up again.

I think an array might be more appropriate than a key that combines bridge address and chain ID like that

The other option is having one entry for each layer 2 bridged token, that references the layer 1 token, but the layer 1 token only references the 'canonical' layer 2 token. We wouldn't want to have multiple token entries for the same token on chain ID 1.

CAMP1973 commented 1 year ago

Muy e

wallet001 commented 6 months ago

Verified

foxweba3 commented 1 month ago

专砖讬诪讜转 讗住讬诪讜谞讬诐 注砖讜讬讜转 诇讛讻讬诇 讗住讬诪讜谞讬诐 讘诪住驻专 专砖转讜转, 诇诪砖诇 Ethereum Mainnet, Rinkeby 讜-Optimism. 讛讗住讬诪讜谞讬诐 讛诇诇讜 讬讻讜诇讬诐 诇讛讬讜转 讙专住讗讜转 '诪讙讜砖专讜转' 讝讛 砖诇 讝讛, 诇诪砖诇 DAI 注砖讜讬 诇讛讬讜转 诪讙讜砖专 诪-Ethereum Mainnet 诇讗讜驻讟讬诪讬讜转. 讬讻讜诇讛 诇讛讬讜转 讚专讱 住讟谞讚专讟讬转 诇讬讬爪讙 讗转 讛拽砖专 讘讬谉 讛讗住讬诪讜谞讬诐 讛诇诇讜.

讗驻砖专讜转 讗讞转 诇讛专讞讘转 讛住讻讬诪讛:

 {
    "chainId": 1,
    "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "symbol": "USDC",
    "name": "USD Coin",
    "decimals": 6,
    "otherChainAddresses": { "420161": "0xAAAA...AAAA" }
}

讚讘专讬诐 谞讜住驻讬诐 砖讗讜诇讬 谞专爪讛 诇讻诇讜诇 讘诪驻专讟 专砖讬诪转 讛讗住讬诪讜谞讬诐:

  • 驻讜谞拽爪讬讬转 讙砖专 ABI
  • 讻转讜讘转 讞讜讝讛 讙砖专 讘砖讻讘讛 1 讜/讗讜 砖讻讘讛 2

讛讗讜驻谉 砖讘讜 谞注砖讛 讝讗转 转诇讜讬 讘砖讬诪讜砖 讛诪讬讜注讚 讘诪诪砖拽. 诇注转 注转讛, 诪讻讬讜讜谉 砖讗讬谉 讚专讱 讘专讜专讛 注讘讜专谞讜 诇讛砖转诪砖 讘讜 讻诪讜 讘诪讟讗 谞转讜谞讬诐 讗讞专讬诐 砖诇 讗住讬诪讜谉, 讬讬转讻谉 砖讝讛 讘住讚专 诇讛砖转诪砖 讘讛专讞讘讜转.