Skip to content

Commit

Permalink
[native-bridge] - add coins dynamically (#16904)
Browse files Browse the repository at this point in the history
## Description

New APIs :
`register_foreign_token<T>(self: &mut Bridge, tc: TreasuryCap<T>, uc:
UpgradeCap, metadata: &CoinMetadata<T>)`
for registering new foreign token type

New system message:
added new `AddSuiToken` message for validators to approve new tokens
addition to the bridge

Notable changes:
added BridgeTokenMetadata to treasury which contains token information
Removed `notional_values` from bridge limiter, token value is now stored
in the treasury in the `BridgeTokenMetadata`
Removed bridged token packages (BTC, ETH, USDT, and USDC) from framework
Added bridged tokens packages to `bridge/move/tokens`
Added new token registration to `TestCluster`
changed all static reference of token id and names with id_token_map
obtained from `BridgeSummary`

## Test Plan

How did you test the new or updated feature?

---
If your changes are not user-facing and do not break anything, you can
skip the following section. Otherwise, please briefly describe what has
changed under the Release Notes section.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes

---------

Co-authored-by: longbowlu <[email protected]>
Co-authored-by: Dario Russi <[email protected]>
  • Loading branch information
3 people committed May 8, 2024
1 parent e31b3e9 commit 7c690e9
Show file tree
Hide file tree
Showing 46 changed files with 2,034 additions and 1,466 deletions.
11 changes: 11 additions & 0 deletions bridge/move/tokens/btc/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "BridgedBTC"
version = "0.0.1"

[dependencies]
MoveStdlib = { local = "../../../../crates/sui-framework/packages/move-stdlib" }
Sui = { local = "../../../../crates/sui-framework/packages/sui-framework" }

[addresses]
bridged_btc = "0x0"

29 changes: 29 additions & 0 deletions bridge/move/tokens/btc/sources/btc.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

module bridged_btc::btc {
use std::option;

use sui::coin;
use sui::transfer;
use sui::tx_context;
use sui::tx_context::TxContext;

struct BTC has drop {}

const DECIMAL: u8 = 8;

fun init(otw: BTC, ctx: &mut TxContext) {
let (treasury_cap, metadata) = coin::create_currency(
otw,
DECIMAL,
b"BTC",
b"Bitcoin",
b"Bridged Bitcoin token",
option::none(),
ctx
);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury_cap, tx_context::sender(ctx));
}
}
11 changes: 11 additions & 0 deletions bridge/move/tokens/eth/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "BridgedETH"
version = "0.0.1"

[dependencies]
MoveStdlib = { local = "../../../../crates/sui-framework/packages/move-stdlib" }
Sui = { local = "../../../../crates/sui-framework/packages/sui-framework" }

[addresses]
bridged_eth = "0x0"

29 changes: 29 additions & 0 deletions bridge/move/tokens/eth/sources/eth.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

module bridged_eth::eth {
use std::option;

use sui::coin;
use sui::transfer;
use sui::tx_context;
use sui::tx_context::TxContext;

struct ETH has drop {}

const DECIMAL: u8 = 8;

fun init(otw: ETH, ctx: &mut TxContext) {
let (treasury_cap, metadata) = coin::create_currency(
otw,
DECIMAL,
b"ETH",
b"Ethereum",
b"Bridged Ethereum token",
option::none(),
ctx
);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury_cap, tx_context::sender(ctx))
}
}
11 changes: 11 additions & 0 deletions bridge/move/tokens/usdc/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "BridgedUSDC"
version = "0.0.1"

[dependencies]
MoveStdlib = { local = "../../../../crates/sui-framework/packages/move-stdlib" }
Sui = { local = "../../../../crates/sui-framework/packages/sui-framework" }

[addresses]
bridged_usdc = "0x0"

29 changes: 29 additions & 0 deletions bridge/move/tokens/usdc/sources/usdc.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

module bridged_usdc::usdc {
use std::option;

use sui::coin;
use sui::transfer;
use sui::tx_context;
use sui::tx_context::TxContext;

struct USDC has drop {}

const DECIMAL: u8 = 6;

fun init(otw: USDC, ctx: &mut TxContext) {
let (treasury_cap, metadata) = coin::create_currency(
otw,
DECIMAL,
b"USDC",
b"USD Coin",
b"Bridged USD Coin token",
option::none(),
ctx
);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury_cap, tx_context::sender(ctx));
}
}
11 changes: 11 additions & 0 deletions bridge/move/tokens/usdt/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "BridgedUSDT"
version = "0.0.1"

[dependencies]
MoveStdlib = { local = "../../../../crates/sui-framework/packages/move-stdlib" }
Sui = { local = "../../../../crates/sui-framework/packages/sui-framework" }

[addresses]
bridged_usdt = "0x0"

