Skip to content

Latest commit

 

History

History
80 lines (54 loc) · 6.98 KB

pool_owner_proxy_bug.md

File metadata and controls

80 lines (54 loc) · 6.98 KB

Vulnerability disclosure 2022-11-20

Summary

  • A vulnerability was discovered in an old Curve Pool Owner contract. This contract was the admin of the old stableswap factory (0x0959158b6040D32d04c301A72CBFD6b39E21c9AE).
  • The vulnerability did not affect user funds. The attack vector was limited to fees earned by the DAO from a minimal set of pools (metapools created by the old factory).
  • The bug reporter was paid out a bounty of 100k CRV.
  • Total value lost: approximately 18k USD of DAO fees. This loss could have been avoided entirely but was exploited by the individual who reported the bug. They have been reported to ImmuneFi* for failing to return these funds.
  • The vulnerability has been patched via a DAO parameter vote: Curve Parameter vote 46.
  • All funds are safe.

*At the time of writing this report, Curve does not have a bug bounty under ImmuneFi. The security researcher was investigating another protocol (Beanstalk) with a liquidity pool on Curve, where they discovered this bug.

Background

On 21st October 2022, an independent security researcher discovered an unguarded contract method in a Pool Owner contract that allowed anyone to set the fee_receiver of metapools in the old stableswap factory. Following this report, Curve core contributors created a new Pool Owner contract to fix issues presented in the faulty Pool Owner contract. Including it into the Curve framework required a DAO vote. The vulnerability has since been patched.

Before and after reporting the vulnerability, the security researcher actively exploited the bug and profited approximately $18k (from DAO fees). They have since refused to return these funds, despite receiving a generous bounty. As the researcher works under the ImmuneFi umbrella, Curve core contributors have reported this behaviour to the ImmuneFi team.

Details of the vulnerability

The faulty contract was: Old Pool Owner. The Pool Owner contract is responsible for setting and changing pool parameters (which do not affect user funds) and receiving fees accrued from swaps (which also do not affect user funds). The pool owner was the admin of the Old Stableswap Factory.

The bug was an unguarded method:

@external
def set_fee_receiver(_target: address, _base_pool: address, _fee_receiver: address):
    Factory(_target).set_fee_receiver(_base_pool, _fee_receiver)

This bug allowed anyone to set a specific address (_fee_receiver parameter) as the fee recipient of pools paired with _base_pool (e.g. 3pool). The bug only affected pools deployed by the old factory. The old factory was already deprecated in favour of the New Stableswap Factory a while ago. In this case, the target was the Old Stableswap factory: (tx hash)[https://etherscan.io/tx/0xe1fc066f789bcf17e22448d814c8f909a788f186a3d875062edb434857d3c35e].

Exploit contract

This bug did not require an external contract to exploit the bug.

Details of the fix

The fix involved two steps:

  1. Replace the admin of the Old Stableswap Factory with a new contract that fixes this vulnerability: 0x8c392fB6F79e2564D73Fe13FB3Ef034f5A309c3D.
  2. Set fee recipient to 0xeCb456EA5365865EbAb8a2661B0c503410e9B347.

The Parameter vote that fixes these issues: Parameter VoteID: 46

The enactment: 0x98a86c5b09ee1e752a9d74ce08c1fe74229e13cd9a9f871a90cda67ad4a16fe3.

Timeline

Links

The blackhat's addresses:

The blackhat has transferred funds that require KYC: