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;
}
}
Submitted on: 2025-09-28 11:36:02
Comments
Log in to comment.
No comments yet.