-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TWAP Oracle needs to determine peg (track $1.00 USD accurately) #259
Comments
I would be able to take this on. Approach 1 Approach 2 Approach 3 Approach 4 I would be open to using approaches 1 or 4 and am available to discuss them further. Would be able to complete it within a week of approval at a price of 1200 USDC. |
Can you elaborate on what you mean by matching? I assumed that if we only do calls vs writes then its free? I feel like this requires just a tad more research but your proposal seems very reasonable and I'm glad that you were able to respond so promptly! |
Sorry, autocorrect changed mathing to matching without me noticing. If using stable pools then reading from each one won't cost anything, it's the math to find the median that will cost gas. If you're using 3 sources vs 6, there's less math to do when comparing 3 but is also more fragile if somehow one of the pools were to be exploited. It could be built to use a set number of sources or so that sources can be added and removed if needed. If wanting to avoid using other stablecoins altogether it could be based on ETH/USD vs ETH/uAD. I don't fully understand the implications that this would have but instincts tell me it's a bad idea and would need massive ETH/uAD depth for it not to be manipulatable. |
Before committing to this architecture its prudent to sample the gas cost of calculating the median of 2 markets and then we can extrapolate to determine reasonable bounds (e.g. we should limit it to 10 markets because the tx cost will be like $50 at 10 gwei etc.) This research is necessary but we don't really have a bounty structure for research related tasks. Since our internal devs are saturated, if this task is something of interest to you we can add an additional time/cost estimate to your quote and have a report be your first deliverable? |
The biggest gas cost of finding a median value would likely be sorting the values. I could build a relatively simple contract that does that with two values and fuzz testing. I could have the report done by Friday and possibly earlier depending on other workloads. Total would be 1400 USDC, 200 for report, 1200 for the rest if approved once method is decided on. |
Since the simple contract is a prototype, security doesn't need to be a priority. My expectations are the following:
As a heads up, we're considering a launch on Optimism which may grant a ton more flexibility for gas costs. The report should include:
Bonus: if you find a way to dynamically select the optimal (definition TBD but e.g. the highest liquidity) markets from Curve to choose from, then this will prompt @Draeieg and other math wizards on the research team to design an algorithm to filter for the subset thats relevant (e.g. $1 pegged stablecoins) With all that said, do you need to update your time/price estimate? |
Nope, and fuzz testing is more to test the math/sorting implementation and try to find any outliers for gas costs. I can write it to take an array of values and do a test with uint[2] and another with uint[3]. Comparing the two will allow me to extrapolate gas costs. |
You're authorized to proceed on the research portion. After we review your report I presume that you'll also be assigned to the real implementation! |
Report is ready |
@0xcodercrane @zgorizzo69 do you have any remarks on @hashedMae's implementation? @hashedMae I'm not sure what the USD value equivalents are at current prices. Are you able to answer the following?
|
I updated the readme in my repo with a table of the cost for each with Ether at $1600 and 50 gwei per gas. At 10 gwei per gas, the examples in the right hand column were a couple cents each. Ideally, would collect the information off chain, arrange it in order lowest to highest, then pass it to the contract. If that's not possible without refactoring multiple other contracts then I would go for the mean instead of median. Creating an ordered list on chain is too expensive because it requires looping and several writes to storage. |
Would we need to verify this on chain with something like merkle trees etc? Or is verification not necessary?
What contracts are you thinking need to be refactored? Median is less risky and is highly preferred as the strategy. For example if one of the five markets we select implodes, it should not negatively affect our oracle price. Ideally if we can have dynamic selection (e.g. top 5 highest liquidity markets) then mean also probably wouldn't work (it could select RAI, or LUSD which both are generally not at $1.00) |
I didn't have a chance to take a look unfortnately. but will get a chance at least this weekend. |
I don't think it would require a merkle tree. I'm not familiar enough with the current architecture to know which ones are calling the current TWAP contact. Way I would do the ordering off chain is whenever a call is made that needs the TWAP, the website backend uses ABIs from Uniswap and Curve to pull the prices from the stable pools we've identified, it puts them in an uint array that's ordered from least to greatest, and then passes that through to the contract in the call. If wanting to use a weighted average it could poll the ABIs periodically and store the values, discarding them once they pass a certain threshold of time. |
@Draeieg @hashedMae @0xcodercrane I propose that we hop on a call after you look. @0xcodercrane you think you could make a group chat when ready? @hashedMae what is your ERC20 USDC address? |
For sure, I will make a group chat at least next Monday. |
@pavlovcik |
Thinking more about off chain data collection and ordering. I'm not a web2 security expert but some sort of on chain verification is likely needed to minimize risk. I'd only seen static merkle trees used previously but it seems a dynamic merkle tree with on-chain verification is possible https://ethresear.ch/t/efficient-on-chain-dynamic-merkle-tree/11054 If not merkle tree then whitelisting addresses that can be polled for the info, then verify the information on chain by contract and the block it was polled. That way if someone were to achieve some sort of code injection on the website, and were using their own contracts with phony info, our own contracts could look at the addresses and reject them. |
Thanks! https://etherscan.io/tx/0xfb57b27c9423a9e167823c866548c441e23cf5a5f085a3b5cfb28f2bb789caa8 |
Note for call:
function median(numbers) {
const sorted = Array.from(numbers).sort((a, b) => a - b);
const middle = Math.floor(sorted.length / 2);
if (sorted.length % 2 === 0) {
return (sorted[middle - 1] + sorted[middle]) / 2;
}
return sorted[middle];
} For whatever its worth, I used the CoinGecko converted values in a second test (the dollar representations, with only two decimal places) and the result was exactly |
Amplification CoefficientAppendix
Curve Pool Registryget pool asset typehttps://curve.readthedocs.io/registry-registry.html#Registry.get_pool_asset_type -
Is metapool?boolean https://curve.readthedocs.io/registry-registry.html#pool-metadata |
Minutes / homework
|
https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.9432 I'll also try to look into RAI to see if there is a way we can call the oracle based on a PID controller, sounds a lot more complex than an average but who knows |
In case I haven't shared this yet, our current oracle relies on a two-swap TWAP (built in to the metapool contract) meaning that if two blocks can be proposed consecutively, we can get rekt. I understand that Uniswap V2's twap oracle implementation encodes a few variables into every sample. (I believe they include the price data with the timestamp and have some minimum time window like a few minutes? It's been a couple years since I last looked and I'm on my phone about to sleep now) Perhaps we can borrow some tricks to make our TWAP less exploitable in this double MEV scenario https://twitter.com/macromate8/status/1563118677549264896?s=46&t=_UGbHclguQLRq9mzlZadXg |
hi, i want to be assigned to this, perhaps more can be explained |
Available commands
|
/start |
@malik672 could you first describe what is the solution you are going to implement? |
I feel like we should spend some weeks revising all of these old bounties on this repository so that we can ensure clear specifications and deliverables. |
@rndquu i can either implement 1 or 4 |
@pavlovcik I removed time and priority labels because the issue desc is not clear @malik672 pls select another bounty while we're making specs more clear for this one |
@pavlovcik ok, thanks is there any solidity related bounty that needs urgent attention |
there will be new solidity related tasks next week |
Skipping |
Could somebody elaborate on why exactly the |
I distinctly remember after Luna imploded and tons of liquidity flowed through the curve markets when people were exiting, and that presumably the 3CRV token accrued trading fees. That was the reason why I originally wrote this. I don't fully understand the 3CRV price mechanics but this is just an observation from CoinGecko price data. |
Curve's 3pool has a trading fee set to 0.1% where:
So, as far as I understand, 3CRV LP token accumulates trading fees hence it's USD quote is greater than We have a TWAP oracle contract that relies on We could use chainlink for fetching |
Closing this as completed in #893 |
! No price label has been set. Skipping permit generation. |
Do you have a brief explanation of the solution? Are you cross referencing the price of ETH? |
We migrated to the latest Curve's metapool implementation which has a built-in oracle. I haven't investigated in depth the Curve's code, but, as far as I understand, latest price oracle takes into account 3CRV LP "virtual price" which is basically a tripool growth overtime. If tripool growth is 3% then 3CRV LP virtual price is 1.03 which is equal to $1.03 USD value. So we're free to use 3CRV LP virtual price in calculations. The implemented solution was proposed in one of the audit issues + cergyk (lead senior watson) signed off on the fix. |
This needs more research but currently our TWAP oracle tracks 3crv, which currently is trading ~$1.02. The net effect of this is that our dollar thinks that our peg is ~$1.02 (1:1 match)
The
consult
method in the oracle contract needs to be updated to actually track $1.00. Off hand and without research, there's several approaches we can take for this:The method lives here:
https://github.com/ubiquity/ubiquity-dollar/blob/enhancement/styles/packages/contracts/dollar/contracts/TWAPOracle.sol#L70-L81
Originally posted by @pavlovcik in #161 (comment)
The text was updated successfully, but these errors were encountered: