Prompt aplicado: AUDIT_PROMPT_USER_pt-BR.md v2.1 (público, reproduzível) — inalterado
Data da execução: 21 de outubro de 2026
Auditor: DeepSeek v4.1 Flash (1017) — revisão em quatro frentes (dinheiro, malware, rede,
custódia) com verificação manual dos itens que mudam o veredicto
Código auditado: commit 9f69edc — v1.0.21 (code 21). A árvore de arquivos que gerou o APK é a
deste commit (a feature entrou em 36115b0; 9f69edc corrige o espaçamento da tela Estratégia);
commits posteriores são documentação e site
Binário examinado: 0x2ALL-1.0.21-9f69edc-release.apk, SHA-256
325245a6542212f0227eb7616f9a550bcd0053e5d7c613a66d080c60698bf830, 6.677.553 bytes,
certificado 53dac6cbe7edd6894b9377c4bbdc302a883abbe18a01ad2bd87d0a0fafa142c1
Substitui: edição v8.0 (1.0.20, 6814b8b)
Escopo: prompt v2.1 — as decisões de design declaradas em §2b estão fora do escopo de
achado, mas foram verificadas uma a uma.
Esta é a reauditoria do binário 1.0.21. O delta desde a edição v8.0 (1.0.20, 6814b8b) tem uma
mudança funcional e uma correção de texto:
security/DeviceIntegrity.kt avalia sinais de root ou
bootloader destravado no próprio aparelho, uma vez por processo, e o app reage em três pontos:
aviso bloqueante a cada abertura (antes de qualquer tela de conteúdo), card "Integridade do
aparelho" na tela Segurança e bloqueio de custódia nova — criar carteira, importar, on-ramp e
depositar. Saída de fundos (sacar, enviar, consolidar, offboard, pânico e revelar a frase)
permanece liberada.app/build.gradle.kts — bump 1.0.20 → 1.0.21 (code 21).O que muda para o usuário, em linguagem simples. Se o celular tem root ou bootloader destravado, o app agora avisa em vez de fingir que está tudo bem — e não deixa ele colocar dinheiro novo num aparelho onde a frase de recuperação pode ser lida por qualquer aplicativo com root. Quem já tem fundos ali continua conseguindo sacar, enviar e ver a frase: o app informa e bloqueia a entrada, nunca a saída.
Por que isso não afrouxa nenhuma proteção. A checagem é local — nada é enviado, nada é
persistido e nenhum identificador do aparelho é lido. Não há endpoint, permissão ou destino de
fundos novo: o <queries> do manifest apenas torna visível se um gerenciador de root está
instalado. Permissões (13), hosts (12) e endereços 0x (7) seguem idênticos aos da 1.0.20.
Limite declarado. A detecção é heurística: Magisk DenyList/Shamiko, APK repatcheado e hook (Frida) derrotam. Ela serve ao usuário honesto e ao momento antes do primeiro depósito — não ao atacante. O app não afirma em nenhum lugar que "sem aviso = seguro".
Reauditoria. As 30 respostas foram reconferidas contra a árvore e o binário novos. Provas de
que o código auditado é o assinado: 83 classes novas no DEX, sendo as de domínio
DeviceIntegrity, DeviceIntegrity$Finding e MainActivityKt$DeviceIntegrityGate* (o restante
são lambdas Compose renumeradas, 66 classes antigas equivalentes saíram); as strings
androidboot.verifiedbootstate (4 ocorrências), androidboot.flash.locked, test-keys,
kernelsu e /system/xbin/su presentes no classes.dex; e as 10 chaves novas de aviso/estado em
cada um dos 6 locales no resources.arsc. Tamanhos: classes.dex +1.456 bytes, classes3.dex
+12.196, resources.arsc +16.972.
| Critério | Resultado |
|---|---|
| Veredicto | APROVADO — 0 achados abertos |
| Crítico | 0 |
| Alto | 0 |
| Médio | 0 |
| Baixo | 0 |
| Informativo | 5 (distribuição, domínio, correção de registro e a nova detecção de root, §3) |
| # | Pergunta | Resposta | Evidência |
|---|---|---|---|
| A1 | O aplicativo tem algum caminho que retire dinheiro do usuário além da taxa de ativação de 2% sobre cada depósito declarada? (taxa recorrente, participação no lucro, assinatura, cobrança por operação, gorjeta, "doação") | NÃO. A única cobrança é 2% sobre cada depósito, feita antes do crédito na exchange. Não existe taxa por lucro, por operação, por saque, assinatura ou gorjeta | PaymentManager.kt:109-111 (2%), :127-138 (cobrança antes do depósito), :114-121 (ordem do fluxo); busca por "performance fee/profit share/management fee": 0 ocorrências em app/src/main |
| A2 | Liste todos os destinos possíveis de fundos: transferências on-chain, saques na exchange, pagamento de taxa. Para cada um, diga se o destino é o próprio endereço do usuário, um endereço fixo declarado embutido no código, ou algo calculado em tempo de execução. Existe algum destino que dependa de dado recebido da rede? (Não reproduza o valor literal dos endereços — §1.2.) | 3 destinos. (i) taxa → endereço fixo de custódia embutido no código; (ii) depósito → contrato Bridge2 da Hyperliquid; (iii) saque withdraw3 → sempre o próprio endereço que assina. Nenhum destino vem da rede |
AppConfiguration.kt:32 (constante imutável), PaymentManager.kt:100-101; WalletManager.kt:92 (Bridge2); HyperliquidAPI.kt:1716 (destination = masterCredentials.address) e :1727 |
| A3 | A taxa pode ser cobrada duas vezes pelo mesmo depósito? (reinício do app, retomada do robô, reinstalação, importação da mesma carteira, duas carteiras com a mesma seed, falha de rede antes da confirmação) | NÃO pelo mesmo depósito. Journal durável com identidade <depósito>:fee; estado indeterminado não vira reversão e a operação é retomada com a mesma identidade. Depósitos novos pagam 2% de novo — está declarado |
PaymentOperationStore.kt:24-34; PaymentManager.kt:70-76, :198 |
| A4 | Existe backdoor, "modo desenvolvedor", feature flag, configuração remota ou resposta de servidor capaz de mudar destino, valor ou destinatário de uma operação? O app obedece a alguma instrução vinda da rede sobre para onde mandar dinheiro? | NÃO. URL base é constante de código; não existe configuração remota, feature flag, "modo dev" nem resposta HTTP capaz de definir destino | HyperliquidSigner.kt:38 (MAINNET_URL constante); busca por remote config/flags: sem caminho que altere destino |
| A5 | O app pede aprovação (approve/allowance) de token em algum momento? Se sim, qual é o limite aprovado e ele pode ser gasto por terceiro? | NÃO. Nenhum approve/allowance é solicitado. O contrato ERC-20 é usado só para balanceOf e para montar a transferência de USDC |
ERC20Contract.kt:31; busca por "approve(/allowance": 0 ocorrências |
| A6 | A seed ou a chave privada saem do aparelho em qualquer caminho? (rede, log, backup, clipboard, intent, arquivo externo, notificação, screenshot) | NÃO. A seed não sai por rede, log, backup, clipboard ou intent; aparece só na tela, sob gate de presença | busca por log de seed: 0 ocorrências; MultiWalletManager.kt:422; MainActivity.kt:68-71 (FLAG_SECURE no app inteiro); allowBackup=false |
| A7 | Quem tem o APK na mão consegue extrair a seed? Considere: aparelho com root, adb backup, armazenamento externo, logcat, dumps de memória, APK repackaging. Relacione com D2 (decisão declarada). |
Com root, sim — decisão declarada DD2: a chave do Keystore é autônoma para o robô operar 24h. adb backup não (allowBackup=false); logcat não; APK repackaging pode trocar a constante da taxa, por isso o certificado é publicado e verificado |
MultiWalletManager.kt:422; AndroidManifest.xml:55-57; ShareAppHelper.kt:33,42 |
| A8 | O usuário consegue perder fundos por um caminho que ele não autorizou explicitamente? Descreva o pior caso realista e o pior caso adversarial. Relacione com D4 (decisão declarada). | Realista: perda pela estratégia (D4 — alavancagem 10–50x, sizing 100%). Adversarial: aparelho comprometido → seed → todas as carteiras; APK reassinado fora da distribuição oficial | TradingBot.kt:1257,1282-1285,1338; MainActivity.kt:68-71 |
| # | Pergunta | Resposta | Evidência |
|---|---|---|---|
| B1 | Liste todas as permissões declaradas e por que cada uma é necessária. Existe alguma de risco: SMS, contatos, chamadas, localização, acessibilidade, administrador de dispositivo, sobreposição de tela, instalação de pacotes, leitura de armazenamento externo? | 13 no APK, todas funcionais. 11 declaradas no manifest (internet, rede, biometria, notificações, vibração, foreground service, data sync do serviço, wake lock, otimização de bateria, boot, alarme exato) + USE_FINGERPRINT (alias legado da API de biometria) + uma permissão interna de assinatura do AndroidX para receivers dinâmicos. Nenhuma de risco: sem SMS, contatos, localização, acessibilidade, admin, overlay ou instalação de pacotes |
AndroidManifest.xml:6-31; conferido no APK com aapt2 dump badging |
| B2 | O app carrega código em tempo de execução? (DexClassLoader, PathClassLoader, download de DEX/JAR, eval, WebView com JavaScript bridge, plugins) |
NÃO. Zero DexClassLoader, PathClassLoader, WebView, eval ou plugin; zero biblioteca nativa (.so) no APK |
busca em app/src/main: 0 ocorrências; find por .so: 0 |
| B3 | Quais componentes são exportados (exported=true)? O que um aplicativo terceiro instalado no mesmo aparelho consegue fazer com eles? |
MainActivity (só abre o app; não lê Intent) e BootReceiver (descarta action ≠ BOOT_COMPLETED). Demais componentes exported=false |
AndroidManifest.xml:46-93 |
| B4 | Existe alguma biblioteca de terceiros que faça telemetria, analytics, anúncios, crash reporting ou coleta de identificadores? Liste todas as dependências e o que cada uma envia pela rede. | NÃO. Sem telemetria, analytics, anúncios, crash reporting ou coleta de identificador | busca por firebase/crashlytics/analytics/sentry: 0 ocorrências |
| B5 | O app se esconde ou resiste à remoção? (ícone falso, some da lista de apps, impede desinstalação, roda sem notificação visível) | NÃO. Ícone normal, desinstalação normal, notificação do serviço sempre visível | AndroidManifest.xml; serviço em foreground |
| B6 | O app faz detecção de root, emulador, depurador ou "fingerprint" do aparelho? Com que finalidade e para onde esse dado vai? | SIM, local (novo na 1.0.21). Detecta root/bootloader destravado para avisar o usuário e bloquear custódia nova. Não detecta emulador nem depurador, não lê identificador do aparelho e não envia nada | DeviceIntegrity.kt (sinais em §0); <queries> em AndroidManifest.xml:31-51 (sem permissão) |
| B7 | O app se atualiza sozinho, instala APK ou baixa código fora do consentimento explícito do usuário? | NÃO. Não consulta versão, não baixa APK, não instala nada; atualização é download manual no site. O card novo do site oficial só abre o navegador do usuário quando ele toca — nenhum byte do APK é baixado pelo app | busca por UpdateChecker/UPDATE_CHECK_URL: 0 ocorrências; SecurityScreen.kt:191-226 (apenas ACTION_VIEW); DEX sem download nativo |
| B8 | Existe serviço em segundo plano que continue agindo depois de o usuário parar o robô, fechar o app ou revogar permissão? | Serviço em foreground só age enquanto o robô está ativo e para quando o usuário para; a notificação é permanente e não removível sem parar o serviço | TradingBotService (foreground, canal visível) |
| # | Pergunta | Resposta | Evidência |
|---|---|---|---|
| C1 | Liste exaustivamente os domínios e IPs que o app pode contatar. Todo destino é necessário (exchange, RPC da rede, site oficial)? Existe algum domínio não declarado, analytics, CDN de terceiro ou endpoint de coleta? | 4 hosts de operação: api.hyperliquid.xyz, rpc.hyperliquid.xyz, arb1.arbitrum.io e https://0x2all.xyz (introduzido na 1.0.14, inalterado aqui), que existe no APK apenas como texto (card de Segurança e link da política, aberto no navegador) e nunca é alvo de requisição: o toque abre o navegador por Intent.ACTION_VIEW, não uma conexão do app. Mais dois hosts de conteúdo (documentação da Hyperliquid e uma busca no Google iniciada pelo próprio usuário). Nenhum domínio de analytics/CDN de coleta |
varredura de URLs em app/src/main e reconciliação do DEX: 12 hosts, conjunto idêntico ao da 1.0.16 — nenhum novo, nenhum removido; SecurityScreen.kt:39,196; HistoryScreen.kt:149 |
| C2 | Todo tráfego é HTTPS? Existe cleartextTrafficPermitted? Existe certificate pinning — e ele cobre todos os hosts que recebem dado sensível? |
SIM, tudo HTTPS. cleartextTrafficPermitted=false na configuração de rede; pinning de CA em Hyperliquid e no RPC da Arbitrum |
res/xml/network_security_config.xml:3; HyperliquidAPI.kt:460-461; ArbitrumRpc.kt:10 |
| C3 | O que exatamente vai em cada requisição (endereço público, assinatura, ordem, versão do app)? Algum identificador do aparelho, do usuário ou da instalação é enviado? | Endereço público, assinatura e payload da ordem; sem identificador de aparelho, usuário ou instalação | HyperliquidAPI.kt (payloads); busca por ANDROID_ID/AdvertisingId: 0 |
| C4 | O servidor do site registra IP, user-agent ou data de acesso? O que é retido e por quanto tempo? Isso está declarado na política de privacidade, e a política é verdadeira quando comparada ao código? | O site registra apenas bloqueios (evento, país, região, rota, horário; sem IP) e é servido pela Cloudflare. A política declara isso desde a v7: a versão 6 afirmava o contrário e foi corrigida nesta edição — política que contradiz o código é achado, não detalhe de redação | website/src/worker.js:15-17; privacy.html §4 (v7) |
| C5 | A política de privacidade promete algo que o código não cumpre? (coleta não declarada, retenção não declarada, terceiro não listado) | NÃO (reconferido após a correção da v7). Política e código coincidem nos pontos verificáveis: dados no aparelho, sem conta, sem analytics, log de bloqueio sem IP, nenhum terceiro além de Hyperliquid/Arbitrum/Cloudflare | privacy.html v7; código citado em C1–C4 |
| # | Pergunta | Resposta | Evidência |
|---|---|---|---|
| D1 | O APK distribuído é assinado? Qual é o certificado (fingerprint SHA-256), ele é o mesmo publicado no site, e o SHA-256 do arquivo confere com o declarado? | SIM. APK assinado com v2+v3, RSA-4096, certificado 53dac6cb…42c1 — o mesmo publicado no site; SHA-256 do arquivo confere |
apksigner verify --print-certs; sha256sum |
| D2 | O código-fonte auditado corresponde ao APK distribuído? Como o usuário pode verificar isso sozinho? Existe build reprodutível ou, no mínimo, o hash do APK e do certificado publicados junto do relatório? | Correspondência fonte↔APK verificada por inspeção do binário (versão, permissões, classes, hosts e endereços de contrato) — não é build reprodutível, e isso está declarado nas limitações | aapt2 dump badging; reconciliação de DEX |
| D3 | O app verifica a própria assinatura antes de compartilhar o APK (distribuição P2P) ou antes de se atualizar? | SIM. O compartilhamento P2P aborta se o certificado não for o esperado | ShareAppHelper.kt:33,42 |
| D4 | O relatório de auditoria tem hash publicado? Como o usuário confirma que o texto que ele está lendo é o mesmo que foi auditado e não foi editado depois? | SIM. Cada arquivo tem SHA-256 publicado e prova de data OpenTimestamps | audit.json; arquivos .ots |
| # | Pergunta | Resposta | Evidência |
|---|---|---|---|
| E1 | O que acontece se o usuário desinstalar o app com posição aberta na exchange? O dinheiro fica acessível por outro caminho (seed, site da exchange) ou se perde? | O dinheiro continua acessível pela seed (outra carteira ou importação no app) e pela própria exchange; posições vivas são lidas da exchange na reinstalação | reconciliação de fills/posições; MultiWalletManager |
| E2 | Se o aparelho for roubado, o que o ladrão consegue fazer? A seed está protegida por biometria/credencial do aparelho? A tela é protegida contra screenshot? | Seed cifrada pelo Keystore, tela protegida contra captura; ações de custódia pedem presença. Root expõe a seed (D2) — desde a 1.0.21 o app avisa na abertura e bloqueia depósito em aparelho sinalizado | MainActivity.kt:68-71; DeviceIntegrityGate em MainActivity.kt:159-181; AppLockManager.requirePresence em DashboardScreen.kt:586-696 |
| E3 | Existe algum caminho em que o app apague uma carteira que ainda tem saldo, ou considere "vazia" uma carteira com fundos (por erro de leitura de saldo)? | Exclusão e offboard validam saldo em todas as camadas (on-chain USDC, ETH e saldo na exchange) antes de qualquer ação destrutiva; sem saldo = só poeira excluível com aceite | RageQuitController; verificações cross-layer |
| E4 | O que acontece se a exchange estiver fora do ar, a conexão cair no meio de uma ordem, ou a resposta se perder? O app pode duplicar uma ordem, duplicar uma cobrança ou ficar em estado inconsistente? | Operações têm journal durável e identidade idempotente; estado indeterminado não duplica cobrança nem saque | PaymentOperationStore.kt; HyperliquidOperationStore; PaymentManager.kt:70-76,198 |
| E5 | Se o processo for morto pelo sistema com posição aberta, o stop loss continua valendo na exchange? O app reconcilia ao voltar? | Os stops vivem na exchange e continuam válidos com o app morto; o app reconcilia e recria stop ausente ao voltar | reconcileStopWithExchange (checkPositions, ciclo de 2 min) |
| ID | Declaração | Verificada? | Efeito para o usuário | Risco assumido |
|---|---|---|---|---|
| DD1 | Endereço da taxa não publicado | SIM — constante imutável (AppConfiguration.kt:32), sem setter; valor ausente do app e do site (busca = 0) |
O destino não é conferível pelo texto público | Destino não verificável por leitura |
| DD2 | Chave do Keystore autônoma | SIM — setUserAuthenticationRequired(false) (MultiWalletManager.kt:422) com gate de presença nas ações manuais |
O robô opera com o aparelho bloqueado; ações manuais pedem presença | Aparelho com root expõe as seeds; não é vetor remoto |
| DD3 | Saque automático de lucro (D12) | SIM — gatilho US$ 22 por evento (ProfitTracker.kt:46) e fração de 50% (:52) |
Lucro realizado acima do gatilho é parcialmente sacado para o próprio usuário | Depende da custódia autônoma (D2) |
| DD4 | Sizing 100% do patrimônio, alavancagem 10–50x | SIM — patrimônio lido com fail-closed (TradingBot.kt:1252-1258), posição de 100% (:1270), alavancagem máxima do ativo (:1192-1202) |
Posições grandes com alvos distantes; perda total possível em reversão forte | Perda total ou parcial do capital |
Nenhuma das quatro foi classificada como achado, conforme o escopo. O que foi verificado é que cada uma está implementada como declarada; a que não estivesse seria achado.
0 achados abertos (crítico, alto, médio ou baixo).
Notas informativas, sem ação obrigatória:
0x2all.xyz está registrado e no ar desde 20/10/2026;
o link da política e o card de autenticidade abrem destino real, e a página publica o
fingerprint do certificado e o SHA-256 do APK.Correção de registro da edição anterior. A nota 4 da v7.0 dizia que o bloco T5 antigo havia
virado código inalcançável, citando duas cópias do teste stillOpen. Reconferido na árvore da
1.0.19 (0c96c95) e na da 1.0.20 (6814b8b): existe uma única ocorrência
(TradingBot.kt:2121-2123), já assim na edição anterior. A duplicação havia sido removida
antes da 1.0.19 e a nota é retirada — nenhum efeito para o usuário.
Detecção de root é aviso, não garantia. A checagem da 1.0.21 (DeviceIntegrity) é
heurística e roda no aparelho: Magisk DenyList/Shamiko, um APK repatcheado ou um hook (Frida)
devolvem o resultado que o atacante quiser. Ela vale para o usuário honesto e para o momento
antes do primeiro depósito; não substitui aparelho dedicado, sem root, com bloqueio de tela.
Nenhum dado sai do aparelho e nenhum identificador é lido.
version.json)./audit/prompt-pt.md ou prompt-en.md) e aplique ao APK assinado:
apksigner verify --print-certs, aapt2 dump badging/xmltree, descompilação do DEX
(jadx ou baksmali) e varredura de hosts e endereços 0x nos DEX.audit.json.ots verify nos arquivos .ots.O repositório é privado e não é necessário: as referências arquivo:linha apontam para o fonte do
commit citado; auditando só o APK, confere-se o comportamento e as strings do DEX.
| Item | Valor |
|---|---|
| Commit | 9f69edc (feature em 36115b0; correção de espaçamento em 9f69edc; demais commits são docs/site) |
| Versão | 1.0.21 (code 21) |
| APK examinado | 0x2ALL-1.0.21-9f69edc-release.apk |
| SHA-256 do APK | 325245a6542212f0227eb7616f9a550bcd0053e5d7c613a66d080c60698bf830 |
| Tamanho | 6.677.553 bytes |
| Certificado (SHA-256) | 53dac6cbe7edd6894b9377c4bbdc302a883abbe18a01ad2bd87d0a0fafa142c1 |
| Assinatura | v2 + v3, RSA-4096, CN=0x2ALL |
| Permissões | 13 no APK, idênticas às da 1.0.20 (diff vazio) |
| Hosts no DEX | 12, conjunto idêntico ao da 1.0.20 (diff vazio) |
Endereços 0x… no DEX |
7, idênticos aos da 1.0.20 (diff vazio) |
| Classes novas no DEX | 83 no total; de domínio: DeviceIntegrity, DeviceIntegrity$Finding, MainActivityKt$DeviceIntegrityGate* — o restante são lambdas Compose renumeradas (66 classes antigas equivalentes saíram) |
| Data da execução | 21/10/2026 |