29 changes: 29 additions & 0 deletions bridge/move/tokens/usdt/sources/usdt.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

module bridged_usdt::usdt {
use std::option;

use sui::coin;
use sui::transfer;
use sui::tx_context;
use sui::tx_context::TxContext;

struct USDT has drop {}

const DECIMAL: u8 = 6;

fun init(otw: USDT, ctx: &mut TxContext) {
let (treasury_cap, metadata) = coin::create_currency(
otw,
DECIMAL,
b"USDT",
b"Tether",
b"Bridged Tether token",
option::none(),
ctx
);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury_cap, tx_context::sender(ctx));
}
}
28 changes: 27 additions & 1 deletion crates/sui-bridge/src/action_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ where
bridge_object_arg: ObjectArg,
) {
info!("Starting run_onchain_execution_loop");
// Get token id maps, this must succeed to continue.
let sui_token_type_tags = sui_client.get_token_id_map().await.unwrap();

while let Some(certificate_wrapper) = execution_queue_receiver.recv().await {
info!(
"Received certified action for execution: {:?}",
Expand Down Expand Up @@ -324,6 +327,7 @@ where
&gas_object_ref,
ceriticate_clone,
bridge_object_arg,
&sui_token_type_tags,
) {
Ok(tx_data) => tx_data,
Err(err) => {
Expand Down Expand Up @@ -450,10 +454,13 @@ mod tests {
use crate::test_utils::DUMMY_MUTALBE_BRIDGE_OBJECT_ARG;
use fastcrypto::traits::KeyPair;
use prometheus::Registry;
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashMap};
use std::str::FromStr;
use sui_json_rpc_types::SuiTransactionBlockResponse;
use sui_types::bridge::{TOKEN_ID_BTC, TOKEN_ID_ETH, TOKEN_ID_USDC, TOKEN_ID_USDT};
use sui_types::crypto::get_key_pair;
use sui_types::gas_coin::GasCoin;
use sui_types::TypeTag;
use sui_types::{base_types::random_object_ref, transaction::TransactionData};

use crate::{
Expand Down Expand Up @@ -489,6 +496,7 @@ mod tests {
_handles,
gas_object_ref,
sui_address,
id_token_map,
) = setup().await;

let (action_certificate, _, _) = get_bridge_authority_approved_action(
Expand All @@ -502,6 +510,7 @@ mod tests {
&gas_object_ref,
action_certificate,
DUMMY_MUTALBE_BRIDGE_OBJECT_ARG,
&id_token_map,
)
.unwrap();

Expand Down Expand Up @@ -553,6 +562,7 @@ mod tests {
&gas_object_ref,
action_certificate,
DUMMY_MUTALBE_BRIDGE_OBJECT_ARG,
&id_token_map,
)
.unwrap();
let tx_digest = get_tx_digest(tx_data, &dummy_sui_key);
Expand Down Expand Up @@ -602,6 +612,7 @@ mod tests {
&gas_object_ref,
action_certificate,
DUMMY_MUTALBE_BRIDGE_OBJECT_ARG,
&id_token_map,
)
.unwrap();
let tx_digest = get_tx_digest(tx_data, &dummy_sui_key);
Expand Down Expand Up @@ -665,6 +676,7 @@ mod tests {
_handles,
gas_object_ref,
sui_address,
id_token_map,
) = setup().await;

let (action_certificate, sui_tx_digest, sui_tx_event_index) =
Expand Down Expand Up @@ -743,6 +755,7 @@ mod tests {
&gas_object_ref,
action_certificate,
DUMMY_MUTALBE_BRIDGE_OBJECT_ARG,
&id_token_map,
)
.unwrap();
let tx_digest = get_tx_digest(tx_data, &dummy_sui_key);
Expand Down Expand Up @@ -779,6 +792,7 @@ mod tests {
_handles,
_gas_object_ref,
_sui_address,
_id_token_map,
) = setup().await;

let sui_tx_digest = TransactionDigest::random();
Expand Down Expand Up @@ -845,6 +859,7 @@ mod tests {
_handles,
gas_object_ref,
sui_address,
id_token_map,
) = setup().await;

let (action_certificate, _, _) = get_bridge_authority_approved_action(
Expand All @@ -859,6 +874,7 @@ mod tests {
&gas_object_ref,
action_certificate.clone(),
arg,
&id_token_map,
)
.unwrap();
let tx_digest = get_tx_digest(tx_data, &dummy_sui_key);
Expand Down Expand Up @@ -1029,6 +1045,7 @@ mod tests {
Vec<tokio::task::JoinHandle<()>>,
ObjectRef,
SuiAddress,
HashMap<u8, TypeTag>,
) {
telemetry_subscribers::init_for_testing();
let registry = Registry::new();
Expand Down Expand Up @@ -1075,6 +1092,14 @@ mod tests {

let (executor_handle, signing_tx, execution_tx) = executor.run_inner();
handles.extend(executor_handle);

// Mock id token type map for testing
let mut id_token_map = HashMap::new();
id_token_map.insert(TOKEN_ID_BTC, TypeTag::from_str("0xb::btc::BTC").unwrap());
id_token_map.insert(TOKEN_ID_ETH, TypeTag::from_str("0xb::eth::ETH").unwrap());
id_token_map.insert(TOKEN_ID_USDC, TypeTag::from_str("0xb::usdc::USDC").unwrap());
id_token_map.insert(TOKEN_ID_USDT, TypeTag::from_str("0xb::usdt::USDT").unwrap());

(
signing_tx,
execution_tx,
Expand All @@ -1090,6 +1115,7 @@ mod tests {
handles,
gas_object_ref,
sui_address,
id_token_map,
)
}
}
13 changes: 9 additions & 4 deletions crates/sui-bridge/src/e2e_tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::crypto::{BridgeAuthorityKeyPair, BridgeAuthorityPublicKeyBytes};
use crate::events::SuiBridgeEvent;
use crate::node::run_bridge_node;
use crate::sui_client::SuiBridgeClient;
use crate::sui_transaction_builder::get_sui_token_type_tag;
use crate::types::{BridgeAction, BridgeActionStatus, BridgeActionType, SuiToEthBridgeAction};
use crate::utils::EthSigner;
use crate::BRIDGE_ENABLE_PROTOCOL_VERSION;
Expand All @@ -16,7 +15,7 @@ use ethers::prelude::*;
use ethers::types::Address as EthAddress;
use move_core_types::ident_str;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashMap};
use std::fs::File;
use std::io::Read;
use std::io::Write;
Expand Down Expand Up @@ -86,7 +85,7 @@ async fn test_bridge_from_eth_to_sui_to_eth() {
let mut test_cluster: test_cluster::TestCluster = TestClusterBuilder::new()
.with_protocol_version(BRIDGE_ENABLE_PROTOCOL_VERSION.into())
.with_epoch_duration_ms(20000)
.build_with_bridge()
.build_with_bridge(true)
.await;
let sui_client = test_cluster.fullnode_handle.sui_client.clone();
test_cluster
Expand Down Expand Up @@ -179,6 +178,8 @@ async fn test_bridge_from_eth_to_sui_to_eth() {
.unwrap();
let nonce = 0;

let sui_token_type_tags = sui_bridge_client.get_token_id_map().await.unwrap();

let sui_to_eth_bridge_action = init_sui_to_eth_bridge(
&sui_client,
sui_address,
Expand All @@ -190,6 +191,7 @@ async fn test_bridge_from_eth_to_sui_to_eth() {
nonce,
bridge_obj_arg,
sui_amount,
&sui_token_type_tags,
)
.await;

Expand Down Expand Up @@ -518,6 +520,7 @@ async fn deposit_eth_to_sui_package(
target_address: EthAddress,
token: ObjectRef,
bridge_object_arg: ObjectArg,
sui_token_type_tags: &HashMap<u8, TypeTag>,
) -> SuiTransactionBlockResponse {
let mut builder = ProgrammableTransactionBuilder::new();
let arg_target_chain = builder.pure(target_chain).unwrap();
Expand All @@ -529,7 +532,7 @@ async fn deposit_eth_to_sui_package(
BRIDGE_PACKAGE_ID,
BRIDGE_MODULE_NAME.to_owned(),
ident_str!("send_token").to_owned(),
vec![get_sui_token_type_tag(TOKEN_ID_ETH).unwrap()],
vec![sui_token_type_tags.get(&TOKEN_ID_ETH).unwrap().clone()],
vec![arg_bridge, arg_target_chain, arg_target_address, arg_token],
);

Expand Down Expand Up @@ -632,6 +635,7 @@ async fn init_sui_to_eth_bridge(
nonce: u64,
bridge_object_arg: ObjectArg,
sui_amount: u64,
sui_token_type_tags: &HashMap<u8, TypeTag>,
) -> SuiToEthBridgeAction {
let resp = deposit_eth_to_sui_package(
sui_client,
Expand All @@ -641,6 +645,7 @@ async fn init_sui_to_eth_bridge(
eth_address,
token,
bridge_object_arg,
sui_token_type_tags,
)
.await;
let sui_events = resp.events.unwrap().data;
Expand Down
2 changes: 1 addition & 1 deletion crates/sui-bridge/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ mod tests {
let test_cluster: test_cluster::TestCluster = TestClusterBuilder::new()
.with_protocol_version(BRIDGE_ENABLE_PROTOCOL_VERSION.into())
.with_epoch_duration_ms(10000)
.build_with_bridge()
.build_with_bridge(true)
.await;

test_cluster
Expand Down
Loading

0 comments on commit 7c690e9

Please sign in to comment.