Skip to content

Commit

Permalink
feat: protocol automated purchase auctions
Browse files Browse the repository at this point in the history
  • Loading branch information
ze97286 committed Sep 21, 2024
1 parent 3a48987 commit 924c2e2
Show file tree
Hide file tree
Showing 60 changed files with 12,728 additions and 8,534 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

- [11644](https://github.com/vegaprotocol/vega/issues/11644) - `liveOnly` flag has been added to the `AMM` API to show only active `AMMs`.
- [11519](https://github.com/vegaprotocol/vega/issues/11519) - Add fees to position API types.

- [11685](https://github.com/vegaprotocol/vega/issues/11685) - Automated purchase support added.

### 🐛 Fixes

- [11672](https://github.com/vegaprotocol/vega/issues/11672) - Add missing fees in GraphQL bindings.
Expand Down
123 changes: 123 additions & 0 deletions commands/proposal_submission.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"code.vegaprotocol.io/vega/libs/num"
"code.vegaprotocol.io/vega/protos/vega"
protoTypes "code.vegaprotocol.io/vega/protos/vega"
types "code.vegaprotocol.io/vega/protos/vega"
vegapb "code.vegaprotocol.io/vega/protos/vega"
commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
datapb "code.vegaprotocol.io/vega/protos/vega/data/v1"
Expand Down Expand Up @@ -216,6 +217,8 @@ func checkProposalChanges(terms *protoTypes.ProposalTerms) Errors {
errs.Merge(checkVolumeDiscountProgram(terms, c))
case *protoTypes.ProposalTerms_UpdateVolumeRebateProgram:
errs.Merge(checkVolumeRebateProgram(terms, c))
case *protoTypes.ProposalTerms_NewProtocolAutomatedPurchase:
errs.Merge(checkAutomatedPurchaseConfig(c))
default:
return errs.FinalAddForProperty("proposal_submission.terms.change", ErrIsNotValid)
}
Expand Down Expand Up @@ -411,6 +414,126 @@ func checkReferralProgramChanges(changes *vegapb.ReferralProgramChanges, enactme
return errs
}

func checkAutomatedPurchaseConfig(newAutoPurchase *vegapb.ProposalTerms_NewProtocolAutomatedPurchase) Errors {
validAccountTypes := map[types.AccountType]struct{}{}
validAccountTypes[types.AccountType_ACCOUNT_TYPE_GLOBAL_INSURANCE] = struct{}{}
validAccountTypes[types.AccountType_ACCOUNT_TYPE_GLOBAL_REWARD] = struct{}{}
validAccountTypes[types.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY] = struct{}{}
validAccountTypes[types.AccountType_ACCOUNT_TYPE_BUY_BACK_FEES] = struct{}{}

errs := NewErrors()
if newAutoPurchase.NewProtocolAutomatedPurchase == nil {
return errs.FinalAddForProperty("proposal_submission.terms.change.automated_purchase_config", ErrIsRequired)
}
if newAutoPurchase.NewProtocolAutomatedPurchase.Changes == nil {
return errs.FinalAddForProperty("proposal_submission.terms.change.automated_purchase_config.changes", ErrIsRequired)
}

change := newAutoPurchase.NewProtocolAutomatedPurchase.Changes
if len(change.From) == 0 {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.from", ErrIsRequired)
}

// TODO @charlie check which account types are valid for this
if change.FromAccountType == protoTypes.AccountType_ACCOUNT_TYPE_UNSPECIFIED {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.from_account_type", ErrIsRequired)
}
if _, ok := validAccountTypes[change.FromAccountType]; !ok {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.from_account_type", ErrIsNotValid)
}
if change.ToAccountType == protoTypes.AccountType_ACCOUNT_TYPE_UNSPECIFIED {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.to_account_type", ErrIsRequired)
}
if _, ok := validAccountTypes[change.ToAccountType]; !ok {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.to_account_type", ErrIsNotValid)
}
if len(change.MarketId) == 0 {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.market_id", ErrIsRequired)
}
if change.PriceOracle == nil {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.price_oracle", ErrIsRequired)
} else {
errs.Merge(checkDataSourceSpec(change.PriceOracle, "data_spec_for_price_oracle", "proposal_submission.terms.change.automated_purchase_config", false))
}
if len(change.OracleOffsetFactor) == 0 {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.oracle_offset_factor", ErrIsRequired)
} else {
d, err := num.DecimalFromString(change.OracleOffsetFactor)
if err != nil {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.oracle_offset_factor", ErrNotAValidFloat)
} else if !d.IsPositive() {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.oracle_offset_factor", ErrMustBePositive)
}
}
if change.AuctionSchedule == nil {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.auction_schedule", ErrIsRequired)
} else {
switch tp := change.AuctionSchedule.SourceType.(type) {
case *vegapb.DataSourceDefinition_External:
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.auction_schedule", fmt.Errorf("auction schedule must be an internal time trigger"))
case *vegapb.DataSourceDefinition_Internal:
switch tp.Internal.SourceType.(type) {
case *vegapb.DataSourceDefinitionInternal_Time:
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.auction_schedule", fmt.Errorf("auction schedule must be an internal time trigger"))
default:
}
}
errs.Merge(checkDataSourceSpec(change.AuctionSchedule, "data_spec_for_auction_schedule", "proposal_submission.terms.change.automated_purchase_config", false))
}
if len(change.AuctionDuration) == 0 {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.auction_duration", ErrIsRequired)
} else {
if _, err := time.ParseDuration(change.AuctionDuration); err != nil {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.auction_duration", fmt.Errorf("must be a valid duration"))
}
}

if change.AuctionVolumeSnapshotSchedule == nil {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.auction_volume_snapshot_schedule", ErrIsRequired)
} else {
switch tp := change.AuctionVolumeSnapshotSchedule.SourceType.(type) {
case *vegapb.DataSourceDefinition_External:
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.auction_volume_snapshot_schedule", fmt.Errorf("auction snapshot volume schedule must be an internal time trigger"))
case *vegapb.DataSourceDefinition_Internal:
switch tp.Internal.SourceType.(type) {
case *vegapb.DataSourceDefinitionInternal_Time:
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.auction_volume_snapshot_schedule", fmt.Errorf("auction snapshot volume schedule must be an internal time trigger"))
default:
}
}
errs.Merge(checkDataSourceSpec(change.AuctionSchedule, "data_spec_for_auction_volume_snapshot_schedule", "proposal_submission.terms.change.automated_purchase_config", false))
}

var min, max *num.Uint
if len(change.MinimumAuctionSize) == 0 {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.minimum_auction_size", ErrIsRequired)
} else {
minSize, overflow := num.UintFromString(change.MinimumAuctionSize, 10)
if overflow || minSize.IsZero() || minSize.IsNegative() {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.minimum_auction_size", ErrMustBePositive)
} else {
min = minSize
}
}
if len(change.MaximumAuctionSize) == 0 {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.maximum_auction_size", ErrIsRequired)
} else {
maxSize, overflow := num.UintFromString(change.MinimumAuctionSize, 10)
if overflow || maxSize.IsZero() || maxSize.IsNegative() {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.maximum_auction_size", ErrMustBePositive)
} else {
max = maxSize
}
}
if min.GT(max) {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.maximum_auction_size", fmt.Errorf("must be greater than or equal to minimum_auction_size"))
}
if change.ExpiryTimestamp < 0 {
errs.AddForProperty("proposal_submission.terms.change.automated_purchase_config.expiry_timestamp", ErrMustBePositiveOrZero)
}
return errs
}

func checkVolumeRebateProgram(terms *vegapb.ProposalTerms, change *vegapb.ProposalTerms_UpdateVolumeRebateProgram) Errors {
errs := NewErrors()
if change.UpdateVolumeRebateProgram == nil {
Expand Down
Loading

0 comments on commit 924c2e2

Please sign in to comment.