-
Notifications
You must be signed in to change notification settings - Fork 57
Fix rounding drift by reading adapter's live share balance #645
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,10 @@ pub trait YieldAdapterInterface { | |
| fn deposit(env: Env, amount: i128) -> i128; | ||
| fn withdraw(env: Env, shares: i128, recipient: Address) -> i128; | ||
| fn total_assets(env: Env) -> i128; | ||
| /// The adapter's current protocol-share balance, read from the underlying | ||
| /// protocol's own ledger rather than self-tracked. Lets the vault reconcile | ||
| /// ADPT_SH instead of estimating its decrements. | ||
| fn total_shares(env: Env) -> i128; | ||
| /// Refreshes the adapter's cached total_assets before it is read for | ||
| /// deposit/withdraw pricing. A no-op for adapters that already price | ||
| /// live on every call. | ||
|
|
@@ -241,7 +245,7 @@ impl MeridianVault { | |
| .set(&TOTAL_SH, &(total_shares + shares_to_mint)); | ||
| env.storage() | ||
| .instance() | ||
| .set(&ADPT_SH, &(total_adapter_shares + adapter_shares)); | ||
| .set(&ADPT_SH, &AdapterClient::new(&env, &adapter_addr).total_shares()); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that |
||
|
|
||
| // Stamp the entry time on the caller's first deposit; top-ups keep | ||
| // the original time. Keyed off whether an entry record exists rather | ||
|
|
@@ -354,7 +358,7 @@ impl MeridianVault { | |
| .set(&TOTAL_SH, &(total_shares - shares)); | ||
| env.storage() | ||
| .instance() | ||
| .set(&ADPT_SH, &(total_adapter_shares - adapter_shares_to_burn)); | ||
| .set(&ADPT_SH, &AdapterClient::new(&env, &adapter_addr).total_shares()); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| let remaining = caller_shares - shares; | ||
|
|
||
|
|
@@ -809,6 +813,10 @@ mod tests { | |
| mock_total_assets(&env, &usdc) | ||
| } | ||
|
|
||
| pub fn total_shares(env: Env) -> i128 { | ||
| env.storage().instance().get(&MA_SH).unwrap_or(0) | ||
| } | ||
|
|
||
| pub fn refresh(_env: Env) { | ||
| // No-op: MockAdapter already prices total_assets() live. | ||
| } | ||
|
|
@@ -868,6 +876,10 @@ mod tests { | |
| mock_total_assets(&env, &usdc) | ||
| } | ||
|
|
||
| pub fn total_shares(env: Env) -> i128 { | ||
| env.storage().instance().get(&LA_SH).unwrap_or(0) | ||
| } | ||
|
|
||
| pub fn refresh(_env: Env) { | ||
| // No-op: LossyMockAdapter already prices total_assets() live. | ||
| } | ||
|
|
@@ -919,6 +931,10 @@ mod tests { | |
| mock_total_assets(&env, &usdc) | ||
| } | ||
|
|
||
| pub fn total_shares(env: Env) -> i128 { | ||
| env.storage().instance().get(&ZS_SH).unwrap_or(0) | ||
| } | ||
|
|
||
| pub fn refresh(_env: Env) { | ||
| // No-op: ZeroShareMockAdapter already prices total_assets() live. | ||
| } | ||
|
|
@@ -994,6 +1010,10 @@ mod tests { | |
| env.storage().instance().get(&CM_TOTAL).unwrap_or(0) | ||
| } | ||
|
|
||
| pub fn total_shares(env: Env) -> i128 { | ||
| env.storage().instance().get(&CM_SH).unwrap_or(0) | ||
| } | ||
|
|
||
| pub fn refresh(env: Env) { | ||
| // USDC address is always set in initialize(), so this is safe. | ||
| let usdc: Address = | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This docstring reads as broken prose now: "This adapter relies on the standard panic handler: bubbling by discarding the error preserves this function's pre-existing fail-loud behaviour..." "bubbling" and "discarding" are opposites, and the sentence doesn't parse. Looks like the new first three lines were spliced onto the tail of the old docstring without removing the leftover fragment. Please rewrite this as one coherent comment.