Skip to content

Commit

Permalink
refactor: transfer to ICS20 first then burn (#296)
Browse files Browse the repository at this point in the history
* feat: transfer to ICS20 first, then burn

* fix: approve ics20 to spend from user in relayer

* nit
  • Loading branch information
Farhad-Shabani authored Feb 19, 2025
1 parent a3fde46 commit 0a1b62f
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 3 deletions.
8 changes: 7 additions & 1 deletion cairo-contracts/packages/apps/src/tests/transfer.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,13 @@ fn test_burn_ok() {
call_contract(ics20.address, selector!("send_transfer_internal"), @msg_transfer);

// Assert the `SendEvent` emitted.
spy.assert_send_event(ics20.address, SN_USER(), CS_USER(), prefixed_denom, cfg.amount);
spy
.assert_send_event(
ics20.address, SN_USER(), CS_USER(), prefixed_denom, cfg.amount,
); // Assert if the transfer happens from the ICS20 address.

// Assert if the burn happens by the ICS20 contract.
spy.assert_transfer_event(erc20.address, SN_USER(), ics20.address, cfg.amount);

// Check the balance of the sender.
erc20.assert_balance(SN_USER(), 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,9 @@ pub mod TokenTransferComponent {
) {
let token = self.get_token(denom.key());

token.burn(account, amount);
token.transfer_from(account, get_contract_address(), amount);

token.burn(get_contract_address(), amount);
}

fn refund_execute(
Expand Down
8 changes: 7 additions & 1 deletion cairo-contracts/packages/contracts/src/tests/transfer.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ fn test_mint_burn_roundtrip() {
ics20.address, CS_USER(), SN_USER(), prefixed_denom.clone(), transfer_cfg.amount, true,
);

let erc20: ERC20Contract = token_address.into();
let mut erc20: ERC20Contract = token_address.into();

// Assert if the transfer happens from the ICS20 address.
spy.assert_transfer_event(erc20.address, ics20.address, SN_USER(), transfer_cfg.amount);
Expand All @@ -123,6 +123,9 @@ fn test_mint_burn_roundtrip() {

start_cheat_caller_address(ics20.address, SN_USER());

// User approves the amount of burn allowance to the `TransferApp` contract.
erc20.approve(SN_USER(), ics20.address, transfer_cfg.amount);

let msg_transfer = transfer_cfg.dummy_msg_transfer(prefixed_denom.clone(), CS_USER());

// User approves the amount of allowance for the `TransferApp` contract.
Expand All @@ -131,6 +134,9 @@ fn test_mint_burn_roundtrip() {
// Assert the `SendEvent` emitted.
spy.assert_send_event(ics20.address, SN_USER(), CS_USER(), prefixed_denom, transfer_cfg.amount);

// Assert if the burn happens by the ICS20 contract.
spy.assert_transfer_event(erc20.address, SN_USER(), ics20.address, transfer_cfg.amount);

// Check the balance of the sender.
erc20.assert_balance(SN_USER(), 0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ use ibc::core::host::types::identifiers::{PortId as IbcPortId, Sequence};
use poseidon::Poseidon3Hasher;
use sha2::{Digest, Sha256};
use starknet::accounts::{Account, Call, ExecutionEncoding, SingleOwnerAccount};
use starknet::core::types::U256;
use starknet::macros::{selector, short_string};
use starknet::providers::Provider;
use starknet::signers::{LocalWallet, SigningKey};
Expand Down Expand Up @@ -542,6 +543,26 @@ fn test_query_unreceived_packets() -> Result<(), Error> {

runtime.sleep(Duration::from_secs(2)).await;

// approve ics20 contract to spend the tokens for `address_starknet_b`
{
let call_data = cairo_encoding.encode(&product![
ics20_contract_address,
U256::from(transfer_quantity)
])?;

let call = Call {
to: *ics20_token_address,
selector: selector!("approve"),
calldata: call_data,
};

let execution = starknet_account_b.execute_v3(vec![call]);

let tx_hash = execution.send().await?.transaction_hash;

starknet_chain.poll_tx_response(&tx_hash).await?;
}

// Create Starknet to Cosmos transfer
let starknet_ics20_send_message = {
let current_starknet_time = starknet_chain.query_chain_status().await?.time;
Expand Down
20 changes: 20 additions & 0 deletions relayer/crates/starknet-integration-tests/src/tests/ics20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,26 @@ fn test_starknet_ics20_contract() -> Result<(), Error> {

assert_eq!(balance_starknet_b_step_1.quantity, transfer_quantity.into());

// approve ics20 contract to spend the tokens for `address_starknet_b`
{
let call_data = cairo_encoding.encode(&product![
ics20_contract_address,
U256::from(transfer_quantity)
])?;

let call = Call {
to: *ics20_token_address,
selector: selector!("approve"),
calldata: call_data,
};

let execution = starknet_account_b.execute_v3(vec![call]);

let tx_hash = execution.send().await?.transaction_hash;

starknet_chain.poll_tx_response(&tx_hash).await?;
}

// create ibc transfer message

let starknet_ics20_send_message = {
Expand Down

0 comments on commit 0a1b62f

Please sign in to comment.