On July 16, 2024, we monitored an attack event on the Ethereum blockchain: https://etherscan.io/tx/0xd82fe84e63b1aa52e1ce540582ee0895ba4a71ec5e7a632a3faa1aff3e763873.
The targeted protocol was LI.FI Protocol, a liquidity aggregation protocol. In this attack, the attacker profited a total of 2,276,295 USDT, equivalent to 2,270,000 USD.
Detailed Analysis of the Attack
First, the attacker checked the USDT balance of the address 0xabe45ea636df7ac90fb7d8d8c74a081b169f92ef
and the allowance of this balance to be spent by the LI.FI Protocol.
Next, the attacker invoked the depositToGasZipERC20
function.
The specific implementation of the above function is shown below:
We can see that the function depositToGasZipERC20
calls the LibSwap.swap
function, with the specific code as follows:
The structure of SwapData
is as follows:
We can see that by controlling the _swap
parameter of the swap
function, it is possible to use the LI.FI Protocol contract to call any contract with arbitrary parameters. The parameters passed by the attacker were:
0xdac17f958d2ee523a2206206994597c13d831ec7: callTo
0x986aca5f2ca6b120f4361c519d7a49c5ac50c240: approveTo
0xf929ba2aeec16cffcfc66858a9434e194baaf80d: sendingAssetId
0xf929ba2aeec16cffcfc66858a9434e194baaf80d: receivingAssetId
0x0000000000000000000000000000000000000001: fromAmount
0x23b872dd000000000000000000000000abe45ea636df7ac90fb7d8d8c74a081b169f92ef0000000000000000000000008b3cb6bf982798fba233bca56749e22eec42dcf300000000000000000000000000000000000000000000000000000211fdceaf69: callData
0x0000000000000000000000000000000000000000: fromAmount
According to the SwapData
structure, we can see that the attacker used the parameters to call the contract at 0xdac17f958d2ee523a2206206994597c13d831ec7: callTo (USDT)
, with the inputData
being 0x23b872dd000000000000000000000000abe45ea636df7ac90fb7d8d8c74a081b169f92ef0000000000000000000000008b3cb6bf982798fba233bca56749e22eec42dcf300000000000000000000000000000000000000000000000000000211fdceaf69: callData
.
Since 0x23b872dd
is the signature for transferFrom
, the parameters for this function were parsed as follows:
0x23b872dd
0x000000000000000000000000abe45ea636df7ac90fb7d8d8c74a081b169f92ef: from
0x0000000000000000000000008b3cb6bf982798fba233bca56749e22eec42dcf3: to
0x00000000000000000000000000000000000000000000000000000211fdceaf69: value
This means the attacker used the LI.FI Protocol to transfer 2,276,295.880553 USDT from 0xabe45ea636df7ac90fb7d8d8c74a081b169f92ef
to 0x8b3cb6bf982798fba233bca56749e22eec42dcf3
. The attack was thus completed.
Summary
The vulnerability occurred because the targeted contract did not strictly validate the parameters passed by the attacker, allowing the attacker to craft specific inputData
that caused the victim's contract to call any contract with arbitrary parameters. Ultimately, the attacker used these crafted parameters to have the victim's contract call transferFrom
, transferring tokens authorized to the victim's contract to an address controlled by the attacker. It is recommended that project teams implement multiple layers of validation in their code logic and, during pre-launch audits, engage multiple auditing firms for cross-verification.