Request an Audit
Back
  • 09/15/2025

Nemo Protocol Hacking Analyze

Event Summary:

On September 7, 2025, Beijing time, Nemo on Sui Chain was attacked, and hackers stole approximately $2.4 million by manipulating py_index.

Attacker Address:

0x01229b3cc8469779d42d59cfc18141e4b13566b581787bf16eb5d61058c1c724

Attack Transaction:

https://suivision.xyz/txblock/HMMicxQWn43rnNswi4gNHanUaeiWW5ijqM5bHLca67D9?tab=Overview

Nemo Package:

0x0f286ad004ea93ea6ad3a953b5d4f3c7306378b0dcc354c3f4ebb1d506d3b47f

Root cause:

The main reason for the Nemo theft was that PyState was incorrectly set to a mutable reference, allowing the attacker to maliciously modify py_index and mint a large amount of PT and YT at an inflated interest rate when calling the mint_py function.

After in-depth analysis, it was found that when the py.get_sy_amount_in_for_exact_py_out function calls py.current_py_index, an unconstrained number is allowed to be passed in to modify the py_index field of pyState.

  • py.get_sy_amount_in_for_exact_py_out calculates the amount of SY input required for PY output, but there is no limit on index here
  • py.current_py_index compares the incoming py_index with the stored index and returns the largest value as the latest value of py_state.py_index_stored

Attack Process Analysis:

  1. The attacker calls the init_py_position function to initialize a py_position
  1. Then use flash loan py.borrow_pt_amount to borrow a large amount of PT tokens
  1. Call market.swap_exact_pt_for_sy 100 times to convert PT into SY tokens
  1. Calculate the SY input required for PY output through py.get_sy_amount_in_for_exact_py_out. Here, the attacker passes a constructed extremely large number 553402322211286548480000 into py_index, destroying the original structure.
  1. The attacker then exploited the abnormally inflated index to mint PT and YT at an abnormally high discount rate when calling yield_factory.mint_py, thereby siphoning off a large amount of PT.

MintEvent is as follows:

  1. Finally, the attacker uses the minted PT to repay the debt through py.repay_pt_amount, then redeem the yield asset through redeem and withdraw the tokens in Scallop.

At this point, the attacker has stolen approximately $2.4 million through py_index operations. The assets were then converted to USDC and transferred across chains via Bridge. Finally, they were converted to ETH and DAI and stored at 0x41b1906c4BCded607c6b02861cE15C2E49FF7576.

After the attack, the Nemo team urgently suspended the smart contract function and began to investigate the attack.

Summary:

The core of this attack lies in incorrectly setting sensitive data to a writable state, allowing attackers to freely input parameters and modify them. The status of sensitive data should be strictly restricted and checked.