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::EthToSuiBridgeAction(_) => {
40            unreachable!()
41        }
42        BridgeAction::EmergencyAction(action) => {
43            build_emergency_op_approve_transaction(contract_address, signer, action.clone(), sigs)
44                .await
45        }
46        BridgeAction::BlocklistCommitteeAction(action) => {
47            build_committee_blocklist_approve_transaction(
48                contract_address,
49                signer,
50                action.clone(),
51                sigs,
52            )
53            .await
54        }
55        BridgeAction::LimitUpdateAction(action) => {
56            build_limit_update_approve_transaction(contract_address, signer, action.clone(), sigs)
57                .await
58        }
59        BridgeAction::AssetPriceUpdateAction(action) => {
60            build_asset_price_update_approve_transaction(
61                contract_address,
62                signer,
63                action.clone(),
64                sigs,
65            )
66            .await
67        }
68        BridgeAction::EvmContractUpgradeAction(action) => {
69            build_evm_upgrade_transaction(signer, action.clone(), sigs).await
70        }
71        BridgeAction::AddTokensOnSuiAction(_) => {
72            unreachable!();
73        }
74        BridgeAction::AddTokensOnEvmAction(action) => {
75            build_add_tokens_on_evm_transaction(contract_address, signer, action.clone(), sigs)
76                .await
77        }
78    }
79}
80
81pub async fn build_emergency_op_approve_transaction(
82    contract_address: EthAddress,
83    signer: EthSigner,
84    action: EmergencyAction,
85    sigs: &BridgeCommitteeValiditySignInfo,
86) -> BridgeResult<ContractCall<EthSigner, ()>> {
87    let contract = EthSuiBridge::new(contract_address, signer.into());
88
89    let message: eth_sui_bridge::Message = action.clone().try_into()?;
90    let signatures = sigs
91        .signatures
92        .values()
93        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
94        .collect::<Vec<_>>();
95    Ok(contract.execute_emergency_op_with_signatures(signatures, message))
96}
97
98pub async fn build_committee_blocklist_approve_transaction(
99    contract_address: EthAddress,
100    signer: EthSigner,
101    action: BlocklistCommitteeAction,
102    sigs: &BridgeCommitteeValiditySignInfo,
103) -> BridgeResult<ContractCall<EthSigner, ()>> {
104    let contract = EthBridgeCommittee::new(contract_address, signer.into());
105
106    let message: eth_bridge_committee::Message = action.clone().try_into()?;
107    let signatures = sigs
108        .signatures
109        .values()
110        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
111        .collect::<Vec<_>>();
112    Ok(contract.update_blocklist_with_signatures(signatures, message))
113}
114
115pub async fn build_limit_update_approve_transaction(
116    contract_address: EthAddress,
117    signer: EthSigner,
118    action: LimitUpdateAction,
119    sigs: &BridgeCommitteeValiditySignInfo,
120) -> BridgeResult<ContractCall<EthSigner, ()>> {
121    let contract = EthBridgeLimiter::new(contract_address, signer.into());
122
123    let message: eth_bridge_limiter::Message = action.clone().try_into()?;
124    let signatures = sigs
125        .signatures
126        .values()
127        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
128        .collect::<Vec<_>>();
129    Ok(contract.update_limit_with_signatures(signatures, message))
130}
131
132pub async fn build_asset_price_update_approve_transaction(
133    contract_address: EthAddress,
134    signer: EthSigner,
135    action: AssetPriceUpdateAction,
136    sigs: &BridgeCommitteeValiditySignInfo,
137) -> BridgeResult<ContractCall<EthSigner, ()>> {
138    let contract = EthBridgeConfig::new(contract_address, signer.into());
139    let message: eth_bridge_config::Message = action.clone().try_into()?;
140    let signatures = sigs
141        .signatures
142        .values()
143        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
144        .collect::<Vec<_>>();
145    Ok(contract.update_token_price_with_signatures(signatures, message))
146}
147
148pub async fn build_add_tokens_on_evm_transaction(
149    contract_address: EthAddress,
150    signer: EthSigner,
151    action: AddTokensOnEvmAction,
152    sigs: &BridgeCommitteeValiditySignInfo,
153) -> BridgeResult<ContractCall<EthSigner, ()>> {
154    let contract = EthBridgeConfig::new(contract_address, signer.into());
155    let message: eth_bridge_config::Message = action.clone().try_into()?;
156    let signatures = sigs
157        .signatures
158        .values()
159        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
160        .collect::<Vec<_>>();
161    Ok(contract.add_tokens_with_signatures(signatures, message))
162}
163
164pub async fn build_evm_upgrade_transaction(
165    signer: EthSigner,
166    action: EvmContractUpgradeAction,
167    sigs: &BridgeCommitteeValiditySignInfo,
168) -> BridgeResult<ContractCall<EthSigner, ()>> {
169    let contract_address = action.proxy_address;
170    let contract = EthCommitteeUpgradeableContract::new(contract_address, signer.into());
171    let message: eth_committee_upgradeable_contract::Message = action.clone().try_into()?;
172    let signatures = sigs
173        .signatures
174        .values()
175        .map(|sig| Bytes::from(sig.as_ref().to_vec()))
176        .collect::<Vec<_>>();
177    Ok(contract.upgrade_with_signatures(signatures, message))
178}
179
180// TODO: add tests for eth transaction building