Attack Details

Attack Details:

By exploiting the DEI token implementation bug, the attacker could manipulate allowances, transfer DEI out of the pair, and swap it for a significant amount of USDC.

The series of events led to the massive security breach and loss of user funds on the Chronos Exchange on the Arbitrum platform, as well as on all other exchanges on which the DEI token was listed.

An in-depth examination of the attack can be found by analyzing the following Arbitrum transaction: https://explorer.phalcon.xyz/tx/arbitrum/0xb1141785b7b94eb37c39c37f0272744c6e79ca1517529fec3f4af59d4c3c37ef?line=25

Here is a simplified explanation of the attacker's method and steps taken:

  1. First, the attacker takes advantage of the bug in the DEI token implementation, which allows them to increase the allowance for any DEI holder. Consequently, the attacker can move any $DEI funds.

Step 1: The attacker calls DEI.burnFrom(spender = sAMM Pair, amount = 0).

The burnFrom implementation involves the approve implementation, where _approve(sAMM, attacker, currentAllowance) is called. That allowed the attacker to spend any 'currentAllowance' from the sAMM Pair.

Link to the source code: https://bscscan.com/address/0x1472b3081d81b792e697aea90accbbc4adc5baf9#code#F5#L308

_allowances[_msgSender()][account]

should be

_allowances[account][msgSender()]

The exploitable burnFrom function:

    function burnFrom(address account, uint256 amount) public virtual {
        uint256 currentAllowance = _allowances[_msgSender()][account];
        _approve(account, _msgSender(), currentAllowance - amount);
        _burn(account, amount);
    }
function _approve( 
address owner, 
address spender, 
uint256 amount 
) internal virtual { 
_allowances[owner][spender] = amount; 
emit Approval(owner, spender, amount); 
}

Step 2: The attacker abuses the broken burnFrom to increase his allowance & transferFrom all DEI out of the pair.

Step 3: The attacker calls sAMM.sync()

which recalculates the reserves based on the token balances.

After calling sync,

DEI reserve0 is 1,

USDC reserve1 is 5,047,470,472,573.

Step 4:

  • The attacker calls swap() and trades the difference. Now, 0 DEI is worth 5 million USDC.

Call swap() and trade the difference; 0 DEI is worth 5M USDC now.

Step 5: The attacker transfers DEI back

This step allowed for massive further damages.

This step allows for massive, massive further damages.

Attackers' accrued profits of approximately $5 million, yet the consequential damages far exceed this figure, estimated to be between $8-10 million based on our current analysis. (before recovering funds, check recovery here)

Based on this step, we conjecture that the attacker opted for a rushed approach, likely fearing that someone else might discover the bug or that his main target was causing maximum damage.

Read more about it here.

  1. Address holding funds after the attacker swapped USDC to WETH: https://arbiscan.io/address/0x189cf534de3097c08b6beaf6eb2b9179dab122d1

Last updated