sui_bridge/
eth_transaction_builder.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::abi::{
5    EthBridgeCommittee, EthBridgeLimiter, EthCommitteeUpgradeableContract, eth_bridge_committee,
6    eth_committee_upgradeable_contract, eth_sui_bridge,
7};
8use crate::abi::{EthBridgeConfig, eth_bridge_config, eth_bridge_limiter};
9use crate::error::{BridgeError, BridgeResult};
10use crate::types::{
11    AddTokensOnEvmAction, AssetPriceUpdateAction, BlocklistCommitteeAction,
12    BridgeCommitteeValiditySignInfo, EvmContractUpgradeAction, LimitUpdateAction,
13    VerifiedCertifiedBridgeAction,
14};
15use crate::utils::EthSigner;
16use crate::{
17    abi::EthSuiBridge,
18    types::{BridgeAction, EmergencyAction},
19};
20use ethers::prelude::*;
21use ethers::types::Address as EthAddress;
22
23pub async fn build_eth_transaction(
24    contract_address: EthAddress,
25    signer: EthSigner,
26    action: VerifiedCertifiedBridgeAction,
27) -> BridgeResult<ContractCall<EthSigner, ()>> {
28    if !action.is_governace_action() {
29        return Err(BridgeError::ActionIsNotGovernanceAction(
30            action.data().clone(),
31        ));
32    }
33    // TODO: Check chain id?
34    let sigs = action.auth_sig();
35    match action.data() {
36        BridgeAction::SuiToEthBridgeAction(_) => {
37            unreachable!()
38        }
39        BridgeAction::SuiToEthTokenTransfer(_) => {
40            unreachable!()
41        }
42        BridgeAction::EthToSuiBridgeAction(_) => {
43            unreachable!()
44        }
45        BridgeAction::EmergencyAction(action) => {
46            build_emergency_op_approve_transaction(contract_address, signer, action.clone(), sigs)
47                .await
48        }
49        BridgeAction::BlocklistCommitteeAction(action) => {
50            build_committee_blocklist_approve_transaction(
51                contract_address,
52                signer,
53                action.clone(),
54                sigs,
55            )
56            .await
57        }
58        BridgeAction::LimitUpdateAction(action) => {
59            build_limit_update_approve_transaction(contract_address, signer, action.clone(), sigs)
60                .await
61        }
62        BridgeAction::AssetPriceUpdateAction(action) => {
63            build_asset_price_update_approve_transaction(
64                contract_address,
65                signer,
66                action.clone(),
67                sigs,
68            )
69            .await
70        }
71        BridgeAction::EvmContractUpgradeAction(action) => {
72            build_evm_upgrade_transaction(signer, action.clone(), sigs).await
73        }
74        BridgeAction::AddTokensOnSuiAction(_) => {
75            unreachable!();
76        }
77        BridgeAction::AddTokensOnEvmAction(action) => {
78            build_add_tokens_on_evm_transaction(contract_address, signer, action.clone(), sigs)
79                .await
80        }
81    }
82}
83
84pub async fn build_emergency_op_approve_transaction(
85    contract_address: EthAddress,
86    signer: EthSigner,
87    action: EmergencyAction,
88    sigs: &BridgeCommitteeValiditySignInfo,
89) -> BridgeResult<ContractCall<EthSigner, ()>> {
90    let contract = EthSuiBridge::new(contract_address, signer.into());
91
92    let message: eth_sui_bridge::Message = action.clone().try_into()?;
93    let signatures = sigs
94        .signatures
95        .values()
96        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
97        .collect::<Vec<_>>();
98    Ok(contract.execute_emergency_op_with_signatures(signatures, message))
99}
100
101pub async fn build_committee_blocklist_approve_transaction(
102    contract_address: EthAddress,
103    signer: EthSigner,
104    action: BlocklistCommitteeAction,
105    sigs: &BridgeCommitteeValiditySignInfo,
106) -> BridgeResult<ContractCall<EthSigner, ()>> {
107    let contract = EthBridgeCommittee::new(contract_address, signer.into());
108
109    let message: eth_bridge_committee::Message = action.clone().try_into()?;
110    let signatures = sigs
111        .signatures
112        .values()
113        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
114        .collect::<Vec<_>>();
115    Ok(contract.update_blocklist_with_signatures(signatures, message))
116}
117
118pub async fn build_limit_update_approve_transaction(
119    contract_address: EthAddress,
120    signer: EthSigner,
121    action: LimitUpdateAction,
122    sigs: &BridgeCommitteeValiditySignInfo,
123) -> BridgeResult<ContractCall<EthSigner, ()>> {
124    let contract = EthBridgeLimiter::new(contract_address, signer.into());
125
126    let message: eth_bridge_limiter::Message = action.clone().try_into()?;
127    let signatures = sigs
128        .signatures
129        .values()
130        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
131        .collect::<Vec<_>>();
132    Ok(contract.update_limit_with_signatures(signatures, message))
133}
134
135pub async fn build_asset_price_update_approve_transaction(
136    contract_address: EthAddress,
137    signer: EthSigner,
138    action: AssetPriceUpdateAction,
139    sigs: &BridgeCommitteeValiditySignInfo,
140) -> BridgeResult<ContractCall<EthSigner, ()>> {
141    let contract = EthBridgeConfig::new(contract_address, signer.into());
142    let message: eth_bridge_config::Message = action.clone().try_into()?;
143    let signatures = sigs
144        .signatures
145        .values()
146        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
147        .collect::<Vec<_>>();
148    Ok(contract.update_token_price_with_signatures(signatures, message))
149}
150
151pub async fn build_add_tokens_on_evm_transaction(
152    contract_address: EthAddress,
153    signer: EthSigner,
154    action: AddTokensOnEvmAction,
155    sigs: &BridgeCommitteeValiditySignInfo,
156) -> BridgeResult<ContractCall<EthSigner, ()>> {
157    let contract = EthBridgeConfig::new(contract_address, signer.into());
158    let message: eth_bridge_config::Message = action.clone().try_into()?;
159    let signatures = sigs
160        .signatures
161        .values()
162        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
163        .collect::<Vec<_>>();
164    Ok(contract.add_tokens_with_signatures(signatures, message))
165}
166
167pub async fn build_evm_upgrade_transaction(
168    signer: EthSigner,
169    action: EvmContractUpgradeAction,
170    sigs: &BridgeCommitteeValiditySignInfo,
171) -> BridgeResult<ContractCall<EthSigner, ()>> {
172    let contract_address = action.proxy_address;
173    let contract = EthCommitteeUpgradeableContract::new(contract_address, signer.into());
174    let message: eth_committee_upgradeable_contract::Message = action.clone().try_into()?;
175    let signatures = sigs
176        .signatures
177        .values()
178        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
179        .collect::<Vec<_>>();
180    Ok(contract.upgrade_with_signatures(signatures, message))
181}
182
183// TODO: add tests for eth transaction building