SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
08.12.2024

Lição: 267: Implementando Contratos de Staking

Contratos de staking são um componente essencial das finanças descentralizadas (DeFi) que permitem aos usuários bloquear seus tokens em um contrato inteligente para ganhar recompensas. Nesta aula, vamos explorar como criar um contrato básico de staking usando Solidity. Implementaremos funcionalidades para que os usuários possam realizar staking de seus tokens, retirar suas participações e reivindicar recompensas.

Pré-requisitos

Antes de começarmos, certifique-se de ter:

  • Conhecimento básico de Solidity.
  • Entendimento sobre Ethereum e contratos inteligentes.
  • Um ambiente de desenvolvimento configurado (como Remix, Hardhat ou Truffle).

Implementação do Contrato de Staking

Passo 1: Definir o Contrato e Variáveis

Vamos começar criando um novo contrato Solidity para staking. O contrato terá variáveis para rastrear as participações e recompensas dos usuários.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Staking {
    // Variáveis para armazenar a quantidade total apostada e recompensas
    mapping(address => uint256) public stakes;
    mapping(address => uint256) public rewards;
    uint256 public totalStaked;
    uint256 public rewardRate = 100; // ex: 100 tokens de recompensa por token apostado

    // Eventos para staking e unstaking
    event Staked(address indexed user, uint256 amount);
    event Unstaked(address indexed user, uint256 amount);
    event RewardPaid(address indexed user, uint256 reward);

    // ... (Funções serão adicionadas aqui)
}

Passo 2: Criar a Função de Staking

A seguir, implementaremos a função stake, permitindo que os usuários depositem seus tokens no contrato.

    // Supõe que um token ERC20 padrão está sendo utilizado
    IERC20 public stakingToken;

    constructor(IERC20 _stakingToken) {
        stakingToken = _stakingToken;
    }

    function stake(uint256 amount) external {
        require(amount > 0, "A quantidade deve ser maior que 0");

        // Transferir tokens do usuário para o contrato
        stakingToken.transferFrom(msg.sender, address(this), amount);

        // Atualizar as participações e a quantidade total apostada
        stakes[msg.sender] += amount;
        totalStaked += amount;

        emit Staked(msg.sender, amount);
    }

Passo 3: Criar a Função de Unstaking

Também precisamos permitir que os usuários retirem seus tokens apostados.

    function unstake(uint256 amount) external {
        require(amount > 0, "A quantidade deve ser maior que 0");
        require(stakes[msg.sender] >= amount, "Quantidade apostada insuficiente");

        // Atualizar as participações e a quantidade total apostada
        stakes[msg.sender] -= amount;
        totalStaked -= amount;

        // Transferir tokens de volta para o usuário
        stakingToken.transfer(msg.sender, amount);

        emit Unstaked(msg.sender, amount);
    }

Passo 4: Criar a Lógica de Cálculo de Recompensas

Agora, implementaremos uma função para calcular e reivindicar recompensas. As recompensas serão distribuídas com base na quantidade apostada e na rewardRate.

    function calculateReward(address user) internal view returns (uint256) {
        return stakes[user] * rewardRate; // Simples exemplo de cálculo
    }

    function claimReward() external {
        uint256 reward = calculateReward(msg.sender);
        require(reward > 0, "Sem recompensas disponíveis");

        // Atualizar o saldo de recompensas
        rewards[msg.sender] += reward;

        emit RewardPaid(msg.sender, reward);
    }

Passo 5: Completar o Contrato

Finalmente, vamos adicionar uma funcionalidade para verificar recompensas e modificar o construtor para lidar com configurações iniciais.

    function getReward() external {
        uint256 reward = rewards[msg.sender];
        require(reward > 0, "Sem recompensas para reivindicar");

        // Reiniciar o saldo de recompensas do usuário
        rewards[msg.sender] = 0;

        // Transferir recompensas para o usuário (essa funcionalidade assume um contrato de tokens de recompensa separado)
        stakingToken.transfer(msg.sender, reward); // Placeholder, substituir por um token de recompensa

        emit RewardPaid(msg.sender, reward);
    }
}

Conclusão

Nesta aula, criamos um contrato básico de staking que permite aos usuários apostarem tokens, retirarem-nos e reivindicarem recompensas. Essa estrutura básica pode ser estendida para incluir mais funcionalidades, como:

  • Diferentes mecanismos de recompensa.
  • Penalidades para retiradas antecipadas.
  • Funcionalidades de retirada de emergência.

Contratos de staking desempenham um papel crucial em incentivar usuários em vários protocolos DeFi, tornando esse conhecimento inestimável à medida que você avança no desenvolvimento de blockchain. Boa codificação!

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!