DatingDapp

First Flight #33
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Invalid

Duplicate MultiSig Wallets Created Permanently

Summary

The matchRewards() function creates a new MultiSigWallet contract every time a match occurs. This permanently deploys multiple duplicate wallets on-chain, leading to high gas costs, redundant storage, and potential loss of funds.

Vulnerability Details

matchRewards() in LikeRegistry.sol

function matchRewards(address from, address to) internal {
MultiSigWallet multiSigWallet = new MultiSigWallet(from, to); // ❌ Deploys new wallet every time!
(bool success, ) = payable(address(multiSigWallet)).call{value: rewards}("");
require(success, "Transfer failed");
}

Problem:

  • Every match deploys a new MultiSigWallet contract on-chain.

  • Users who match multiple times will generate multiple redundant wallets.

  • Old wallets remain permanently deployed, wasting gas & blockchain storage.

  • Funds can get stuck in unused wallets, as users may not track all deployed wallets.

PoC

1.Alice and Bob match the first time.

  • A new MultiSigWallet is deployed.

  • MultiSigWallet #1 is created.

2.Alice and Bob match again later.

  • Another MultiSigWallet is deployed.

  • MultiSigWallet #2 is created.

3.Both wallets exist permanently, increasing gas costs and on-chain clutter.

Unexpected Result: Alice and Bob now have two separate wallets for the same match, making it hard to track funds!

Impact

  • Permanent blockchain clutter: Every match deploys a new contract forever.

  • High gas fees: Unnecessary deployments waste user funds.

  • Lost funds risk: Users may not track multiple wallets, losing access to their funds.

Tools Used

Manual Review

Recommendations

Use a Mapping to Store Existing Wallets.

Modify matchRewards() to check if a wallet already exists before creating a new one.

// Store wallets
mapping(address => mapping(address => address)) public multiSigWallets;
function matchRewards(address from, address to) internal {
// Check if a wallet already exists
if (multiSigWallets[from][to] == address(0)) {
MultiSigWallet multiSigWallet = new MultiSigWallet(from, to);
multiSigWallets[from][to] = address(multiSigWallet); // Store wallet address
}
uint256 matchUserOne = userBalances[from];
uint256 matchUserTwo = userBalances[to];
userBalances[from] = 0;
userBalances[to] = 0;
uint256 totalRewards = matchUserOne + matchUserTwo;
uint256 matchingFees = (totalRewards * FIXEDFEE) / 100;
uint256 rewards = totalRewards - matchingFees;
totalFees += matchingFees;
address wallet = multiSigWallets[from][to]; // Use existing wallet
(bool success, ) = payable(wallet).call{value: rewards}("");
require(success, "Transfer failed");
}
Updates

Appeal created

n0kto Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.