Open hats-bug-reporter[bot] opened 3 weeks ago
WHITELISTER_ROLE is trusted, this assumes otherwise. I don't see this as an attack vector and the described attack flow seems to depend on the victim giving allowance to the attacker? doesn't make sense imo
I respectfully disagree with your response, which appears to misunderstand both the attack vector and the broader security implications at play. Your response suggests the attack depends on victims giving allowance directly to the attacker, but this misses the critical point: users must provide allowances to the InvestToken contract as part of normal protocol operations. The vulnerability exploits these legitimate protocol allowances, not direct attacker allowances. These approvals are a fundamental requirement for users to interact with the protocol, not an optional security risk. Dismissing this vulnerability simply because "WHITELISTER_ROLE is trusted" reflects a concerning security assumption. As recently demonstrated by the Radiant Capital hack ($50M loss), even systems with trusted roles and hardware wallets can be compromised through sophisticated attacks. Their team members' computers were trojaned, allowing attackers to intercept and manipulate signing requests while showing legitimate data on screens. This real-world example shows how trusted roles can be compromised despite robust security measures. Furthermore, your response doesn't address the core technical issue: the asymmetric validation between USDE and InvestToken contracts. This inconsistency creates a systemic vulnerability that could be exploited by a compromised whitelister. The fact that different validation logic exists between these interacting contracts demands explanation - either there's a specific reason for this design choice that should be documented, or it's an oversight that should be addressed.
users must provide allowances to the InvestToken contract as part of normal protocol operations
I don't understand this point. Which operations do you suggest users have to provide allowance to the contract for?
Dismissing this vulnerability simply because "WHITELISTER_ROLE is trusted" (...) security measures.
Your recommendations might make certain attack vector more difficult, but a malicious actor getting access to a role poses more general problems whose solution falls under the umbrella of operational handling. Since the tokens are compliant with certain regulations, onchain logic has to facilitate flexible operations.
Furthermore, your response doesn't address the core technical issue: the asymmetric validation between USDE and InvestToken contracts (...) either there's a specific reason for this design choice that should be documented, or it's an oversight that should be addressed.
The reason for it is because of compliance with regulations. Getting into the details/reasons of these regulations is beyond the scope, but the intended design is clear and mentioned in the README.
Github username: -- Twitter username: -- Submission hash (on-chain): 0x5f99236dbd42a4d5e063ac3e411503d2959907fe09c3230f62a7ca46aa5ffd96 Severity: high
Description:
Brief
The Validator contract allows malicious actors with WHITELISTER_ROLE to exploit asymmetric validation between USDE and InvestToken. By manipulating validator states, an attacker can steal user funds and lock them in InvestToken, leading to a complete loss of user assets.
Vulnerability Details
Core Issue
The vulnerability stems from inconsistent validation logic between USDE and InvestToken when interacting with the Validator contract:
The key vulnerability is that USDE allows transfers as long as accounts aren't blacklisted, while InvestToken requires accounts to be explicitly whitelisted. This asymmetry can be exploited through a sandwich attack.
Attack Flow
When spotting a victim with active approvals:
Recommendation
Immediate actions needed:
Code fixes:
// Option 2: Add state change delay mapping(address => uint256) public lastStateChange; uint256 public constant STATE_CHANGE_DELAY = 24 hours;
function whitelist(address account) external { require(block.timestamp >= lastStateChange[account] + STATE_CHANGE_DELAY, "delay not met"); _whitelist(account); lastStateChange[account] = block.timestamp; }
Test Output
The test execution demonstrates a complete end-to-end exploitation of the vulnerability:
The attack successfully transitions through all states:
WHITELISTED (1) → VOID (0) → WHITELISTED (1)
Full value capture is achieved:
Victim loses all 1000 USDE Attacker gains 1000 InvestTokens No funds are lost in the process
All state changes and transfers succeed:
No reversion during VOID transfers No reversion during re-whitelisting No reversion during final deposit
This proof of concept demonstrates not just the theoretical vulnerability but a practical, working exploit that could be deployed on mainnet, making the threat immediate and concrete.