#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.