The claimProfit function in the MembershipERC1155 contract is vulnerable to a reentrancy attack, which could allow malicious users to drain the contract's funds by recursively calling claimProfit before their profit state is updated.
The issue arises because the claimProfit function transfers tokens to the user before updating the savedProfit[msg.sender] variable. This creates a window where a malicious user could exploit the transfer process by re-entering the claimProfit function, calling it recursively, and draining additional tokens from the contract.
Reentrancy protection: The function does not guard against reentrancy, which is a common vulnerability in Solidity smart contracts that can allow an attacker to perform unintended actions.
State consistency: By updating the state (i.e., resetting savedProfit[msg.sender]) after transferring tokens, the function violates the typical order of operations, which may allow unexpected behavior.
A malicious actor could call claimProfit, triggering the token transfer to their address. Before the state update is completed (before the savedProfit[msg.sender] is set to 0), they could recursively call claimProfit, claiming additional tokens without the state reflecting the correct balance. This could result in the contract transferring more funds than intended.
Malicious actor calls claimProfit.
Tokens are transferred to the malicious actor’s address.
Before the savedProfit[msg.sender] state variable is updated, the actor reenters the claimProfit function.
The attacker claims more tokens than they are entitled to by exploiting the reentrancy gap.
This recursive attack can continue, leading to fund draining.
Vulnerability Type: Reentrancy attack.
Location in code: The issue is in the claimProfit function, specifically with the order of state updates and token transfers.
Token Transfer: The contract calls IERC20(currency).safeTransfer(msg.sender, profit) before updating the state (i.e., savedProfit[msg.sender] = 0).
This vulnerability can lead to a loss of funds from the contract. Malicious users can exploit the reentrancy gap to repeatedly claim profits, draining the contract's available balance. Depending on how much profit has accumulated and the number of reentrancy calls, this can result in serious financial damage.
Here’s how a malicious actor could exploit the vulnerability:
Deploy a malicious contract that calls the claimProfit function in the target contract.
In the fallback function of the malicious contract, call claimProfit recursively.
This will allow the malicious actor to drain the contract’s balance by continuously claiming profit before the state is updated.
Example of a malicious contract:
To fix the issue and prevent reentrancy attacks, the claimProfit function should be modified to update the state first and then transfer the tokens to the user. This eliminates the reentrancy window that allows recursive calls before the state is updated.
Consider adding a reentrancy guard (e.g., using the ReentrancyGuard from OpenZeppelin) to prevent multiple nested calls to the claimProfit function.
MembershipERC1155.solThe contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.