Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

kipu-bank

Codigo Solidity de KipuBank - Contrato Inteligente para Bóveda Bancaria

// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/**
 * @title Contrato KipuBank
 * @notice Este es un contrato para una bóveda bancaria simple donde los usuarios depositan y retiran ETH con límites de seguridad.
 * @author Estudiante EthKipu
 * @custom:security No usar en producción. Solo para fines educativos.
 */

contract KipuBank {

    /*///////////////////////
                    Variables
    ///////////////////////*/
    /// @notice Límite global inmutable para el total de depósitos en el banco.
    uint256 immutable public i_bankCap;

    /// @notice Umbral inmutable para el monto máximo de retiro por transacción.
    uint256 immutable public i_umbralRetiro;
    
    /// @notice Mapping para almacenar el saldo de cada usuario en su bóveda personal.
    mapping(address => uint256) public s_saldos;

    /// @notice Balance total acumulado de todos los depósitos.
    uint256 public s_totalDepositado;
    
    /// @notice Contador del número total de depósitos realizados.
    uint256 public s_numeroDepositos;
    
    /// @notice Contador del número total de retiros realizados.
    uint256 public s_numeroRetiros;
    
    /*///////////////////////
                        Eventos
    ////////////////////////*/
    /// @notice Evento emitido cuando se realiza un depósito exitoso.
    event KipuBank_Deposito(address indexed usuario, uint256 monto);
    
    /// @notice Evento emitido cuando se realiza un retiro exitoso.
    event KipuBank_Retiro(address indexed usuario, uint256 monto);
    
    /*///////////////////////
                        Errores
    /////////////////////////*/
    /// @notice Error emitido cuando un depósito excede la capacidad global del banco.
    error KipuBank_DepositoExcedeCap(uint256 nuevoTotal, uint256 cap);
    
    /// @notice Error emitido cuando el saldo es insuficiente para un retiro.
    error KipuBank_SaldoInsuficiente(uint256 solicitado, uint256 disponible);
    
    /// @notice Error emitido cuando un retiro excede el umbral permitido.
    error KipuBank_RetiroExcedeUmbral(uint256 solicitado, uint256 umbral);
    
    /// @notice Error emitido cuando falla una transferencia de ETH.
    error KipuBank_TransferenciaFallida(bytes data);
    
    /*///////////////////////
                    Funciones
    /////////////////////////*/
    /**
     * @notice Constructor para inicializar el contrato.
     * @param _capacidadBanco El límite global de depósitos.
     * @param _umbralRetiro El umbral máximo por retiro.
     */
    constructor(uint256 _capacidadBanco, uint256 _umbralRetiro) {
        i_bankCap = _capacidadBanco;
        i_umbralRetiro = _umbralRetiro;
    }
    
    /// @notice Función para recibir ETH directamente (depósito automático).
    receive() external payable {
        _depositar(msg.sender, msg.value);
    }

    /// @notice Fallback: evita pérdida si se envían datos no esperados con ETH.
    fallback() external payable {
        if (msg.value > 0) {
            _depositar(msg.sender, msg.value);
        }
    }
    
    /**
     * @notice Función external payable para realizar un depósito en la bóveda personal.
     * @dev Sigue el patrón Checks-Effects-Interactions implícitamente a través de la función privada.
     * @dev Emite un evento al finalizar.
     */
    function depositar() external payable {
        _depositar(msg.sender, msg.value);
    }
    
    /**
     * @notice Función para retirar fondos de la bóveda personal.
     * @dev Solo permite retiros hasta el umbral y saldo disponible.
     * @dev Sigue Checks-Effects-Interactions para seguridad.
     * @param _monto El monto a retirar.
     */
    function retirar(uint256 _monto) external {
        // Checks
        if (_monto == 0) revert KipuBank_SaldoInsuficiente(0, 0); // Evita retiros cero, opcional pero buena práctica.
        if (_monto > s_saldos[msg.sender]) {
            revert KipuBank_SaldoInsuficiente(_monto, s_saldos[msg.sender]);
        }
        if (_monto > i_umbralRetiro) {
            revert KipuBank_RetiroExcedeUmbral(_monto, i_umbralRetiro);
        }
        
        // Effects
        s_saldos[msg.sender] -= _monto;
        s_totalDepositado -= _monto;
        s_numeroRetiros++;
        
        // Interactions
        (bool exito, bytes memory data) = payable(msg.sender).call{value: _monto}("");
        if (!exito) {
            revert KipuBank_TransferenciaFallida(data);
        }
        
        emit KipuBank_Retiro(msg.sender, _monto);
    }
    
    /**
     * @notice Función external view para consultar el saldo de un usuario.
     * @param _usuario La dirección del usuario.
     * @return El saldo actual en la bóveda.
     */
    function saldoDe(address _usuario) external view returns (uint256) {
        return s_saldos[_usuario];
    }
    
    /**
     * @notice Función private para procesar depósitos.
     * @dev Realiza validaciones y actualizaciones de estado.
     * @param _usuario El usuario que deposita.
     * @param _monto El monto del depósito.
     */
    function _depositar(address _usuario, uint256 _monto) private {
        // Checks
        if (_monto == 0) revert KipuBank_DepositoExcedeCap(0, i_bankCap); // Evita depósitos cero.
        uint256 nuevoTotal = s_totalDepositado + _monto;
        
        if (nuevoTotal > i_bankCap) {
            revert KipuBank_DepositoExcedeCap(nuevoTotal, i_bankCap);
        }
        
        // Effects
        s_saldos[_usuario] += _monto;
        s_totalDepositado = nuevoTotal;
        s_numeroDepositos++;
        
        // Sin interactions externas aquí, solo estado interno.
        
        emit KipuBank_Deposito(_usuario, _monto);
    }
}

