Vault Smart Contract Examples Home > Developers > Vault Smart Contract Examples Production-ready Solidity examples for Noderr Vault smart contracts with comprehensive implementation patterns.

Vault Deposit Implementation solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC4626/ERC4626.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract NoderrVault is ERC4626, ReentrancyGuard { IERC20 public asset; address public manager; uint256 public totalDeposits; uint256 public totalWithdrawals; event Deposit(address indexed user, uint256 amount, uint256 shares); event Withdrawal(address indexed user, uint256 shares, uint256 amount); constructor( IERC20 _asset, string memory _name, string memory _symbol ) ERC4626(_asset) ERC20(_name, _symbol) { asset = _asset; manager = msg.sender; } function deposit(uint256 assets, address receiver) public override nonReentrant returns (uint256) { require(assets > 0, "Deposit amount must be greater than 0"); require(receiver!= address(0), "Invalid receiver address"); // Transfer assets from user to vault require( asset.transferFrom(msg.sender, address(this), assets), "Transfer failed" ); // Calculate shares based on vault balance uint256 shares = previewDeposit(assets); require(shares > 0, "Deposit too small"); // Mint shares to receiver _mint(receiver, shares); totalDeposits += assets; emit Deposit(msg.sender, assets, shares); return shares; } function mint(uint256 shares, address receiver) public override nonReentrant returns (uint256) { uint256 assets = previewMint(shares); require(assets > 0, "Mint amount too small"); require( asset.transferFrom(msg.sender, address(this), assets), "Transfer failed" ); _mint(receiver, shares); totalDeposits += assets; emit Deposit(msg.sender, assets, shares); return assets; } function _deposit( address caller, address receiver, uint256 assets, uint256 shares ) internal override nonReentrant { require(assets > 0, "Assets must be greater than 0"); SafeERC20.safeTransferFrom( IERC20(asset()), caller, address(this), assets ); _mint(receiver, shares); emit Deposit(caller, assets, shares); } }

Vault Withdrawal Implementation solidity contract NoderrVault is ERC4626, ReentrancyGuard { function withdraw( uint256 assets, address receiver, address owner ) public override nonReentrant returns (uint256) { require(assets > 0, "Withdrawal amount must be greater than 0"); require(receiver!= address(0), "Invalid receiver address"); require(owner!= address(0), "Invalid owner address"); // Calculate shares to burn uint256 shares = previewWithdraw(assets); require(shares > 0, "Withdrawal too small"); // Check allowance if caller is not owner if (msg.sender!= owner) { uint256 allowed = allowance(owner, msg.sender); require(allowed >= shares, "Insufficient allowance"); _approve(owner, msg.sender, allowed - shares); } // Burn shares from owner _burn(owner, shares); // Transfer assets to receiver require( asset.transfer(receiver, assets), "Transfer failed" ); totalWithdrawals += assets; emit Withdrawal(owner, shares, assets); return shares; } function redeem( uint256 shares, address receiver, address owner ) public override nonReentrant returns (uint256) { require(shares > 0, "Shares must be greater than 0"); require(receiver!= address(0), "Invalid receiver address"); require(owner!= address(0), "Invalid owner address"); // Check balance require(balanceOf(owner) >= shares, "Insufficient balance"); // Check allowance if caller is not owner if (msg.sender!= owner) { uint256 allowed = allowance(owner, msg.sender); require(allowed >= shares, "Insufficient allowance"); _approve(owner, msg.sender, allowed - shares); } // Calculate assets to withdraw uint256 assets = previewRedeem(shares); require(assets > 0, "Redemption too small"); // Burn shares _burn(owner, shares); // Transfer assets require( asset.transfer(receiver, assets), "Transfer failed" ); totalWithdrawals += assets; emit Withdrawal(owner, shares, assets); return assets; } function _withdraw( address caller, address receiver, address owner, uint256 assets, uint256 shares ) internal override nonReentrant { require(assets > 0, "Assets must be greater than 0"); if (caller!= owner) { _spendAllowance(owner, caller, shares); } _burn(owner, shares); SafeERC20.safeTransfer(IERC20(asset()), receiver, assets); emit Withdrawal(caller, assets, shares); } }

Vault Balance Calculation solidity contract NoderrVault is ERC4626 { function totalAssets() public view override returns (uint256) { return asset.balanceOf(address(this)); } function convertToShares(uint256 assets) public view override returns (uint256) { uint256 supply = totalSupply(); return supply == 0? assets : assets * supply / totalAssets(); } function convertToAssets(uint256 shares) public view override returns (uint256) { uint256 supply = totalSupply(); return supply == 0? shares : shares * totalAssets() / supply; } function previewDeposit(uint256 assets) public view override returns (uint256) { return convertToShares(assets); } function previewMint(uint256 shares) public view override returns (uint256) { uint256 supply = totalSupply(); return supply == 0? shares : shares * totalAssets() / supply + 1; } function previewWithdraw(uint256 assets) public view override returns (uint256) { uint256 supply = totalSupply(); return supply == 0? assets : assets * supply / totalAssets() + 1; } function previewRedeem(uint256 shares) public view override returns (uint256) { return convertToAssets(shares); } function maxDeposit(address) public view override returns (uint256) { return type(uint256).max; } function maxMint(address) public view override returns (uint256) { return type(uint256).max; } function maxWithdraw(address owner) public view override returns (uint256) { return convertToAssets(balanceOf(owner)); } function maxRedeem(address owner) public view override returns (uint256) { return balanceOf(owner); } }

Vault Fee Management solidity contract NoderrVault is ERC4626 { uint256 public managementFee; // in basis points (100 = 1%) uint256 public performanceFee; // in basis points address public feeRecipient; uint256 public lastFeeCollection; event FeeCollected(uint256 managementFee, uint256 performanceFee); event FeeUpdated(uint256 newManagementFee, uint256 newPerformanceFee); constructor( uint256 _managementFee, uint256 _performanceFee, address _feeRecipient ) { require(_managementFee <= 1000, "Management fee too high"); // max 10% require(_performanceFee <= 5000, "Performance fee too high"); // max 50% require(_feeRecipient!= address(0), "Invalid fee recipient"); managementFee = _managementFee; performanceFee = _performanceFee; feeRecipient = _feeRecipient; lastFeeCollection = block.timestamp; } function collectManagementFee() public { uint256 timePassed = block.timestamp - lastFeeCollection; uint256 yearlyFee = (totalAssets() * managementFee) / 10000; uint256 fee = (yearlyFee * timePassed) / 365 days; if (fee > 0) { uint256 shares = convertToShares(fee); _mint(feeRecipient, shares); lastFeeCollection = block.timestamp; emit FeeCollected(fee, 0); } } function collectPerformanceFee(uint256 profit) public { require(msg.sender == manager, " manager can collect fees"); uint256 fee = (profit * performanceFee) / 10000; if (fee > 0) { uint256 shares = convertToShares(fee); _mint(feeRecipient, shares); emit FeeCollected(0, fee); } } function updateFees(uint256 _managementFee, uint256 _performanceFee) public onlyManager { require(_managementFee <= 1000, "Management fee too high"); require(_performanceFee <= 5000, "Performance fee too high"); managementFee = _managementFee; performanceFee = _performanceFee; emit FeeUpdated(_managementFee, _performanceFee); } }

Vault Access Control solidity contract NoderrVault is ERC4626, Ownable { mapping(address => bool) public whitelisted; mapping(address => uint256) public userDepositLimit; bool public paused; event UserWhitelisted(address indexed user); event UserRemovedFromWhitelist(address indexed user); event DepositLimitSet(address indexed user, uint256 limit); event VaultPaused(); event VaultUnpaused(); modifier onlyWhitelisted() { require(whitelisted[msg.sender], "User not whitelisted"); _; } modifier whenNotPaused() { require(!paused, "Vault is paused"); _; } function whitelistUser(address user) public onlyOwner { whitelisted[user] = true; emit UserWhitelisted(user); } function removeFromWhitelist(address user) public onlyOwner { whitelisted[user] = false; emit UserRemovedFromWhitelist(user); } function setDepositLimit(address user, uint256 limit) public onlyOwner { userDepositLimit[user] = limit; emit DepositLimitSet(user, limit); } function deposit(uint256 assets, address receiver) public override onlyWhitelisted whenNotPaused returns (uint256) { require( assets <= userDepositLimit[msg.sender], "Exceeds deposit limit" ); return super.deposit(assets, receiver); } function pauseVault() public onlyOwner { paused = true; emit VaultPaused(); } function unpauseVault() public onlyOwner { paused = false; emit VaultUnpaused(); } }

Vault Emergency Functions solidity contract NoderrVault is ERC4626 { function emergencyWithdraw(uint256 amount) public onlyOwner nonReentrant { require(amount <= asset.balanceOf(address(this)), "Insufficient balance"); require(asset.transfer(owner(), amount), "Transfer failed"); } function recoverToken(address token, uint256 amount) public onlyOwner nonReentrant { require(token!= address(asset), "Cannot recover vault asset"); require(IERC20(token).transfer(owner(), amount), "Transfer failed"); } function setManager(address newManager) public onlyOwner { require(newManager!= address(0), "Invalid manager address"); manager = newManager; } function getVaultStats() public view returns ( uint256 totalAssets_, uint256 totalShares, uint256 totalDeposits_, uint256 totalWithdrawals_ ) { return ( totalAssets(), totalSupply(), totalDeposits, totalWithdrawals ); } } --- See Also:Strategy Smart Contracts | Smart Contract Integration | REST API Documentation --- See Also: - Noderr White Paper v7.1 - Noderr Lite Paper v3.1 - Noderr Protocol Documentation

results matching ""

    No results matching ""