# Decodificando swaps SCW

Com carteiras de contrato inteligente (SCWs), as trocas seguem um caminho muito diferente do que com carteiras tradicionais do Ethereum/EVM. Essa diferença pode ser confusa, especialmente quando algo dá errado. Mas, uma vez que você entende os principais participantes do fluxo — e como ler o que aconteceu passo a passo no app e no explorador — as coisas começam a fazer sentido.

Vamos analisar isso juntos.

***

#### De um toque à execução on-chain: o que realmente acontece

Quando você toca em “Swap” no app, parece uma única ação. Na realidade, você está iniciando um processo em várias camadas construído sobre a abstração de conta do Ethereum (ERC-4337). Sua transação não vai direto para a blockchain como em uma carteira normal. Em vez disso, ela faz um desvio:

1. Nós construímos a rota. Pedimos ao motor de roteamento (como o 1inch) para encontrar o melhor caminho para sua troca e simulamos para garantir que funciona. Estimamos o gás, validamos que você tem os tokens e empacotamos as instruções em um formato especial: um `UserOperation`.
2. Um `bundler` entra em cena. Esse é um ator off-chain responsável por submeter UserOperations à blockchain. Ele verifica sua operação, confirma que é válida e pré-paga o gás por você (é reembolsado depois).
3. Sua UserOp entra na blockchain através do `EntryPoint` smart contract. Pense no EntryPoint como o portão pelo qual todas as transações SCW passam. O EntryPoint executa checagens finais e, se tudo parecer certo…
4. O EntryPoint diz à sua Smart Contract Wallet (SCW) para executar a troca. Sua SCW chama o roteador (por exemplo, 1inch), o roteador chama os pools, os tokens se movem e o resultado volta para sua carteira.

Então, para resumir: você toca em swap → nós simulamos → o bundler submete → EntryPoint valida → sua SCW executa.

***

#### Vamos ver um exemplo real

Agora que entendemos o fluxo em alto nível, vamos ver como isso se desenrola em uma troca real: primeiro no app, depois on-chain:

<figure><img src="https://3303217878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFKhEXxJL95YqC19XHlF%2Fuploads%2FU1GSRk2DpRQfQX1RZwSK%2Fimage.png?alt=media&#x26;token=a86ea5fd-705e-43ce-b5a2-c30f8cfcc5ec" alt=""><figcaption></figcaption></figure>

Aqui está o que vemos:

* Trocamos 1 USDC por 0,765 KTA.
* A troca foi executada na Base (observe o ícone da Base nos símbolos das moedas).
* Pagamos:
  * $0,03 de gás (em ETH)
  * 0,22% de taxa de swap para a goodcryptoX
  * 0,05% de taxa de roteador para a 1inch
* A rota foi simples: 100% através de um pool Uniswap v4.
* Bundler: Alchemy (veja o Passo 2 acima para recapitulação)
* Links do explorador aparecem se a transação alcançou a blockchain e foi registrada no bloco (mesmo que falhe)

Até aqui, tudo bem. Em seguida, vamos clicar no link do BaseScan para ver como essa transação aparece on-chain:

<figure><img src="https://3303217878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFKhEXxJL95YqC19XHlF%2Fuploads%2FzZOTevTgzK4edwRl4iCw%2Fimage.png?alt=media&#x26;token=16995823-34da-4628-b17f-6fe314fbaa1f" alt=""><figcaption></figcaption></figure>

**De:** esta não é sua carteira — é o bundler da Alchemy. Isso é esperado, já que o bundler submeteu a transação.

**Para:** EntryPoint (v0.6.0). Novamente, esperado — todas as transações SCW entram por aqui.

**Transações internas:** mostra fluxos de tokens nativos (ETH na Base) dentro da transação. Veja o que vemos:

* Nossa carteira (…0A5) enviou ETH ao EntryPoint para a taxa de gás.
* O EntryPoint reembolsou o bundler com o custo real do gás (já que o bundler pré-pagou o gás em seu nome; veja o Passo 2 acima). Qualquer ETH restante permaneceu no EntryPoint como seu depósito para transações futuras.

**Transferências ERC-20:** mostra os movimentos reais dos tokens:

Nossa carteira não enviou USDC diretamente. Em vez disso, o contrato token USDC (…2A8) processou e disparou as transferências. Isso é normal: em cadeias EVM, as transferências de tokens são tratadas pelo próprio contrato do token após receber uma instrução da sua smart contract wallet.

1. O contrato USDC dividiu nosso 1 USDC em três transferências:
   * 0,0022 USDC para a carteira de taxas do nosso protocolo (…608A)
   * 0,0005 USDC para a carteira de taxas da 1inch (…1DE5)
   * Os restantes 0,9973 USDC para o roteador Uniswap v4 (…Universal Router)
2. O roteador Uniswap v4 o repassou ao Pool Manager do Uniswap v4 (contrato único que lida com todos os pools v4).
3. O Pool Manager executou a troca: USDC entra → KTA sai.
4. O KTA foi roteado de volta através do Aggregation Router da 1inch, que o encaminhou para nossa carteira (…0A5).

***

### 🧩 Como decodificar uma transação SCW falhada

Agora que entendemos como as trocas com smart-contract-wallet (SCW) funcionam — e já passamos por uma negociação bem-sucedida — vamos usar as mesmas ferramentas para decifrar uma que falhou.

Usaremos outro caso real: uma troca ETH → token no Ethereum que falhou dentro do contrato EntryPoint porque não havia ETH suficiente para cobrir tanto a troca quanto a taxa de gás.

Ok, então você vê “Error” como o status da sua troca no app ou recebe uma notificação push de que sua troca falhou. O que fazer?

***

#### Passo 1 — Verifique os detalhes do pedido na goodcryptoX

Aqui está o que você vê neste caso:

<figure><img src="https://3303217878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFKhEXxJL95YqC19XHlF%2Fuploads%2FwrYogeeljYqmlMsWsucl%2Fimage.png?alt=media&#x26;token=a5b58912-2a41-4e26-91ad-e5f53da6d335" alt=""><figcaption></figcaption></figure>

Usando a estrutura que desenvolvemos anteriormente, você nota rapidamente:

* O status da troca é `Error` *(falhou?)*  &#x20;
* Nenhuma mensagem de erro é exibida *(isso é incomum)*
* Há taxa de gás *(atingiu a blockchain?)*
* Há rota exibida *(a simulação deu certo?)*
* Há links para exploradores de blockchain *(posso checar a tx na blockchain!).*

Vamos checar sua intuição:

* O `Error` status significa que a troca falhou
* Deveria haver tanto uma mensagem de erro legível para humanos (traduzida do bruto) quanto a mensagem bruta. A ausência de mensagem de erro definitivamente indica que algo incomum aconteceu
* A taxa de gás de fato significa que a transação alcançou a blockchain e alguma atividade on-chain aconteceu (que consumiu gás)
* A rota confirma que a simulação da transação passou e resultou em um caminho claro para execução
* Os links do explorador confirmam que a transação alcançou a blockchain — mesmo que tenha falhado. Devemos definitivamente abrir um deles e investigar mais a fundo

***

**Passo 2 – Abra a transação no explorador de blockchain**

Você toca no link do Etherscan para ver o que aconteceu:

<figure><img src="https://3303217878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFKhEXxJL95YqC19XHlF%2Fuploads%2FAQ6NDCTqMrDc6JkAvTVw%2Fimage.png?alt=media&#x26;token=4da84760-6804-4583-8224-2b0dea1a5cea" alt=""><figcaption></figcaption></figure>

À primeira vista, as coisas ficam ainda mais confusas:

* O status diz ✅ Success *— espere, o quê?!*
* Mas nós já sabemos que a troca **não foi concluída**
* Sob o campo “To” (EntryPoint), há uma pequena mensagem amarela:

  > *“<mark style="color:$warning;">Embora um ou mais erros tenham ocorrido \[execution reverted] Contract Execution Completed</mark>”*

Então, o que está realmente acontecendo aqui?

Lembre-se do fluxo de transação SCW que cobrimos antes:

* o bundler empacota sua troca em um `UserOperation` (um pacote de dados com sua lógica de swap)
* depois envia para o contrato EntryPoint
* O EntryPoint valida (checando seu saldo, assinatura e nonce)
* se tudo estiver certo, ele executa sua intenção — chamando roteadores, pools e movendo tokens.

Do ponto de vista da blockchain, porém, tudo isso parece apenas “bundler envia dados para EntryPoint”.&#x20;

