-
Notifications
You must be signed in to change notification settings - Fork 233
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
Conversation
Codecov Report
Additional details and impacted files@@ 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
|
Datadog ReportBranch report: ✅ |
767699e
to
7e6fb40
Compare
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.
Did a pass for readability. I'll take another review the distributeProportionalSharesWithLimits
logic closely
*/ | ||
addAssets(assetAmount, sourceSeat) { | ||
addAssets(assetAmount, sourceSeat, toRaise) { |
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.
"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.
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.
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.
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.
I ended up with totalProceedsGoal
, saving a few characters here and there, with losing clarity, I think.
test-proportionalDist covers all of distributeProportionalSharesWithLimits
17e5f41
to
dbc0fd4
Compare
Other miscellaneous minor renamings and refactorings.
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.
looking good.
deposits.push({ | ||
seat, | ||
amount: collateral.make(BigInt(rawDeposits[i].deposit)), | ||
goal: collect ? currency.make(BigInt(collect)) : null, |
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.
collect
was to match what I had proposed for the property of the deposit
element type. To match the type now:
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]>} */ ([ |
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.
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.
await driver.advanceTo(170n); | ||
await eventLoopIteration(); |
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.
I forget, if we make advanceTo
also await the event loop something else breaks?
WDYT of having an option like…
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) => { |
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.
limit
name is confusing since it contains {goal}
. I think this is also more correct,
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 |
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.
ditto re: name and our style is to express optionality with brackets (per JSDoc)
* @param {undefined | { goal: Amount<'nat'> }} limit | |
* @param {{ goal: Amount<'nat'> }} [offerArgs] |
const currencyLimit = totalProceedsGoal | ||
? AmountMath.min(totalProceedsGoal, initialCurrencyTarget) | ||
: initialCurrencyTarget; | ||
const isRaiseBounded = |
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.
"bounded" might not be worth a new term.
const isRaiseBounded = | |
const isRaiseLimited = |
if (proceedsGoal || totalProceedsGoal) { | ||
this.state.totalProceedsGoal = ceilMultiplyBy( | ||
AmountMath.add(curCollateral, assetAmount), | ||
// @ts-expect-error calcTargetRatio always returns a ratio here |
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.
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 |
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.
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(); |
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.
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); |
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.
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
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.
Approving based on discussion about what's pending push
9eb4b93
to
3f9059a
Compare
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.