Skip to content

Commit e2eb391

Browse files
authored
fix(starknet): approve for native token (#255)
* fix(starknet): approve for native tokens * chore: bumped versions
1 parent 8803e58 commit e2eb391

File tree

4 files changed

+41
-14
lines changed

4 files changed

+41
-14
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bridge-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bridge-cli"
3-
version = "0.3.41"
3+
version = "0.3.42"
44
edition = "2021"
55
repository = "https://github.com/Near-One/bridge-sdk-rs"
66
rust-version = "1.88.0"

bridge-sdk/bridge-clients/starknet-bridge-client/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "starknet-bridge-client"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
edition = "2021"
55
rust-version = "1.88.0"
66

bridge-sdk/bridge-clients/starknet-bridge-client/src/starknet_bridge_client.rs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ pub use builder::StarknetBridgeClientBuilder;
2020
mod builder;
2121
pub mod error;
2222

23+
/// STRK native token contract address on Starknet.
24+
const STRK_TOKEN: Felt = Felt::from_hex_unchecked(
25+
"0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
26+
);
27+
2328
/// Event data extracted from a Starknet `InitTransfer` receipt.
2429
#[derive(Debug)]
2530
pub struct StarknetInitTransferEvent {
@@ -228,7 +233,8 @@ impl StarknetBridgeClient {
228233

229234
/// Initiate a transfer from Starknet.
230235
///
231-
/// This issues a multicall: first ERC-20 `approve`, then `init_transfer`.
236+
/// This issues a multicall: ERC-20 `approve` for the transfer token (amount + fee),
237+
/// optionally ERC-20 `approve` for STRK (native_fee), then `init_transfer`.
232238
#[tracing::instrument(skip_all, name = "STARKNET INIT TRANSFER")]
233239
#[allow(clippy::too_many_arguments)]
234240
pub async fn init_transfer(
@@ -242,12 +248,33 @@ impl StarknetBridgeClient {
242248
) -> Result<Felt> {
243249
let bridge = self.omni_bridge_address()?;
244250

245-
// ERC-20 approve call (amount as u256 = [low, high])
246-
let approve_call = Call {
247-
to: token,
248-
selector: selector!("approve"),
249-
calldata: vec![bridge, Self::encode_u128(amount), Felt::ZERO],
250-
};
251+
let mut calls = Vec::new();
252+
253+
// Approve transfer token for amount + fee
254+
let token_total: u128 = amount.checked_add(fee).ok_or_else(|| {
255+
StarknetBridgeClientError::InvalidArgument(
256+
"amount + fee overflows u128".to_string(),
257+
)
258+
})?;
259+
260+
if token_total > 0 {
261+
calls.push(Call {
262+
to: token,
263+
selector: selector!("approve"),
264+
calldata: vec![bridge, Self::encode_u128(token_total), Felt::ZERO],
265+
});
266+
}
267+
268+
// Approve STRK token for native_fee.
269+
// On Starknet there is no msg.value, so the bridge contract pulls the
270+
// native fee from the caller via ERC-20 transferFrom on STRK.
271+
if native_fee > 0 {
272+
calls.push(Call {
273+
to: STRK_TOKEN,
274+
selector: selector!("approve"),
275+
calldata: vec![bridge, Self::encode_u128(native_fee), Felt::ZERO],
276+
});
277+
}
251278

252279
// init_transfer call
253280
let mut calldata = vec![
@@ -259,13 +286,13 @@ impl StarknetBridgeClient {
259286
calldata.extend(Self::encode_byte_array(&recipient));
260287
calldata.extend(Self::encode_byte_array(&message));
261288

262-
let init_call = Call {
289+
calls.push(Call {
263290
to: bridge,
264291
selector: selector!("init_transfer"),
265292
calldata,
266-
};
293+
});
267294

268-
self.send_and_wait(vec![approve_call, init_call]).await
295+
self.send_and_wait(calls).await
269296
}
270297

271298
/// Finalize a transfer to Starknet using a `SignTransferEvent` from Near.

0 commit comments

Comments
 (0)