Skip to content

Commit

Permalink
feat(ckerc20): support subaccounts for ckERC20 withdrawals (#2510)
Browse files Browse the repository at this point in the history
Allow a user to specify two optional ledger subaccounts when withdrawing
ckERC20:

1. one on the ckETH ledger to pay for the transaction fee
2. on the ckERC20 ledger where the tokens are being withdrawn.
  • Loading branch information
gregorydemay authored Nov 12, 2024
1 parent da0106c commit 95b760e
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 291 deletions.
6 changes: 6 additions & 0 deletions rs/ethereum/cketh/minter/cketh_minter.did
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,12 @@ type WithdrawErc20Arg = record {

// Ethereum address to withdraw to.
recipient : text;

// The subaccount to burn ckETH from to pay for the transaction fee.
from_cketh_subaccount : opt Subaccount;

// The subaccount to burn ckERC20 from.
from_ckerc20_subaccount : opt Subaccount;
};

type RetrieveErc20Request = record {
Expand Down
3 changes: 3 additions & 0 deletions rs/ethereum/cketh/minter/src/endpoints/ckerc20.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::ledger_client::LedgerBurnError;
use crate::state::transactions::Erc20WithdrawalRequest;
use candid::{CandidType, Deserialize, Nat, Principal};
use icrc_ledger_types::icrc1::account::Subaccount;

#[derive(CandidType, Deserialize)]
pub struct WithdrawErc20Arg {
pub amount: Nat,
pub ckerc20_ledger_id: Principal,
pub recipient: String,
pub from_cketh_subaccount: Option<Subaccount>,
pub from_ckerc20_subaccount: Option<Subaccount>,
}

#[derive(Clone, PartialEq, Debug, CandidType, Deserialize)]
Expand Down
35 changes: 27 additions & 8 deletions rs/ethereum/cketh/minter/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ async fn withdraw_erc20(
amount,
ckerc20_ledger_id,
recipient,
from_cketh_subaccount,
from_ckerc20_subaccount,
}: WithdrawErc20Arg,
) -> Result<RetrieveErc20Request, WithdrawErc20Error> {
validate_ckerc20_active();
Expand Down Expand Up @@ -436,11 +438,24 @@ async fn withdraw_erc20(
let erc20_tx_fee = estimate_erc20_transaction_fee().await.ok_or_else(|| {
WithdrawErc20Error::TemporarilyUnavailable("Failed to retrieve current gas fee".to_string())
})?;
let cketh_account = Account {
owner: caller,
subaccount: from_cketh_subaccount,
};
let ckerc20_account = Account {
owner: caller,
subaccount: from_ckerc20_subaccount,
};
let now = ic_cdk::api::time();
log!(INFO, "[withdraw_erc20]: burning {:?} ckETH", erc20_tx_fee);
log!(
INFO,
"[withdraw_erc20]: burning {:?} ckETH from account {}",
erc20_tx_fee,
cketh_account
);
match cketh_ledger
.burn_from(
caller.into(),
cketh_account,
erc20_tx_fee,
BurnMemo::Erc20GasFee {
ckerc20_token_symbol: ckerc20_token.ckerc20_token_symbol.clone(),
Expand All @@ -453,13 +468,14 @@ async fn withdraw_erc20(
Ok(cketh_ledger_burn_index) => {
log!(
INFO,
"[withdraw_erc20]: burning {} {}",
"[withdraw_erc20]: burning {} {} from account {}",
ckerc20_withdrawal_amount,
ckerc20_token.ckerc20_token_symbol
ckerc20_token.ckerc20_token_symbol,
ckerc20_account
);
match LedgerClient::ckerc20_ledger(&ckerc20_token)
.burn_from(
caller.into(),
ckerc20_account,
ckerc20_withdrawal_amount,
BurnMemo::Erc20Convert {
ckerc20_withdrawal_id: cketh_ledger_burn_index.get(),
Expand All @@ -478,7 +494,8 @@ async fn withdraw_erc20(
ckerc20_ledger_burn_index,
erc20_contract_address: ckerc20_token.erc20_contract_address,
from: caller,
from_subaccount: None,
from_subaccount: from_ckerc20_subaccount
.and_then(LedgerSubaccount::from_bytes),
created_at: now,
};
log!(
Expand Down Expand Up @@ -507,8 +524,10 @@ async fn withdraw_erc20(
let reimbursement_request = ReimbursementRequest {
ledger_burn_index: cketh_ledger_burn_index,
reimbursed_amount: reimbursed_amount.change_units(),
to: caller,
to_subaccount: None,
to: cketh_account.owner,
to_subaccount: cketh_account
.subaccount
.and_then(LedgerSubaccount::from_bytes),
transaction_hash: None,
};
mutate_state(|s| {
Expand Down
Loading

0 comments on commit 95b760e

Please sign in to comment.