From ec87f124751e5047712469e5b3eb7b7e7684037b Mon Sep 17 00:00:00 2001 From: Panos Matsinopoulos Date: Fri, 7 Nov 2025 18:32:26 +0200 Subject: [PATCH 1/5] Pin solidity version 0.8.25 like the one in the package.json --- .tool-versions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tool-versions b/.tool-versions index fb44f4ff..3b72ac62 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ nodejs 20.12.2 yarn 1.22.19 -solidity 0.8.24 +solidity 0.8.25 From abb214e99e82d8e71cee4d225ec29c9c3629b399 Mon Sep 17 00:00:00 2001 From: Panos Matsinopoulos Date: Fri, 7 Nov 2025 18:41:08 +0200 Subject: [PATCH 2/5] Make pragma solidity version compatible with the Hardhat config solidity version --- contracts/talent/TalentVaultV3.sol | 32 ++++++++++++------------------ 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/contracts/talent/TalentVaultV3.sol b/contracts/talent/TalentVaultV3.sol index 8b5133c4..8196c134 100644 --- a/contracts/talent/TalentVaultV3.sol +++ b/contracts/talent/TalentVaultV3.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.24; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; @@ -89,14 +89,12 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { /// @notice Create a new Talent Vault V3 contract /// @param _token The token that will be deposited into the contract /// @param _yieldSource The wallet paying for the yield - constructor( - IERC20 _token, - address _yieldSource - ) ERC4626(_token) ERC20("TalentVaultV3", "sTALENT3") Ownable(msg.sender) { - if ( - address(_token) == address(0) || - address(_yieldSource) == address(0) - ) { + constructor(IERC20 _token, address _yieldSource) + ERC4626(_token) + ERC20("TalentVaultV3", "sTALENT3") + Ownable(msg.sender) + { + if (address(_token) == address(0) || address(_yieldSource) == address(0)) { revert InvalidAddress(); } @@ -294,9 +292,7 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { uint256 timeElapsed; if (block.timestamp > endTime) { - timeElapsed = endTime > balanceMeta.lastRewardCalculation - ? endTime - balanceMeta.lastRewardCalculation - : 0; + timeElapsed = endTime > balanceMeta.lastRewardCalculation ? endTime - balanceMeta.lastRewardCalculation : 0; } else { timeElapsed = block.timestamp - balanceMeta.lastRewardCalculation; } @@ -339,13 +335,11 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { /// @param owner The address of the owner /// @param assets The amount of tokens to withdraw /// @param shares The amount of shares to withdraw - function _withdraw( - address caller, - address receiver, - address owner, - uint256 assets, - uint256 shares - ) internal virtual override { + function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares) + internal + virtual + override + { UserBalanceMeta storage ownerUserBalanceMeta = userBalanceMeta[owner]; if (ownerUserBalanceMeta.lastDepositAt + lockPeriod > block.timestamp) { From fe7a49b97b65821b8d1698c6c988e603294a9b27 Mon Sep 17 00:00:00 2001 From: Panos Matsinopoulos Date: Fri, 7 Nov 2025 19:18:44 +0200 Subject: [PATCH 3/5] Minor nat-spec improvements --- contracts/talent/TalentVaultV3.sol | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/contracts/talent/TalentVaultV3.sol b/contracts/talent/TalentVaultV3.sol index 8196c134..459acb57 100644 --- a/contracts/talent/TalentVaultV3.sol +++ b/contracts/talent/TalentVaultV3.sol @@ -193,6 +193,7 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { /// @notice Get the maximum deposit amount for an address /// @param receiver The address to get the maximum deposit amount for + /// @return The maximum deposit amount for the address function maxDeposit(address receiver) public view virtual override returns (uint256) { if (maxDepositLimitFlags[receiver]) { return maxDeposits[receiver]; @@ -203,6 +204,7 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { /// @notice Get the maximum deposit amount for an address /// @param receiver The address to get the maximum deposit amount for + /// @return The maximum deposit amount for the address function maxMint(address receiver) public view virtual override returns (uint256) { return maxDeposit(receiver); } @@ -210,6 +212,7 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { /// @notice Deposit tokens into the contract /// @param assets The amount of tokens to deposit /// @param receiver The address to deposit the tokens for + /// @return The number of tokens deposited function deposit(uint256 assets, address receiver) public virtual override returns (uint256) { if (assets <= 0) { revert InvalidDepositAmount(); @@ -235,6 +238,7 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { /// @notice Deposit tokens into the contract /// @param shares The amount of shares to deposit /// @param receiver The address to deposit the shares for + /// @return The number of tokens deposited function mint(uint256 shares, address receiver) public virtual override returns (uint256) { return deposit(shares, receiver); } @@ -265,13 +269,14 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { } /// @notice This reverts because TalentVault is non-transferable - /// @dev reverts with TalentVaultNonTansferable + /// @dev reverts with TalentVaultNonTransferable function transferFrom(address, address, uint256) public virtual override(ERC20, IERC20) returns (bool) { revert TalentVaultNonTransferable(); } /// @notice Calculate the accrued rewards for an address /// @param user The address to calculate the accrued rewards for + /// @return The amount of accrued rewards for the user function calculateRewards(address user) public view returns (uint256) { UserBalanceMeta storage balanceMeta = userBalanceMeta[user]; From 4f23a4d78d860c0a1348e43fc90986406cf9c1eb Mon Sep 17 00:00:00 2001 From: Panos Matsinopoulos Date: Fri, 7 Nov 2025 19:19:26 +0200 Subject: [PATCH 4/5] Gas spent improvement. String comparison since data types are unsigned integers --- contracts/talent/TalentVaultV3.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/talent/TalentVaultV3.sol b/contracts/talent/TalentVaultV3.sol index 459acb57..5ad6b12d 100644 --- a/contracts/talent/TalentVaultV3.sol +++ b/contracts/talent/TalentVaultV3.sol @@ -214,7 +214,7 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { /// @param receiver The address to deposit the tokens for /// @return The number of tokens deposited function deposit(uint256 assets, address receiver) public virtual override returns (uint256) { - if (assets <= 0) { + if (assets == 0) { revert InvalidDepositAmount(); } @@ -247,7 +247,7 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { /// the deposit meta data including minting any rewards /// @param account The address of the user to refresh function refreshForAddress(address account) public { - if (balanceOf(account) <= 0) { + if (balanceOf(account) == 0) { UserBalanceMeta storage balanceMeta = userBalanceMeta[account]; balanceMeta.lastRewardCalculation = block.timestamp; return; From ab03549c2a8d57455b5a2a5b0aa548a57b9610fa Mon Sep 17 00:00:00 2001 From: Panos Matsinopoulos Date: Fri, 7 Nov 2025 19:20:03 +0200 Subject: [PATCH 5/5] Check for yieldRewardsFlag before accessing storage. --- contracts/talent/TalentVaultV3.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/talent/TalentVaultV3.sol b/contracts/talent/TalentVaultV3.sol index 5ad6b12d..79094826 100644 --- a/contracts/talent/TalentVaultV3.sol +++ b/contracts/talent/TalentVaultV3.sol @@ -278,12 +278,12 @@ contract TalentVaultV3 is ERC4626, Ownable, ReentrancyGuard { /// @param user The address to calculate the accrued rewards for /// @return The amount of accrued rewards for the user function calculateRewards(address user) public view returns (uint256) { - UserBalanceMeta storage balanceMeta = userBalanceMeta[user]; - if (!yieldRewardsFlag) { return 0; } + UserBalanceMeta storage balanceMeta = userBalanceMeta[user]; + uint256 userBalance = balanceOf(user); uint256 endTime;