diff --git a/nest/src/token/pUSD.sol b/nest/src/token/pUSD.sol
index 7b55b24..5535159 100644
--- a/nest/src/token/pUSD.sol
+++ b/nest/src/token/pUSD.sol
@@ -14,6 +14,8 @@ import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.so
 import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
 import { IERC20Metadata } from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
 
+import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
+
 import { ComponentToken } from "../ComponentToken.sol";
 import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
 
@@ -22,9 +24,17 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s
  * @author Eugene Y. Q. Shen, Alp Guneysel
  * @notice Unified Plume USD stablecoin
  */
-contract pUSD is Initializable, ERC20Upgradeable, AccessControlUpgradeable, UUPSUpgradeable, ComponentToken {
+contract pUSD is
+    Initializable,
+    ERC20Upgradeable,
+    AccessControlUpgradeable,
+    UUPSUpgradeable,
+    ComponentToken,
+    ReentrancyGuardUpgradeable
+{
 
     using SafeERC20 for IERC20;
+    
     // ========== STORAGE ==========
     /// @custom:storage-location erc7201:plume.storage.pUSD
 
@@ -68,7 +78,12 @@ contract pUSD is Initializable, ERC20Upgradeable, AccessControlUpgradeable, UUPS
     // Changed to _initialize to avoid double initialization
 
     function initialize(address owner, IERC20 asset_, address vault_) public initializer {
+        require(owner != address(0), "Zero address owner");
+        require(address(asset_) != address(0), "Zero address asset");
+        require(vault_ != address(0), "Zero address vault");
+
         super.initialize(owner, "Plume USD", "pUSD", asset_, false, false);
+        __ReentrancyGuard_init();
 
         pUSDStorage storage $ = _getpUSDStorage();
         $.vault = IVault(vault_);
@@ -79,7 +94,7 @@ contract pUSD is Initializable, ERC20Upgradeable, AccessControlUpgradeable, UUPS
     // ========== ADMIN FUNCTIONS ==========
     function setVault(
         address newVault
-    ) external onlyRole(VAULT_ADMIN_ROLE) {
+    ) external nonReentrant onlyRole(VAULT_ADMIN_ROLE) {
         pUSDStorage storage $ = _getpUSDStorage();
         address oldVault = address($.vault);
         $.vault = IVault(newVault);
@@ -92,22 +107,25 @@ contract pUSD is Initializable, ERC20Upgradeable, AccessControlUpgradeable, UUPS
     }
 
     // ========== COMPONENT TOKEN INTEGRATION ==========
-    function deposit(
+ function deposit(
         uint256 assets,
         address receiver,
-        address controller // Required by ComponentToken interface but not used in this implementation
-    ) public virtual override returns (uint256 shares) {
+        address controller
+    ) public virtual override nonReentrant returns (uint256 shares) {
         // Calculate shares to mint
         shares = previewDeposit(assets);
 
-        // Transfer assets from depositor
-        IERC20(asset()).safeTransferFrom(msg.sender, address(this), assets);
+        // Get asset token
+        IERC20 assetToken = IERC20(asset());
+
+        // Transfer assets from depositor using safeTransferFrom
+        assetToken.safeTransferFrom(msg.sender, address(this), assets);
 
         // Mint shares to receiver
         _mint(receiver, shares);
 
-        // Approve and deposit assets into vault
-        IERC20(asset()).approve(address(_getpUSDStorage().vault), assets);
+        // Use safeIncreaseAllowance
+        assetToken.safeIncreaseAllowance(address(_getpUSDStorage().vault), assets);
         _getpUSDStorage().vault.enter(address(this), address(asset()), assets, receiver, shares);
 
         emit Deposit(msg.sender, receiver, assets, shares);
@@ -117,7 +135,7 @@ contract pUSD is Initializable, ERC20Upgradeable, AccessControlUpgradeable, UUPS
         uint256 shares,
         address receiver,
         address controller
-    ) public virtual override returns (uint256 assets) {
+    ) public virtual override nonReentrant returns (uint256 assets) {
         // Calculate the assets amount using previewRedeem
         assets = previewRedeem(shares);
 
@@ -137,7 +155,10 @@ contract pUSD is Initializable, ERC20Upgradeable, AccessControlUpgradeable, UUPS
     }
 
     // ========== ERC20 OVERRIDES ==========
-    function transfer(address to, uint256 amount) public virtual override(ERC20Upgradeable, IERC20) returns (bool) {
+    function transfer(
+        address to,
+        uint256 amount
+    ) public virtual override(ERC20Upgradeable, IERC20) nonReentrant returns (bool) {
         // Since balances are tracked in the vault, we only need to update the vault's records
         return _getpUSDStorage().vault.transferFrom(msg.sender, to, amount);
     }
@@ -146,16 +167,13 @@ contract pUSD is Initializable, ERC20Upgradeable, AccessControlUpgradeable, UUPS
         address from,
         address to,
         uint256 amount
-    ) public virtual override(ERC20Upgradeable, IERC20) returns (bool) {
-        // Handle allowance in the token contract
+    ) public virtual override(ERC20Upgradeable, IERC20) nonReentrant returns (bool) {
+        require(from != address(0), "ERC20: transfer from zero address");
+        require(to != address(0), "ERC20: transfer to zero address");
+
+        // Handle allowance using OpenZeppelin's ERC20 spending mechanism
         if (from != msg.sender) {
-            uint256 currentAllowance = allowance(from, msg.sender);
-            if (currentAllowance != type(uint256).max) {
-                require(currentAllowance >= amount, "ERC20: insufficient allowance");
-                unchecked {
-                    _approve(from, msg.sender, currentAllowance - amount);
-                }
-            }
+            _spendAllowance(from, msg.sender, amount);
         }
 
         // Delegate the actual transfer to the vault