Vault

Description:

Smart contract deployed on Ethereum.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

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


interface IERC20Burnable {
    function balanceOf(address account) external view returns (uint256);
    function totalSupply() external view returns (uint256);
    function burnFrom(address account, uint256 amount) external;
    function allowance(address owner, address spender) external view returns (uint256);
}


contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor() {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), msg.sender);
    }

    modifier onlyOwner() {
        require(msg.sender == _owner, "Ownable: caller is not the owner");
        _;
    }

    function owner() external view returns (address) {
        return _owner;
    }

    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "Ownable: zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}


contract ReentrancyGuard {
    uint256 private _status = 1;

    modifier nonReentrant() {
        require(_status != 2, "ReentrancyGuard: reentrant call");
        _status = 2;
        _;
        _status = 1;
    }
}


contract Vault is ReentrancyGuard, Ownable {
    IERC20Burnable public immutable rewardToken; 

    mapping(address => uint256) public withdrawnEther;
    uint256 public totalWithdrawn;

    event Deposit(address indexed from, uint256 amount);
    event Withdraw(address indexed to, uint256 ethAmount, uint256 burnedTokens);

    constructor(address _rewardToken) {
        require(_rewardToken != address(0), "Invalid token address");
        rewardToken = IERC20Burnable(_rewardToken);
    }

   
    receive() external payable {
        emit Deposit(msg.sender, msg.value);
    }

    fallback() external payable {
        emit Deposit(msg.sender, msg.value);
    }

   
    function withdrawableETH(address user) public view returns (uint256) {
        uint256 userBalance = rewardToken.balanceOf(user);
        uint256 totalSupply = rewardToken.totalSupply();
        if (userBalance == 0 || totalSupply == 0) return 0;

        uint256 totalReceived = address(this).balance + totalWithdrawn;
        uint256 entitled = (totalReceived * userBalance) / totalSupply;

        if (entitled <= withdrawnEther[user]) return 0;
        return entitled - withdrawnEther[user];
    }

   
    function withdraw() external nonReentrant {
        uint256 amountETH = withdrawableETH(msg.sender);
        require(amountETH > 0, "No withdrawable ETH");

        uint256 burnAmount = amountETH * 100; // 1 ETH = 100 rETH

        uint256 allowance = rewardToken.allowance(msg.sender, address(this));
        require(allowance >= burnAmount, "Insufficient allowance");

        rewardToken.burnFrom(msg.sender, burnAmount);

        withdrawnEther[msg.sender] += amountETH;
        totalWithdrawn += amountETH;

        (bool success, ) = payable(msg.sender).call{value: amountETH}("");
        require(success, "ETH transfer failed");

        emit Withdraw(msg.sender, amountETH, burnAmount);
    }

    
    function getVaultBalance() external view returns (uint256) {
        return address(this).balance;
    }
}

Tags:
addr:0x40b5af46d2833be7ee22ff139ec3cae9b04d08dc|verified:true|block:23459658|tx:0x0b9f1c3762dcc91948fad76374a51960ffd474a534785d96176c4db1ff5e044c|first_check:1759052162

Submitted on: 2025-09-28 11:36:02

Comments

Log in to comment.

No comments yet.