Em termos SCW, essa etapa é chamada de `transação` externa.

E essa transação teve sucesso: os dados foram entregues e o EntryPoint começou a executar sua lógica interna. Daí o ✅ Success no topo.

***

Mas o explorador, sendo cuidadoso, ainda avisa que algo falhou *dentro* do EntryPoint com aquela pequena nota amarela. Para o explorador, essa falha interna não é suficiente para marcar a transação como falhada.

Agora, outro detalhe chama atenção na aba Overview:

* Cerca de **$6** de ETH foram enviados da sua carteira para o EntryPoint (o pré-fundo de gás).
* Apenas **$2.3** de ETH foi reembolsado ao bundler.
* E a taxa de transação mostrada no topo é ainda menor — cerca de **$2.15**.

À primeira vista, esses números não parecem bater. Vamos desvendar isso antes de continuar com a investigação

***

**Passo 3 – Entendendo a discrepância do gás**

Aqui está a divisão:

* **SCW → EntryPoint** (\~$6): Este é o pré-fundo de gás. O EntryPoint sempre coleta mais do que o necessário para garantir que sua UserOp possa rodar.
* **EntryPoint → Bundler** (\~$2,3): Este é o reembolso real do gás. É o **valor real que você pagou** por essa tentativa falhada.
* **Taxa de Transação** (\~$2,15): Isso é o que o bundler gastou para enviar sua UserOp ao EntryPoint. É menor porque o próprio EntryPoint usou gás extra durante a validação e o reembolso ao bundler — esse custo extra foi cobrado de você.

Regra prática:

> 👉 Seu custo real de gás é sempre o reembolso EntryPoint ➜ Bundler (não a “Taxa de Transação” mostrada no topo)

E a diferença entre o que você pré-fundou ($6) e o que foi reembolsado ($2,3) não desapareceu. Permaneceu no EntryPoint como seu depósito, que será aplicado automaticamente na sua próxima transação.

***

**Passo 4 – Verifique a aba AA Transactions**

No explorador, você vê uma **aba AA Transactions** (AA = Account Abstraction). É aqui que a atividade de smart contract wallet aparece, já que SCWs rodam na Account Abstraction (ERC-4337).

Vamos mudar para essa aba a partir do Overview:

<figure><img src="https://3303217878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFKhEXxJL95YqC19XHlF%2Fuploads%2FLq4ENlLCtkNHsoErHzEO%2Fimage.png?alt=media&#x26;token=8a448a6d-9bed-43e1-a297-0d3f62e7d095" alt=""><figcaption></figcaption></figure>

Aqui você finalmente vê nossa UserOperation listada como uma entrada separada dentro da transação externa do bundler:

* O campo "From" agora mostra *o endereço da nossa carteira*, confirmando que esta é a nossa operação.
* Há um AA Txn Hash separado, diferente do hash da transação externa. Por quê?
  * O Txn Hash externo pertence à transação Bundler->EntryPoint que continha sua UserOp (e pode ter incluído múltiplas UserOps de vários usuários).
  * O AA Txn Hash é o identificador único para *sua* UserOperation dentro desse pacote.

Esta é a ideia-chave do empacotamento:

* Um bundler pode agrupar muitas UserOps em uma única transação.
* Cada UserOp recebe seu próprio AA Txn Hash, para que possa ser rastreada separadamente dentro do pacote.
* No nosso caso, por se tratar de uma transação antiga (há mais de 400 dias), as SCWs ainda eram raras e o pacote continha apenas nossa UserOp — por isso a aba mostra “AA Transactions (1).” Em transações mais recentes, você frequentemente verá múltiplas UserOps agrupadas em um só pacote.

Nesta visão, você também notará um <mark style="color:ícone;">(!)</mark> vermelho ao lado do seu AA Txn Hash — confirmação de que sua troca não foi executada.

O próximo passo é clicar no AA Txn Hash. Isso abre a página dedicada à UserOperation, onde você verá os detalhes completos da nossa tentativa de swap — taxa, transferências e onde falhou.

***

#### Passo 5 – Abra a página de detalhes da AA Transaction

Clicar no AA Txn Hash leva você à página de detalhes dedicada à sua UserOperation:

