2025-02-datingdapp/agent-finding.md
han 09ed9015e5
Some checks failed
CI / Foundry project (push) Has been cancelled
add valid finding, ai finding, and retro
2025-03-08 23:24:27 +07:00

205 lines
6.2 KiB
Markdown

# 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;`