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

fix(fast-usdc): consider encumberedBalance in withdrawCalc #10870

Merged
merged 2 commits into from
Jan 23, 2025
Merged

Conversation

dckc
Copy link
Member

@dckc dckc commented Jan 21, 2025

closes: #10856

Description

  • add contract test to confirm the bug
  • fix pool-share-math; update tests
  • update liquidity-pool exo

Security Considerations

Prevents contract from becoming unavailable due to an inconsistent state.

Scaling / Documentation Considerations

n/a

Testing Considerations

  • added a contract test
  • added a pool-share-math unit test

Upgrade Considerations

not yet deployed

Copy link

cloudflare-workers-and-pages bot commented Jan 21, 2025

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: daa6c38
Status: ✅  Deploy successful!
Preview URL: https://aa645b5c.agoric-sdk.pages.dev
Branch Preview URL: https://dc-fu-wd.agoric-sdk.pages.dev

View logs

@dckc dckc changed the title fix(fast-usdc): withdraw all liquidity while ADVANCING fix(fast-usdc): consider encumberedBalance in withdrawCalc Jan 22, 2025
@dckc dckc marked this pull request as ready for review January 22, 2025 05:16
@dckc dckc requested a review from a team as a code owner January 22, 2025 05:16
@dckc dckc force-pushed the dc-fu-wd branch 2 times, most recently from 893ff4b to 3c74e53 Compare January 22, 2025 05:21
@@ -112,6 +152,8 @@ export const withdrawCalc = (shareWorth, { give, want }) => {
const { denominator: sharesOutstanding, numerator: poolBalance } = shareWorth;
!isGTE(want.USDC, poolBalance) ||
Fail`cannot withdraw ${q(want.USDC)}; only ${q(poolBalance)} in pool`;
isGTE(unencumberedBalance, want.USDC) ||
Fail`cannot withdraw ${q(want.USDC)}; ${q(encumberedBalance)} is in use; stand by for pool to return to ${q(poolBalance)}`;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure what to do about this but I'm pretty sure these Amounts show up as [an Object] or some such thing on the user level, which I assume this messaging is intended for, so maybe render the values instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

q(...) renders them. for example:

RemoteError(error:captp:far-zoeTest#20001)#3: cannot withdraw ***"brand":"[Alleged: USDC brand]","value":"[7000000n]"***; ***"brand":"[Alleged: USDC brand]","value":"[5879999n]"*** is in use; stand by for pool to return to ***"brand":"[Alleged: USDC brand]","value":"[10000001n]"***


// 3. Alice proposes to withdraw 7 USDC
await t.throwsAsync(E(alice).withdraw(t, 0.7), {
message: /cannot withdraw .* in use; stand by/,
Copy link
Contributor

Choose a reason for hiding this comment

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

Related to my comment above, possibly make this expected string more explicit

Copy link
Member Author

Choose a reason for hiding this comment

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

OK.

I'm generally reluctant to commit to specific error messages in our API, but don't suppose I have a solid justification.

@@ -72,7 +76,7 @@ test('withdrawal after deposit OK', t => {
});
mustMatch(proposal, shapes.withdraw);

const actual = withdrawCalc(state1, proposal);
const actual = withdrawCalc(state1, proposal, pDep.give);
Copy link
Contributor

Choose a reason for hiding this comment

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

I know this already existed but I'm not sure what pDep means... "proposal for deposit"? It's not immediately clear what the connection is between that and the pool allocation. Could we infer it from shareWorth instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's not immediately clear what the connection is between [proposal for deposit] and the pool allocation.

The connection is that proposal.give is what the deposit handler transfers into the pool:

zcf.atomicRearrange(
harden([
// zoe guarantees lp has proposal.give allocated
[lp, poolSeat, proposal.give],

Could we infer it from shareWorth instead?

Not quite; shareWorth.numerator is off by 1E-6 USDC so that it never goes to zero. It's a bit of a design wart, but I haven't figured out a better way.

@dckc dckc requested a review from samsiegart January 23, 2025 17:40
@dckc dckc added the automerge:rebase Automatically rebase updates, then merge label Jan 23, 2025
dckc added 2 commits January 23, 2025 18:48
 - advise caller to stand by for pool to be replenished
 - pass pool allocation, encumbered balance to withdrawCalc
   - push checkPoolBalance down into pool-share-math
     - take allocation rather than stateful seat
   - push dust calculations down to pool-share-math
@mergify mergify bot merged commit 2af926f into master Jan 23, 2025
83 checks passed
@mergify mergify bot deleted the dc-fu-wd branch January 23, 2025 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

withdraw calculations don't take encumbered balance into account
2 participants