Skip to content

restaking: Restaking oracle#334

Draft
dhruvja wants to merge 4 commits intomasterfrom
restaking-oracle
Draft

restaking: Restaking oracle#334
dhruvja wants to merge 4 commits intomasterfrom
restaking-oracle

Conversation

@dhruvja
Copy link
Contributor

@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.

@dhruvja dhruvja requested a review from mina86 May 29, 2024 16:45
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
Contributor

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
Contributor 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
Contributor

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
Contributor

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
Contributor 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
Contributor

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
Contributor 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
Contributor

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
Contributor 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
Contributor

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
Contributor 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
Contributor

mina86 commented May 30, 2024

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

@dhruvja
Copy link
Contributor 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
Contributor

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
Contributor 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
Contributor

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
Contributor 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