#access-control, #tx.origin, #unsafe-setter
The setPerpVault function uses an insecure tx.origin == owner() check instead of a reliable onlyOwner modifier based on msg.sender. An attacker can trick the owner into calling the function through a malicious contract, passing attackerAddress as the new perpVault. Once perpVault is pointed to the attacker, any subsequent call to refundExecutionFee drains Ether directly to the attacker’s address.
Flawed Authentication: The function relies on tx.origin == owner(), which is vulnerable to phishing or malicious intermediary contracts.
Arbitrary Address Assignment: Attackers set perpVault to their own address.
Ether Drain: The new perpVault holder calls refundExecutionFee with an arbitrary amount, withdrawing the contract’s Ether.
Impact: High – Attackers acquire direct, unauthorized access to the contract’s Ether balance.
Likelihood: High – A single tx.origin check can be bypassed through phishing, malicious call flows, or compromised user wallets.
Manual Review
An attacker deploys a malicious intermediary contract.
The attacker successfully tricks the owner into calling setPerpVault with the attacker’s address as the new perpVault and supplies a valid market parameter.
The tx.origin check passes because the owner's address is the transaction origin, and the function sets perpVault to the attacker-controlled address.
The attacker, now as the authorized caller, invokes refundExecutionFee with their address and an arbitrary Ether amount.
The contract transfers Ether to the attacker's address, draining funds from the contract.
Replace tx.origin-based authentication with a robust modifier like onlyOwner (based on msg.sender).
Consider making perpVault immutable if no changes are required after initialization. Otherwise, wrap changes in multi-signature governance approvals.
Lightchaser: Medium-5
The 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.