Descripción del Contrato

KipuBank es un smart contract simple y seguro implementado en Solidity que permite a los usuarios depositar ETH en una bóveda personal y retirarlos con restricciones de seguridad. El contrato sigue mejores prácticas de desarrollo Web3, incluyendo el uso de errores personalizados, el patrón Checks-Effects-Interactions (CEI), eventos para logging, y variables inmutables para límites fijos.

Características Principales

  • Depósitos: Los usuarios pueden depositar ETH vía depositar(), receive() o fallback(). Hay un límite global (i_bankCap) para el total depositado.
  • Retiros: Los usuarios retiran vía retirar(uint256 _monto), limitado por saldo personal y un umbral por transacción (i_umbralRetiro).
  • Registros: Mantiene contadores de depósitos (s_numeroDepositos) y retiros (s_numeroRetiros), y saldos por usuario (s_saldos).
  • Seguridad: Errores personalizados, CEI en retiros, manejo seguro de transferencias nativas.
  • Consultas: Función view saldoDe(address) para balances.

El contrato es ownerless (sin propietario), enfocado en usuarios individuales y soporta múltiples usuarios simultáneamente (cada wallet tiene su bóveda independiente).

Requisitos

Instrucciones de Despliegue con Remix en Sepolia

  1. Configura MetaMask para Sepolia:

    • Abre MetaMask y agrega la red Sepolia (RPC: https://rpc.sepolia.org, Chain ID: 11155111, Explorer: https://sepolia.etherscan.io).
    • Solicita ETH de prueba en un faucet (necesitas ~0.05 ETH para gas).
  2. Abre Remix y Carga el Código:

    • Ve a remix.ethereum.org.
    • Crea un nuevo archivo: En el panel izquierdo (File Explorer), clic en "Create new file" > Nómbralo KipuBank.sol.
    • Copia y pega el código del contrato KipuBank (ver /contracts/KipuBank.sol en tu repo).
  3. Compila el Contrato:

    • Ve a la pestaña Solidity Compiler (ícono de Solidity).
    • Selecciona compiler 0.8.26.
    • Clic en Compile KipuBank.sol. Verifica "Compilation successful".
  4. Despliega en Sepolia:

    • Ve a Deploy & Run Transactions (ícono de Ethereum).
    • En "Environment", selecciona Injected Provider - MetaMask (conecta tu wallet).
    • En "Contract", elige KipuBank.
    • En campos del constructor:
      • _capacidadBanco: 10000000000000000000 (10 ETH en wei).
      • _umbralRetiro: 1000000000000000000 (1 ETH en wei).
    • Clic en Deploy. Confirma en MetaMask (gas ~0.01 ETH).
    • Copia la dirección del contrato (e.g., 0x123...abc) de la sección "Deployed Contracts".
  5. Verifica en Etherscan (Opcional pero recomendado):

    • Ve a sepolia.etherscan.io.
    • Busca tu contract address.
    • Para verificar código: En Remix (Solidity Compiler > "Verification"), ingresa address, compiler, y el código fuente. O manualmente en Etherscan > "Verify and Publish".

Cómo Interactuar con el Contrato en Remix

Usa la sección "Deployed Contracts" en Remix para llamar funciones. Cambia accounts en MetaMask para simular múltiples usuarios.

1. Depositar ETH (Bóveda Personal)

  • Pon valor en Value (e.g., 0.1 para 0.1 ETH).
  • Selecciona depositar.
  • Clic en transact > Confirma en MetaMask.
  • Ver evento en logs: KipuBank_Deposito.

2. Consultar Saldo

  • Selecciona saldoDe.
  • Input: Tu address (e.g., 0x... de MetaMask).
  • Clic en call (no gasta gas).
  • Resultado: Saldo en wei (e.g., 100000000000000000 = 0.1 ETH).

3. Retirar Fondos

  • Deja Value en 0.
  • Selecciona retirar.
  • Input: Monto en wei (e.g., 50000000000000000 = 0.05 ETH).
  • Clic en transact > Confirma.
  • Ver evento: KipuBank_Retiro. Consulta saldo actualizado.

4. Pruebas Multi-Usuario

  • Crea otra account en MetaMask y envía ETH de prueba.
  • Cambia a la nueva account (dropdown en MetaMask).
  • Repite depósitos/retiros: Cada address tiene saldo independiente.
  • Prueba límite global: Deposita hasta exceder i_bankCap (revierte).

5. Errores de Seguridad (Pruebas)

  • Deposito 0 ETH: Revierte (KipuBank_DepositoExcedeCap).
  • Retiro > umbral: Revierte (KipuBank_RetiroExcedeUmbral).
  • Retiro > saldo: Revierte (KipuBank_SaldoInsuficiente).

Dirección del Contrato Desplegado

  • Red: Sepolia Testnet
  • Dirección: [Inserta aquí después del despliegue, e.g., 0x123...abc]
  • Block Explorer: [Enlace verificado, e.g., https://sepolia.etherscan.io/address/0x123...abc]
  • Transacciones de Ejemplo:
    • Despliegue: [Tx Hash de MetaMask]
    • Depósito: [Tx Hash]
    • Retiro: [Tx Hash]

Notas Adicionales

  • Conversión Wei/ETH: Usa eth-converter.com para wei a ETH.
  • Troubleshooting:
    • "Insufficient funds": Pide más ETH del faucet.
    • Transacción fallida: Verifica gas en MetaMask (baja si es alto).
    • Múltiples usuarios: Importa seeds de test en MetaMask.
  • Este contrato es educativo.

Portafolio

Este proyecto demuestra habilidades en Solidity: seguridad (CEI, errores custom), documentación (NatSpec), y despliegue en testnet con Remix/MetaMask. ¡Explora Web3!

Desplegado el: 12 de octubre de 2025

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors