Skip to content
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

restaking: Restaking oracle #334

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft

restaking: Restaking oracle #334

wants to merge 4 commits into from

Conversation

dhruvja
Copy link
Collaborator

@dhruvja dhruvja commented May 29, 2024

Adding support to get price feed from oracle so that we can support staking of assets other than SOL and LSTs. The method gets the token price from oracle and then is divided by sol price to get in terms of sol. If the price feed id doesnt exist for tokens, then the solana price feed id is used as default.

Comment on lines +122 to +130
let token_decimals = ctx.accounts.token_mint.decimals;

let amount_in_sol_decimals = (amount *
10u64.pow(SOL_DECIMALS as u32)) /
10u64.pow(token_decimals as u32);

let final_amount_in_sol = ((token_price.price *
(amount_in_sol_decimals as i64)) /
sol_price.price) as u64;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can subtract rather than dividing. More importantly, I’m not
happy with the i64 and u64 conversions. Those need to be checked
rather than as. We have overflow checks for other operations but
as just interprets the bits.

Suggested change
let token_decimals = ctx.accounts.token_mint.decimals;
let amount_in_sol_decimals = (amount *
10u64.pow(SOL_DECIMALS as u32)) /
10u64.pow(token_decimals as u32);
let final_amount_in_sol = ((token_price.price *
(amount_in_sol_decimals as i64)) /
sol_price.price) as u64;
let decimals = SOL_DECIMALS - ctx.accounts.token_mint.decimals;
let amount_in_sol_decimals = amount * 10u64.pow(decimals as u32);
let amount_in_sol_decimals =
i64::try_from(amount_in_sol_decimals).unwrap();
let final_amount_in_sol = token_price.price *
amount_in_sol_decimals /
sol_price.price;
let final_amount_in_sol =
u64::try_from(final_amount_in_sol).unwrap();

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the thing is that the token decimals can be more than solana decimals so i guess we could do smtg like this then

let decimals = (SOL_DECIMALS as i64) - (ctx.accounts.token_mint.decimals as i64);
let amount_in_sol_decimals = if decimals < 0 {
     amount / 10u64.pow(abs(decimals))
} else {
     amount * 10u64.pow(decimals)
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, though prefer i64::from(...) to ... as i64. I also wonder if we should be concerned with rounding? I guess in this instance truncating is the correct approach.

Comment on lines -74 to +85
.find(|&&token_mint| token_mint == ctx.accounts.token_mint.key())
.enumerate()
.find_map(|(index, &token_mint)| {
if token_mint == ctx.accounts.token_mint.key() {
return Some(index);
}
None
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like you’re looking for position.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yes right.

let token_price_update = &ctx.accounts.token_price_update;
let sol_price_update = &ctx.accounts.sol_price_update;

let sol_price_feed_id = SOL_PRICE_FEED_ID.to_string();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why convert it to String?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the feed id from hex expects &string and if i convert it there then the compiler complains saying use of moved value.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what you want is:

        let token_feed_id = staking_params
            .token_oracle_addresses
            .get(token_index)
            .as_deref()
            .unwrap_or(SOL_PRICE_FEED_ID);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh ya i think deref is what was needed.

.get(token_index)
.unwrap_or(&sol_price_feed_id);

let final_amount_in_sol = if token_feed_id == &sol_price_feed_id {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sholudn’t this be !=?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yes sorry, my bad.

@mina86
Copy link
Collaborator

mina86 commented May 30, 2024

So what happens when the token price changes? Do we ever re-evaluate it?

@dhruvja
Copy link
Collaborator Author

dhruvja commented May 30, 2024

Well no. We store the calculated value during deposit and use the same value to unstake. The thing is the user will get the same number of tokens, the conversion is only for validator stake so i guess its prolly fine.

@mina86
Copy link
Collaborator

mina86 commented May 31, 2024

I’m just wondering about a case if someone deposits 1 FOO at a moment when it’s worth 1000 SOL. So we’re going to record it as 1000 SOL. But say month later it drops to 1 FOO = 1 SOL, but we will still treat this as worth 1000 SOL when calculating total stake and quorum.

@dhruvja
Copy link
Collaborator Author

dhruvja commented May 31, 2024

We would just enable stables for now else it's gonna get a bit tricky to update price everytime.

@mina86
Copy link
Collaborator

mina86 commented May 31, 2024

OK, that makes more sense. Though even then between 2021 and now price of SOL fluctuated from 10 USD to 250 USD. ;)

@dhruvja
Copy link
Collaborator Author

dhruvja commented Jun 13, 2024

ill keep this in draft since we wont be using it for v1.

@dhruvja dhruvja marked this pull request as draft June 13, 2024 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants