Description
On September 22, 2025, UxLink’s multisig was compromised through private key theft, resulting in $11.3M direct theft plus unauthorized minting of 10 trillion tokens worth ~$28M. Attackers manipulated the multisig configuration to drain funds and gain token minting privileges.Core Vulnerability Mechanism
The attack exploited two weaknesses:- Compromised Private Keys: Attackers gained access to UxLink’s multisig owner private keys
- Unrestricted Multisig Configuration: Safe contract allowed threshold reduction and owner changes without security checks
- Token Minting Access: Compromised multisig gained Manager privileges over the UXLINK token contract
Attack Analysis
Attack Sequence
Phase 1: Multisig Compromise Attackers used compromised private keys to revoke admin privileges, add themselves as owners, and reduce the multisig threshold to 1, gaining full control. Phase 2: Treasury Drainage Drained $11.3M in assets (USDT, USDC, WBTC, ETH) and converted them across chains. Phase 3: Token Exploitation Used multisig control to mint unlimited UXLINK tokens, causing a price crash and significant market cap loss.Root Causes
- Private Key Compromise: Compromised private keys due to poor operational security
- No Multisig Protection: No safeguards against rapid configuration changes
- No Rate Limiting: Multisig changes executed immediately without cooling periods
- Missing Access Controls: No whitelisting for owner changes
Proposed Solution
Multisig protection assertions could have prevented this attack:How These Assertions Prevent the Attack
What they do:- Threshold Protection: Prevents any threshold reduction
- Owner Whitelisting: Only allows pre-approved addresses to become owners
- Cooling Periods: Enforces 24-hour delays between configuration changes
- Timestamp Tracking: Updates last change times to enforce cooling periods
- Batch Protection: Prevents rapid owner additions/removals in sequence
- Step 1:
assertThresholdProtection()
blocks threshold reduction and enforces 24-hour cooling period - Step 2:
assertOwnerAddition()
blocks attacker address (not whitelisted) and enforces cooling period - Step 3:
assertOwnerRemoval()
blocks rapid removal of legitimate owners and enforces cooling period - Result: Prevents rapid reconfiguration and batching that enabled the multisig compromise