PROVIDER
createSignal()
Publica um novo sinal de trading com stake real. Define par, direção (LONG/SHORT), preço de entrada validado pelo oracle Chainlink (±2%), take-profit e stop-loss. Taxa de 3.5% debitada automaticamente para a treasury.
pair — ex: "BTC/USDT"
direction — LONG | SHORT
entryPrice — validado pelo oracle ±2%
takeProfit / stopLoss — alvos em USD
msg.value — stake em ETH / MATIC / AVAX
FOLLOWER
followSignal()
Qualquer usuário pode seguir um sinal aberto com stake real. O pool cresce a cada follower. Máximo de 500 followers por sinal. Taxa de 3.5% debitada automaticamente.
signalId — ID do sinal aberto
msg.value — stake (mín. 0.001 ETH/MATIC/AVAX)
ORACLE
resolveByOracle()
Resolve o sinal quando o preço Chainlink atinge TP ou SL. Qualquer endereço pode chamar. WIN: TP atingido → provider + followers vencem. LOSS: SL atingido → followers vencem, provider perde o stake.
signalId — ID do sinal a resolver
Chamável por qualquer endereço
ORACLE
checkUpkeep()
Chamada pelo Chainlink Automation a cada bloco. Varre os sinais abertos em lote e retorna true se algum atingiu TP, SL ou expirou. Habilita a execução automática sem custo para o usuário.
checkData — batchSize e offset da varredura
Retorna: bool + bytes com signalId
ORACLE
performUpkeep()
Executada automaticamente pelo Chainlink Automation quando checkUpkeep() retorna true. Resolve por TP/SL ou expira o sinal — 100% sem intervenção humana, sem gas para o usuário.
performData — bytes com signalId a executar
Chamada pelo Chainlink Automation
ORACLE
getCurrentPrice()
Consulta o preço atual de um par via Chainlink Price Feed. Normaliza decimais (6 ou 8) para 8 internamente. Reverte se o preço estiver stale (sem atualização há mais de 1 hora).
pair — ex: "BTC/USDT"
Retorna: uint256 preço com 8 decimais
REWARD
claimReward()
Vencedores resgatam sua parte proporcional do pool após resolução. O valor fica em pendingWithdrawal até ser sacado. Proteção anti-double-claim — não pode ser chamada duas vezes.
signalId — ID do sinal resolvido
Credita em pendingWithdrawal[msg.sender]
REWARD
claimExpired()
Se um sinal expirar (timeout 30 dias) sem resolução, provider e followers recuperam 100% do stake sem penalidade. Proteção para fundos nunca ficarem presos no contrato.
signalId — ID do sinal expirado
Credita em pendingWithdrawal[msg.sender]
REWARD
withdraw()
Saca o ETH/MATIC/AVAX acumulado em pendingWithdrawal. Padrão pull-payment — o usuário saca quando quiser, nunca automático. ReentrancyGuard ativo para segurança total.
Chamável por qualquer endereço
Transfere pendingWithdrawal[msg.sender]
ADMIN
setPriceFeed()
Registra o endereço do Chainlink Price Feed para um par de trading. Necessário antes de qualquer sinal para esse par. Apenas o owner pode configurar novos feeds.
pair — ex: "ETH/USDT"
feedAddress — endereço do Chainlink feed
Apenas owner
ADMIN
emergencyResolve()
Resolução manual com duplo timelock: proposta disponível após 3 dias do sinal + execução 1 dia após proposta. Último recurso se o oracle Chainlink falhar persistentemente.
signalId — ID do sinal
won — true = WIN, false = LOSS
Delay: 3 dias para propor + 1 dia para executar
ADMIN
cancelEmergencyResolve()
Cancela proposta de emergência pendente. Emite evento EmergencyResolutionCancelled on-chain — qualquer monitor de eventos verá o cancelamento. Nova proposta pode ser feita do zero.
signalId — ID da proposta a cancelar
Apenas owner
Emite: EmergencyResolutionCancelled
ADMIN
setAutomationRegistry()
Define o endereço do registry do Chainlink Automation autorizado a chamar performUpkeep(). Se address(0), qualquer endereço pode chamar (modo aberto). Recomendado configurar após registro do upkeep.
registry — endereço do Chainlink Automation registry
Apenas owner
Emite: AutomationRegistrySet
ADMIN
rescueDust()
Resgata wei residual acumulado por arredondamento de divisão inteira nos cálculos de claimReward(). Calculado como balance − totalPendingWithdrawals. Não toca fundos de usuários.
to — endereço de destino do dust
Apenas owner
Emite: DustRescued
ADMIN
pause() / unpause()
Circuit breaker de emergência. Quando pausado, createSignal() e followSignal() são bloqueadas. Sinais e stakes existentes ficam protegidos e inalterados. Owner pode retomar com unpause().
Apenas owner
Bloqueia: createSignal + followSignal
ADMIN
transferOwnership()
Inicia transferência de ownership usando Ownable2Step — o novo owner precisa aceitar explicitamente via acceptOwnership(). Protege contra envio acidental para endereço errado.
newOwner — endereço proposto
Novo owner deve chamar acceptOwnership()
TREASURY
withdraw() Treasury
A treasury acumula 3.5% de taxa de cada createSignal() e followSignal(). Saca via pull-payment a qualquer momento. Nunca bloqueia o protocolo — taxa segura separada dos stakes dos usuários.
Apenas treasury address
Saca treasuryBalance acumulado
LEITURA
getSignal()
Retorna todos os dados de um sinal: par, direção, preço de entrada, TP, SL, pool total, status (OPEN / WIN / LOSS / EXPIRED), provider, timestamps de criação e resolução.
signalId — ID do sinal
Retorna: Signal struct completa
LEITURA
getOpenSignals()
Retorna array com IDs de todos os sinais atualmente abertos. Usada pelo frontend para o feed e pelo Chainlink Automation para varrer quais sinais precisam de monitoramento.
Retorna: uint256[] lista de IDs abertos
LEITURA
pendingWithdrawal()
Consulta o saldo de ETH/MATIC/AVAX disponível para saque de um endereço. Após claimReward(), o valor fica em pendingWithdrawal até o usuário chamar withdraw() explicitamente — padrão pull-payment.
address — carteira a consultar
Retorna: uint256 em wei