hats-finance / VMEX-0xb6861bdeb368a1bf628fc36a36cec62d04fb6a77

LP token lending protocol
MIT License
2 stars 4 forks source link

Balancer Oracle stable pairs need to divide by the rate #6

Open hats-bug-reporter[bot] opened 1 year ago

hats-bug-reporter[bot] commented 1 year ago

Github username: -- Submission hash (on-chain): 0x06738a6303eb869c0aa5a99e558f4139911996486753579b4bee5f8a3e726c52 Severity: low

Description: Description\

When calling min(prices), we need to make sure all of the prices are actually like-kind (i.e., supposed to be the same). The rETH price is NOT supposed to be the same as the WETH price; you can imagine that eventually, after lots of yield has accrued, the price might be 10:1. In this case, min(prices) will always give us the WETH price, and what does that really tell us? Nothing.

What we really want to know is how rETH is trading relative to its theoretical price, NOT relative to the price of WETH. So, we have to normalize the price of rETH by dividing its on-chain deposit/redemption rate. Then we get a number close to 1 WETH, where if it's trading at a relative premium then it will be greater, and at a discount lesser.

Attack Scenario\ Imagine that 1 rETH == 10 WETH (lots of yield has accrued over time).

Now, something bad happens, and the market prices 1 rETH at just 5 WETH (50% discount).

// market price: 10 WETH | redemption price: 10 WETH
min(10 WETH, 1 WETH) => 1 WETH

// market price: 5 WETH | redemption price: 10 WETH
min(5 WETH, 1 WETH) => 1 WETH

We don't even see the discount in our price logic because we get the same result before and after the discount. If we use the normalized version:

// market price: 10 WETH | redemption price: 10 WETH
min(1 WETH, 1 WETH) => 1 WETH

// market price: 5 WETH | redemption price: 10 WETH
min(0.5 WETH, 1 WETH) => 0.5 WETH

Now we see the 50% discount, and we apply it to our overall BPT price when we compute the return value.