Skip to content

Commit 9cee7ca

Browse files
committed
Merge branch 'tiago/bridge-pool-fees' (#1795)
* origin/tiago/bridge-pool-fees: Changelog for #1795 Fix the denomination of Bridge pool gas fees Add `DenominatedAmount::is_zero` Fix docstring Make Bridge pool gas payer CLI arg optional Standardize Bridge pool transfer CLI args Update CLI args for Bridge pool transfers Test paying Bridge pool gas fees in ERC20 tokens Arbitrary gas fees in Ethereum events `init_balances` Fix bug in `determine_escrow_checks` and document corner cases Add misc Bridge pool VP tests Fix test_minting_wnam() unit test Validate different gas fee tokens in Bridge pool VP Check correct gas fee token in Bridge pool transfers Fix compilation errors from prev commit Add token addr field to Bridge pool gas fees Move `check_balance_changes` to Bridge pool VP module
2 parents c015932 + 968f1a6 commit 9cee7ca

File tree

15 files changed

+660
-339
lines changed

15 files changed

+660
-339
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Allow Bridge pool transfer fees to be paid in arbitrary token types (except
2+
NUTs) ([\#1795](https://github.com/anoma/namada/pull/1795))

apps/src/lib/cli.rs

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,6 +2484,22 @@ pub mod args {
24842484
);
24852485
pub const BLOCK_HEIGHT: Arg<BlockHeight> = arg("block-height");
24862486
pub const BLOCK_HEIGHT_OPT: ArgOpt<BlockHeight> = arg_opt("height");
2487+
pub const BRIDGE_POOL_GAS_AMOUNT: ArgDefault<token::DenominatedAmount> =
2488+
arg_default(
2489+
"pool-gas-amount",
2490+
DefaultFn(|| token::DenominatedAmount {
2491+
amount: token::Amount::default(),
2492+
denom: NATIVE_MAX_DECIMAL_PLACES.into(),
2493+
}),
2494+
);
2495+
pub const BRIDGE_POOL_GAS_PAYER: ArgOpt<WalletAddress> =
2496+
arg_opt("pool-gas-payer");
2497+
pub const BRIDGE_POOL_GAS_TOKEN: ArgDefaultFromCtx<WalletAddress> =
2498+
arg_default_from_ctx(
2499+
"pool-gas-token",
2500+
DefaultFn(|| "NAM".parse().unwrap()),
2501+
);
2502+
pub const BRIDGE_POOL_TARGET: Arg<EthAddress> = arg("target");
24872503
pub const BROADCAST_ONLY: ArgFlag = flag("broadcast-only");
24882504
pub const CHAIN_ID: Arg<ChainId> = arg("chain-id");
24892505
pub const CHAIN_ID_OPT: ArgOpt<ChainId> = CHAIN_ID.opt();
@@ -2515,7 +2531,7 @@ pub mod args {
25152531
pub const ETH_GAS: ArgOpt<u64> = arg_opt("eth-gas");
25162532
pub const ETH_GAS_PRICE: ArgOpt<u64> = arg_opt("eth-gas-price");
25172533
pub const ETH_ADDRESS: Arg<EthAddress> = arg("ethereum-address");
2518-
pub const ETH_ADDRESS_OPT: ArgOpt<EthAddress> = arg_opt("ethereum-address");
2534+
pub const ETH_ADDRESS_OPT: ArgOpt<EthAddress> = ETH_ADDRESS.opt();
25192535
pub const ETH_RPC_ENDPOINT: ArgDefault<String> = arg_default(
25202536
"eth-rpc-endpoint",
25212537
DefaultFn(|| "http://localhost:8545".into()),
@@ -2532,7 +2548,6 @@ pub mod args {
25322548
arg_default("gas-limit", DefaultFn(|| GasLimit::from(20_000)));
25332549
pub const FEE_TOKEN: ArgDefaultFromCtx<WalletAddress> =
25342550
arg_default_from_ctx("gas-token", DefaultFn(|| "NAM".parse().unwrap()));
2535-
pub const BRIDGE_GAS_PAYER: Arg<WalletAddress> = arg("bridge-gas-payer");
25362551
pub const GENESIS_PATH: Arg<PathBuf> = arg("genesis-path");
25372552
pub const GENESIS_VALIDATOR: ArgOpt<String> =
25382553
arg("genesis-validator").opt();
@@ -2846,7 +2861,8 @@ pub mod args {
28462861
sender: ctx.get(&self.sender),
28472862
amount: self.amount,
28482863
fee_amount: self.fee_amount,
2849-
fee_payer: ctx.get(&self.fee_payer),
2864+
fee_payer: self.fee_payer.map(|fee_payer| ctx.get(&fee_payer)),
2865+
fee_token: ctx.get(&self.fee_token),
28502866
code_path: self.code_path,
28512867
}
28522868
}
@@ -2856,15 +2872,13 @@ pub mod args {
28562872
fn parse(matches: &ArgMatches) -> Self {
28572873
let tx = Tx::parse(matches);
28582874
let asset = ERC20.parse(matches);
2859-
let recipient = ETH_ADDRESS.parse(matches);
2860-
let sender = ADDRESS.parse(matches);
2875+
let recipient = BRIDGE_POOL_TARGET.parse(matches);
2876+
let sender = SOURCE.parse(matches);
28612877
let amount = InputAmount::Unvalidated(AMOUNT.parse(matches));
2862-
let fee_amount = FEE_AMOUNT_OPT
2863-
.parse(matches)
2864-
.map_or_else(token::Amount::default, |denom_amount| {
2865-
denom_amount.amount
2866-
});
2867-
let fee_payer = BRIDGE_GAS_PAYER.parse(matches);
2878+
let fee_amount =
2879+
InputAmount::Unvalidated(BRIDGE_POOL_GAS_AMOUNT.parse(matches));
2880+
let fee_payer = BRIDGE_POOL_GAS_PAYER.parse(matches);
2881+
let fee_token = BRIDGE_POOL_GAS_TOKEN.parse(matches);
28682882
let code_path = PathBuf::from(TX_BRIDGE_POOL_WASM);
28692883
let nut = NUT.parse(matches);
28702884
Self {
@@ -2875,6 +2889,7 @@ pub mod args {
28752889
amount,
28762890
fee_amount,
28772891
fee_payer,
2892+
fee_token,
28782893
code_path,
28792894
nut,
28802895
}
@@ -2888,27 +2903,29 @@ pub mod args {
28882903
.help("The Ethereum address of the ERC20 token."),
28892904
)
28902905
.arg(
2891-
ETH_ADDRESS
2906+
BRIDGE_POOL_TARGET
28922907
.def()
28932908
.help("The Ethereum address receiving the tokens."),
28942909
)
28952910
.arg(
2896-
ADDRESS
2897-
.def()
2898-
.help("The Namada address sending the tokens."),
2911+
SOURCE.def().help("The Namada address sending the tokens."),
28992912
)
29002913
.arg(
29012914
AMOUNT.def().help(
29022915
"The amount of tokens being sent across the bridge.",
29032916
),
29042917
)
2905-
.arg(FEE_AMOUNT_OPT.def().help(
2906-
"The amount of NAM you wish to pay to have this transfer \
2918+
.arg(BRIDGE_POOL_GAS_AMOUNT.def().help(
2919+
"The amount of gas you wish to pay to have this transfer \
29072920
relayed to Ethereum.",
29082921
))
2909-
.arg(BRIDGE_GAS_PAYER.def().help(
2910-
"The Namada address of the account paying the fee for the \
2911-
Ethereum transaction.",
2922+
.arg(BRIDGE_POOL_GAS_PAYER.def().help(
2923+
"The Namada address of the account paying the gas. By \
2924+
default, it is the same as the source.",
2925+
))
2926+
.arg(BRIDGE_POOL_GAS_TOKEN.def().help(
2927+
"The token for paying the Bridge pool gas fees. Defaults \
2928+
to NAM.",
29122929
))
29132930
.arg(NUT.def().help(
29142931
"Add Non Usable Tokens (NUTs) to the Bridge pool. These \

apps/src/lib/node/ledger/shell/finalize_block.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1745,6 +1745,7 @@ mod test_finalize_block {
17451745
///
17461746
/// Sets the validity of the transfer on Ethereum's side.
17471747
fn test_bp_nonce_is_incremented_aux(valid_transfer: bool) {
1748+
use crate::node::ledger::shell::address::nam;
17481749
test_bp(|shell: &mut TestShell| {
17491750
let asset = EthAddress([0xff; 20]);
17501751
let receiver = EthAddress([0xaa; 20]);
@@ -1769,7 +1770,6 @@ mod test_finalize_block {
17691770
}
17701771
// add bertha's gas fees the pool
17711772
{
1772-
use crate::node::ledger::shell::address::nam;
17731773
let amt: Amount = 999_999_u64.into();
17741774
let pool_balance_key = token::balance_key(
17751775
&nam(),
@@ -1795,6 +1795,7 @@ mod test_finalize_block {
17951795
sender: bertha.clone(),
17961796
},
17971797
gas_fee: GasFee {
1798+
token: nam(),
17981799
amount: 10u64.into(),
17991800
payer: bertha.clone(),
18001801
},

core/src/ledger/eth_bridge/storage/bridge_pool.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ mod test_bridge_pool_tree {
415415
use proptest::prelude::*;
416416

417417
use super::*;
418+
use crate::types::address::nam;
418419
use crate::types::eth_bridge_pool::{
419420
GasFee, TransferToEthereum, TransferToEthereumKind,
420421
};
@@ -441,6 +442,7 @@ mod test_bridge_pool_tree {
441442
amount: 1.into(),
442443
},
443444
gas_fee: GasFee {
445+
token: nam(),
444446
amount: 0.into(),
445447
payer: bertha_address(),
446448
},
@@ -468,6 +470,7 @@ mod test_bridge_pool_tree {
468470
amount: (i as u64).into(),
469471
},
470472
gas_fee: GasFee {
473+
token: nam(),
471474
amount: 0.into(),
472475
payer: bertha_address(),
473476
},
@@ -496,6 +499,7 @@ mod test_bridge_pool_tree {
496499
amount: (i as u64).into(),
497500
},
498501
gas_fee: GasFee {
502+
token: nam(),
499503
amount: 0.into(),
500504
payer: bertha_address(),
501505
},
@@ -534,6 +538,7 @@ mod test_bridge_pool_tree {
534538
amount: 1.into(),
535539
},
536540
gas_fee: GasFee {
541+
token: nam(),
537542
amount: 0.into(),
538543
payer: bertha_address(),
539544
},
@@ -562,6 +567,7 @@ mod test_bridge_pool_tree {
562567
amount: (i as u64).into(),
563568
},
564569
gas_fee: GasFee {
570+
token: nam(),
565571
amount: 0.into(),
566572
payer: bertha_address(),
567573
},
@@ -593,6 +599,7 @@ mod test_bridge_pool_tree {
593599
amount: 1u64.into(),
594600
},
595601
gas_fee: GasFee {
602+
token: nam(),
596603
amount: 0.into(),
597604
payer: bertha_address(),
598605
},
@@ -617,6 +624,7 @@ mod test_bridge_pool_tree {
617624
amount: 1u64.into(),
618625
},
619626
gas_fee: GasFee {
627+
token: nam(),
620628
amount: 0.into(),
621629
payer: bertha_address(),
622630
},
@@ -653,6 +661,7 @@ mod test_bridge_pool_tree {
653661
amount: 1.into(),
654662
},
655663
gas_fee: GasFee {
664+
token: nam(),
656665
amount: 0.into(),
657666
payer: bertha_address(),
658667
},
@@ -672,6 +681,7 @@ mod test_bridge_pool_tree {
672681
amount: 1u64.into(),
673682
},
674683
gas_fee: GasFee {
684+
token: nam(),
675685
amount: 0.into(),
676686
payer: bertha_address(),
677687
},
@@ -704,6 +714,7 @@ mod test_bridge_pool_tree {
704714
amount: 0.into(),
705715
},
706716
gas_fee: GasFee {
717+
token: nam(),
707718
amount: 0.into(),
708719
payer: bertha_address(),
709720
},
@@ -733,6 +744,7 @@ mod test_bridge_pool_tree {
733744
amount: (i as u64).into(),
734745
},
735746
gas_fee: GasFee {
747+
token: nam(),
736748
amount: 0.into(),
737749
payer: bertha_address(),
738750
},
@@ -763,6 +775,7 @@ mod test_bridge_pool_tree {
763775
amount: (i as u64).into(),
764776
},
765777
gas_fee: GasFee {
778+
token: nam(),
766779
amount: 0.into(),
767780
payer: bertha_address(),
768781
},
@@ -793,6 +806,7 @@ mod test_bridge_pool_tree {
793806
amount: (i as u64).into(),
794807
},
795808
gas_fee: GasFee {
809+
token: nam(),
796810
amount: 0.into(),
797811
payer: bertha_address(),
798812
},
@@ -821,6 +835,7 @@ mod test_bridge_pool_tree {
821835
amount: (i as u64).into(),
822836
},
823837
gas_fee: GasFee {
838+
token: nam(),
824839
amount: 0.into(),
825840
payer: bertha_address(),
826841
},
@@ -849,6 +864,7 @@ mod test_bridge_pool_tree {
849864
amount: (i as u64).into(),
850865
},
851866
gas_fee: GasFee {
867+
token: nam(),
852868
amount: 0.into(),
853869
payer: bertha_address(),
854870
},
@@ -877,6 +893,7 @@ mod test_bridge_pool_tree {
877893
amount: (i as u64).into(),
878894
},
879895
gas_fee: GasFee {
896+
token: nam(),
880897
amount: 0.into(),
881898
payer: bertha_address(),
882899
},
@@ -909,6 +926,7 @@ mod test_bridge_pool_tree {
909926
amount: Default::default(),
910927
},
911928
gas_fee: GasFee {
929+
token: nam(),
912930
amount: Default::default(),
913931
payer: bertha_address(),
914932
},

core/src/types/eth_bridge_pool.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ pub struct PendingTransferAppendix<'transfer> {
7575
pub kind: Cow<'transfer, TransferToEthereumKind>,
7676
/// The sender of the transfer.
7777
pub sender: Cow<'transfer, Address>,
78-
/// The amount of gas fees (in NAM)
79-
/// paid by the user sending this transfer
78+
/// The amount of gas fees paid by the user
79+
/// sending this transfer.
8080
pub gas_fee: Cow<'transfer, GasFee>,
8181
}
8282

@@ -158,10 +158,10 @@ pub struct TransferToEthereum {
158158
BorshSchema,
159159
)]
160160
pub struct PendingTransfer {
161-
/// The message to send to Ethereum to
161+
/// Transfer to Ethereum data.
162162
pub transfer: TransferToEthereum,
163-
/// The amount of gas fees (in NAM)
164-
/// paid by the user sending this transfer
163+
/// Amount of gas fees paid by the user
164+
/// sending the transfer.
165165
pub gas_fee: GasFee,
166166
}
167167

@@ -267,9 +267,9 @@ impl From<&PendingTransfer> for Key {
267267
}
268268
}
269269

270-
/// The amount of NAM to be payed to the relayer of
271-
/// a transfer across the Ethereum Bridge to compensate
272-
/// for Ethereum gas fees.
270+
/// The amount of fees to be payed, in Namada, to the relayer
271+
/// of a transfer across the Ethereum Bridge, compensating
272+
/// for Ethereum gas costs.
273273
#[derive(
274274
Debug,
275275
Clone,
@@ -285,15 +285,19 @@ impl From<&PendingTransfer> for Key {
285285
BorshSchema,
286286
)]
287287
pub struct GasFee {
288-
/// The amount of fees (in NAM)
288+
/// The amount of fees.
289289
pub amount: Amount,
290290
/// The account of fee payer.
291291
pub payer: Address,
292+
/// The address of the fungible token to draw
293+
/// gas fees from.
294+
pub token: Address,
292295
}
293296

294297
#[cfg(test)]
295298
mod test_eth_bridge_pool_types {
296299
use super::*;
300+
use crate::types::address::nam;
297301
use crate::types::address::testing::established_address_1;
298302

299303
/// Test that [`PendingTransfer`] and [`TransferToEthereum`]
@@ -309,6 +313,7 @@ mod test_eth_bridge_pool_types {
309313
sender: established_address_1(),
310314
},
311315
gas_fee: GasFee {
316+
token: nam(),
312317
amount: 10u64.into(),
313318
payer: established_address_1(),
314319
},

core/src/types/token.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,12 @@ impl DenominatedAmount {
309309
}
310310
}
311311

312+
/// Check if the inner [`Amount`] is zero.
313+
#[inline]
314+
pub fn is_zero(&self) -> bool {
315+
self.amount.is_zero()
316+
}
317+
312318
/// A precise string representation. The number of
313319
/// decimal places in this string gives the denomination.
314320
/// This not true of the string produced by the `Display`

0 commit comments

Comments
 (0)