# DatingDapp Smart Contract Audit Findings ## Overview This audit was conducted on the DatingDapp smart contract system, which consists of three main contracts: - SoulboundProfileNFT.sol - LikeRegistry.sol - MultiSig.sol ## High Severity Findings ### [H-01] Blocked Profile Can Bypass Restrictions by Reminting **Contract**: SoulboundProfileNFT.sol => this is actually Medium **Description**: The `blockProfile` function in SoulboundProfileNFT contract fails to permanently prevent blocked addresses from participating in the platform. **Impact**: - Blocked malicious users can immediately create new profiles - Platform security measures can be circumvented - Admin actions become ineffective **Proof of Concept**: 1. Admin blocks user A using `blockProfile(address A)` 2. User A's profile is burned and mappings are cleared 3. User A can immediately call `mintProfile()` to create a new profile **Recommendation**: Implement a blacklist mapping to track blocked addresses: ```solidity mapping(address => bool) public blockedAddresses; function blockProfile(address blockAddress) external onlyOwner { blockedAddresses[blockAddress] = true; uint256 tokenId = profileToToken[blockAddress]; require(tokenId != 0, "No profile found"); _burn(tokenId); delete profileToToken[blockAddress]; delete _profiles[tokenId]; emit ProfileBurned(blockAddress, tokenId); } function mintProfile(string memory name, uint8 age, string memory profileImage) external { require(!blockedAddresses[msg.sender], "Address is blocked"); // ... rest of the function } ``` ### [H-02] Incorrect Balance Management in Match Rewards **Contract**: LikeRegistry.sol **Description**: In the `matchRewards` function, user balances are set to zero before their values are used in calculations, resulting in zero rewards distribution. **Impact**: - Users lose all deposited funds when matched - No rewards are distributed to matched pairs - Funds remain locked in the contract **Proof of Concept**: ```solidity function matchRewards(address from, address to) internal returns (address) { userBalances[from] = 0; // Balance cleared before use userBalances[to] = 0; // Balance cleared before use uint256 matchUserOne = userBalances[from]; // Will always be 0 uint256 matchUserTwo = userBalances[to]; // Will always be 0 // ... rest of the function } ``` **Recommendation**: Store balances in temporary variables before clearing: ```solidity function matchRewards(address from, address to) internal returns (address) { uint256 matchUserOne = userBalances[from]; uint256 matchUserTwo = userBalances[to]; userBalances[from] = 0; userBalances[to] = 0; uint256 totalRewards = matchUserOne + matchUserTwo; // ... rest of the function } ``` ### [H-03] ETH Lock Risk in LikeRegistry **Contract**: LikeRegistry.sol => invalid, by design / info **Description**: The `receive()` function accepts ETH and updates user balances, but there's no mechanism for users to withdraw their funds directly. **Impact**: - User funds can be permanently locked in the contract - No way to recover accidentally sent ETH - Potential loss of user funds **Recommendation**: Add a withdrawal function for direct deposits: ```solidity function withdrawBalance() external { uint256 amount = userBalances[msg.sender]; require(amount > 0, "No balance to withdraw"); userBalances[msg.sender] = 0; (bool success,) = payable(msg.sender).call{value: amount}(""); require(success, "Transfer failed"); } ``` ## Medium Severity Findings ### [M-01] Potential Fund Lock in MultiSig => invalid, info, by design **Contract**: MultiSig.sol **Description**: The MultiSig contract lacks recovery mechanisms if one owner becomes unresponsive or loses their keys. **Impact**: - Funds could be permanently locked if one owner is unavailable - No way to replace or update owners - No emergency withdrawal mechanism **Recommendation**: Implement a timelock mechanism for emergency withdrawals or owner replacement functionality. ### [M-02] Missing Profile Update Functionality => invalid **Contract**: SoulboundProfileNFT.sol **Description**: Users cannot update their profile information without burning and reminting their NFT. **Impact**: - Poor user experience - Unnecessary gas costs for profile updates - Historical data loss when profiles are updated **Recommendation**: Add a profile update function with proper access controls. ## Low Severity Findings ### [L-01] Insufficient Input Validation => invalid **Contract**: SoulboundProfileNFT.sol **Description**: - No validation for name length - No validation for profile image URL format - No age restrictions or validation **Recommendation**: Add proper input validation: ```solidity function mintProfile(string memory name, uint8 age, string memory profileImage) external { require(bytes(name).length > 0 && bytes(name).length <= 50, "Invalid name length"); require(age >= 18 && age <= 100, "Invalid age"); require(bytes(profileImage).length > 0, "Invalid profile image"); // ... rest of the function } ``` ### [L-02] Gas Optimization Issues => not needed **Contracts**: All **Description**: - Storage of full profile data on-chain is expensive - Redundant storage of data that could be emitted as events - Inefficient string handling in profile data **Recommendation**: - Consider using events for historical data - Use off-chain storage for profile images - Optimize string handling and storage patterns ### [L-03] Missing Events for Critical Operations => not needed **Contracts**: All **Description**: Some state-changing operations lack event emissions, making it difficult to track changes off-chain. **Recommendation**: Add events for all significant state changes. ## Informational Findings ### [I-01] Documentation Gaps => not needed **Contracts**: All **Description**: - Limited NatSpec documentation - Missing function parameter documentation - Unclear error messages **Recommendation**: Improve documentation coverage and clarity. ### [I-02] Version Control => not needed **Contracts**: All **Description**: Contracts use `^0.8.19` which allows for minor version updates. **Recommendation**: Pin to exact version: `pragma solidity 0.8.19;`