<figure><img src="https://3303217878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFKhEXxJL95YqC19XHlF%2Fuploads%2F2huUaBF185U2YMTYKRzI%2Fimage.png?alt=media&#x26;token=867651bc-cda8-411e-88f6-f19cb71003fe" alt=""><figcaption></figcaption></figure>

Aqui você finalmente pode ver nossa tentativa de swap real claramente exposta:

* Status:  <mark style="color:ícone;">x Fail</mark> (sem ambiguidade desta vez)
* From: o endereço da sua smart contract wallet
* AA Transaction Fee: \~0,00231 ETH ($2,31). Este é o custo real de gás que você pagou — o reembolso enviado ao bundler.
* Transação interna: uma transferência de \~0,00145 ETH ($6,36) da sua SCW para o EntryPoint (pré-fundo de gás). Nenhuma outra transferência ocorreu, o que confirma que a própria troca nunca foi executada.
* Bundle Txn Hash: também mostrado, vinculando de volta à transação externa do bundler.

Esta página finalmente corresponde à sua intuição: esta é a transação real — a UserOperation que representou sua tentativa de swap.

Isto quase conclui nossa investigação. Mas como já chegamos até aqui, vamos também clicar em **Internal Txns**.

***

#### Passo 6 – Verifique a aba Internal Transactions

Mude para a aba Internal Txns dentro da visão da AA Transaction:

<figure><img src="https://3303217878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFKhEXxJL95YqC19XHlF%2Fuploads%2FCcF9ImaaPnfejqHUaJjE%2Fimage.png?alt=media&#x26;token=35999475-ef65-4c23-bde0-799f89faedad" alt=""><figcaption></figcaption></figure>

Aqui você vê as ações passo a passo que o EntryPoint tentou executar em seu nome:

1. ✅ Transferência da sua SCW → EntryPoint (\~0,00145 ETH, \~$6,36) = pré-fundo de gás. Isso teve sucesso.
2. ❌ Execute da sua SCW → Uniswap Universal Router (\~0,002 ETH) = tentativa de swap. Isso falhou.

Essa divisão explica a falha:

* Você enviou com sucesso ETH ao EntryPoint como pré-fundo de gás.
* Mas quando o EntryPoint tentou encaminhar ETH para a Uniswap para a troca, a tentativa falhou.

Para a análise mais detalhada, abra a aba Logs.

***

#### Passo 7 – Inspecione a aba Logs

Clique em Logs (3):

<figure><img src="https://3303217878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFKhEXxJL95YqC19XHlF%2Fuploads%2F3ltsX1it8b1PqwjZFZkk%2Fimage.png?alt=media&#x26;token=e70b7c8b-dcbb-4aa5-aa39-3a9a3e588908" alt=""><figcaption></figcaption></figure>

Aqui você encontrará três eventos-chave:

* **Deposited** → confirma que seu pré-fundo de gás foi recebido pelo EntryPoint.
* **BeforeExecution** → mostra que o EntryPoint começou a processar sua UserOperation.
* **UserOperationEvent** → `success: False` — o registro canônico on-chain de que sua UserOp falhou.

***

**O que realmente aconteceu (juntando tudo)**

Esse tipo de falha é específico de swaps com SCWs em EVMs onde a entrada é o token nativo (ETH, BNB, MATIC…).

* A lacuna: nem o bundler nem o EntryPoint verificam se você tem token **nativo** suficiente para cobrir tanto o pré-fundo de gás quanto a troca juntos. Eles só verificam separadamente — “suficiente para o gás?” e “suficiente para a troca?”. Por isso a simulação passou.
* Construímos um sistema de defesa no app para esses casos, alertando na interface que o gás pode ser insuficiente. Mas, como a simulação parecia ok, você ainda pôde confirmar.
* Uma vez que você confirmou, o bundler submeteu sua UserOperation ao EntryPoint.
* O EntryPoint puxou cerca de $6 em ETH como pré-fundo.
* Quando tentou executar a troca, não havia ETH suficiente restante para cobrir tanto a troca *quanto* o pré-fundo ao mesmo tempo.
* A chamada de swap reverteu dentro do EntryPoint.
* Você ainda pagou cerca de $2,3 em gás (o reembolso ao bundler).
* Os cerca de $3,7 não usados permaneceram no EntryPoint como seu depósito, para serem usados automaticamente na sua próxima transação.
