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

feat(auction): Auction allows vaults to specify an amount to raise #7239

Merged
merged 11 commits into from
Mar 30, 2023

Conversation

Chris-Hibbert
Copy link
Contributor

closes: #6952

Description

The Auctioneer allows providers of collateral to specify a target amount to raise. It's specified in an offerArg when exercising a deposit invitation as { toRaise: amount }. There's no guarantee that precisely this amount will be raised: there might not be enough bids, or others might have deposited different amounts with different payout ratios. But when it can, the auction will stop when it reaches that amount, and not sell more collateral past that point.

Reviewers might want to scan the tests to see how all the stats are updated.

Security Considerations

Nothing special.

Scaling Considerations

No change in concerns for auction or vaults.

Documentation Considerations

This is visible to the UI for depositors. It doesn't impact bidders in the auction.

Testing Considerations

Tests were added for all the major branches. It will be good to have people exercising the code and trying many variations.

@Chris-Hibbert Chris-Hibbert added Inter-protocol Overarching Inter Protocol Vaults VaultFactor (née Treasury) labels Mar 24, 2023
@Chris-Hibbert Chris-Hibbert self-assigned this Mar 24, 2023
@Chris-Hibbert Chris-Hibbert requested a review from turadg March 24, 2023 23:13
@codecov
Copy link

codecov bot commented Mar 24, 2023

Codecov Report

Merging #7239 (3f9059a) into master (5ba5f7b) will increase coverage by 0.05%.
The diff coverage is 79.31%.

❗ Current head 3f9059a differs from pull request most recent head 9bf5b13. Consider uploading reports for the commit 9bf5b13 to get more accurate results

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #7239      +/-   ##
==========================================
+ Coverage   70.94%   70.99%   +0.05%     
==========================================
  Files         451      450       -1     
  Lines       86095    86359     +264     
  Branches        3        3              
==========================================
+ Hits        61081    61313     +232     
- Misses      24948    24978      +30     
- Partials       66       68       +2     
Impacted Files Coverage Δ
packages/inter-protocol/src/auction/auctionBook.js 69.82% <37.62%> (-3.47%) ⬇️
packages/inter-protocol/src/auction/auctioneer.js 61.70% <94.56%> (+25.92%) ⬆️

... and 3 files with indirect coverage changes

Impacted file tree graph

@datadog-full-agoric
Copy link

datadog-full-agoric bot commented Mar 24, 2023

Datadog Report

Branch report: 6952-auctionTargeRaise
Commit report: b87f62f

agoric-sdk: 0 Failed, 0 New Flaky, 3490 Passed, 47 Skipped, 24m 32.59s Wall Time

@Chris-Hibbert Chris-Hibbert force-pushed the 6952-auctionTargeRaise branch from 767699e to 7e6fb40 Compare March 25, 2023 00:10
Copy link
Member

@turadg turadg left a comment

Choose a reason for hiding this comment

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

Did a pass for readability. I'll take another review the distributeProportionalSharesWithLimits logic closely

