According to Numen’s on-chain monitoring, on Mar-15-2023 03:16:02 AM +UTC, Ethereum, Binance, and Polygon’s on-chain Poolz Finance was attacked, resulting in a total loss of approximately $665,000. The attacker managed to siphon the following:
- 2,805,805 MEE
- 525,134 ESNC
- 774,997 DON
- 2,007,504,238 ASW
- 6,510,689 KMON
- 2,521,065 POOLZ
- 35,976,107 DCD
- 760,845 PORTX
- 252,153,413 ECIO
- 35,975,489 WOD
- 29,032,394 SIP
- 61,856,885 MNZ
- 465,116 EBA
- 157,696 GEMG
- 202,442 WANA
- 223,500 KXA
- 82,067 MSTR
- 1,717,102 CHRP
- 822,631 CVZ
- 37,053 CHIM
- 8,577,867 QZA
The attacker’s address is 0x190Cd736F5825ff0Ae0141B5C9cb7Fcd042cef2a,
The contract is 0x058bae36467a9fc5e1045dbdffc2fd65b91c2203.
One of the attack transactions is 0x39718b03ae346dfe0210b1057cf9f0c378d9ab943512264f06249ae14030c5d5.
Poolz Finance Attack Process
The attack process is as follows:
- The attacker first exchanged MNZ tokens through PancakeSwap.
- The attacker then called the CreateMassPools function, which was the main issue in the attack.
The normal function is that users can create pools in batches, provide initial liquidity, and then create the pools using the CreatePool function, which records the pool attributes using a mapping.
The issue arose with the getArraySum function controlling the amount in TransferInToken, which was used to establish liquidity in the pool.
The issue was with the getArraySum function, which iterates through the startamount array and accumulates its values. By looking at the call stack, it was found that the array sum exceeded uint256, which caused the function to return 1. However, the CreatePool function still used startamount to record the pool attributes, which allowed the attacker to deposit only 1 token, but with an extremely large startamount value.
The attacker then called withdraw to complete the attack and profit from the exploit.
The root cause of this attack was an arithmetic overflow. To prevent this issue, it is recommended to use the higher version of Solidity that performs overflow checks during compilation, or to use the OpenZeppelin SafeMath library in lower versions of Solidity to prevent integer overflow.