*/
addAssets(assetAmount, sourceSeat) {
addAssets(assetAmount, sourceSeat, toRaise) {
Copy link
Member

Choose a reason for hiding this comment

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

"raise" is ambiguous between between "increase a quantity" (raise the bet) and "transact to reach a capital threshold" (raise $1m for charity).

Is there another term that's unambiguous? Maybe "collect". Also, I see the "total" in state goes down, which seems less like a total and more like "remaining".

There's also the matter of the optionality of the state. If it's not defined, it means "collect/raise as much as possible", yes?

Consider toCollect for the param and collectionLimit for the state. The limit goes up by toCollect and down with each sell.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I kind of like remainingCollectionTarget, though remainingTarget is a close second. I couldn't find a good replacement for "Collection", and I agree that "remaining" is critical. "target" seems important, to remind readers that it's only a goal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I ended up with totalProceedsGoal, saving a few characters here and there, with losing clarity, I think.

@Chris-Hibbert Chris-Hibbert force-pushed the 6952-auctionTargeRaise branch from 17e5f41 to dbc0fd4 Compare March 28, 2023 20:59
@Chris-Hibbert Chris-Hibbert requested a review from turadg March 28, 2023 22:58
Copy link
Member

@turadg turadg left a comment

Choose a reason for hiding this comment

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

looking good.

deposits.push({
seat,
amount: collateral.make(BigInt(rawDeposits[i].deposit)),
goal: collect ? currency.make(BigInt(collect)) : null,
Copy link
Member

Choose a reason for hiding this comment

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

collect was to match what I had proposed for the property of the deposit element type. To match the type now:

Suggested change
goal: collect ? currency.make(BigInt(collect)) : null,
goal: goal ? currency.make(BigInt(goal)) : null,

);

// rounding happens because the value of collateral is negligible.
const transferSharing2000 = /** @type {Array<[bigint, bigint]>} */ ([
Copy link
Member

Choose a reason for hiding this comment

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

these one-off fixtures could be inlined. The reason I made the const was to convey that each of the cases using it has the same transfers.

Comment on lines 641 to 642
await driver.advanceTo(170n);
await eventLoopIteration();
Copy link
Member

Choose a reason for hiding this comment

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

I forget, if we make advanceTo also await the event loop something else breaks?

WDYT of having an option like…

Suggested change
await driver.advanceTo(170n);
await eventLoopIteration();
await driver.advanceTo(170n, 'andTurn');

incidental, out of scope

@@ -175,7 +175,7 @@ const makeAuctionDriver = async (t, customTerms, params = defaultParams) => {
return E(zoe).offer(bidInvitation, proposal, payment, harden(offerArgs));
};

const depositCollateral = async (collateralAmount, issuerKit) => {
const depositCollateral = async (collateralAmount, issuerKit, limit) => {
Copy link
Member

Choose a reason for hiding this comment

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

limit name is confusing since it contains {goal}. I think this is also more correct,

Suggested change
const depositCollateral = async (collateralAmount, issuerKit, limit) => {
const depositCollateral = async (collateralAmount, issuerKit, offerArgs) => {

/**
* @param {Pick<IssuerKit<'nat'>, 'brand' | 'issuer' | 'mint'>} issuerKit
* @param {Amount<'nat'>} collateralAmount
* @param {undefined | { goal: Amount<'nat'> }} limit
Copy link
Member

Choose a reason for hiding this comment

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

ditto re: name and our style is to express optionality with brackets (per JSDoc)

Suggested change
* @param {undefined | { goal: Amount<'nat'> }} limit
* @param {{ goal: Amount<'nat'> }} [offerArgs]

const currencyLimit = totalProceedsGoal
? AmountMath.min(totalProceedsGoal, initialCurrencyTarget)
: initialCurrencyTarget;
const isRaiseBounded =
Copy link
Member

Choose a reason for hiding this comment

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

"bounded" might not be worth a new term.

Suggested change
const isRaiseBounded =
const isRaiseLimited =

if (proceedsGoal || totalProceedsGoal) {
this.state.totalProceedsGoal = ceilMultiplyBy(
AmountMath.add(curCollateral, assetAmount),
// @ts-expect-error calcTargetRatio always returns a ratio here
Copy link
Member

Choose a reason for hiding this comment

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

let's ensure that statically so this suppression isn't needed. I think a throw Fail at the end of calcTargetRatio would do it

collateralValue,
);
// The share for those who specified a limit is proportional to their
// collateral. ceiling because it's a lower limit on the restrictive branch
Copy link
Member

Choose a reason for hiding this comment

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

thx for documenting why ceiling

@@ -1071,6 +1037,14 @@ export const prepareVaultManagerKit = (
/** @type {import('@agoric/zoe/src/contractSupport/atomicTransfer.js').TransferPart[]} */
const transfers = [];
let liquidated = 0;
/** @type {MapStore<string, Vault>} */
const vaultsToReinstate = makeScalarMapStore();
Copy link
Member

Choose a reason for hiding this comment

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

between here and when these entries are read, there can be failure that exits the function. That in-between should be in a try/catch so execution continues to the reinstating and publishing.

@@ -862,11 +856,11 @@ export const prepareVaultManagerKit = (
userSeatPromise,
]);

trace(`VM LiqV after long wait`, proceeds);
trace(`LiqV after long wait`, proceeds);
Copy link
Member

Choose a reason for hiding this comment

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

I notice that this function is async but the bulk of it is sync from here on. It would be easier to maintain and follow if here down was in its own sync function. e.g. helper.liquidateFromAuction.

not a blocker

Copy link
Member

@turadg turadg left a comment

Choose a reason for hiding this comment

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

Approving based on discussion about what's pending push

@Chris-Hibbert Chris-Hibbert added the automerge:squash Automatically squash merge label Mar 29, 2023
@Chris-Hibbert Chris-Hibbert force-pushed the 6952-auctionTargeRaise branch from 9eb4b93 to 3f9059a Compare March 30, 2023 00:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:squash Automatically squash merge Inter-protocol Overarching Inter Protocol Vaults VaultFactor (née Treasury)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Auction targets a specific amount of IST to raise; returns excess collateral to vault holders
2 participants