code.vegaprotocol.io/vega@v0.79.0/core/integration/steps/amm_submission.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package steps 17 18 import ( 19 "context" 20 "fmt" 21 22 "code.vegaprotocol.io/vega/core/types" 23 "code.vegaprotocol.io/vega/libs/num" 24 "code.vegaprotocol.io/vega/libs/ptr" 25 26 "github.com/cucumber/godog" 27 ) 28 29 func PartiesSubmitTheFollowingAMMs(exec Execution, table *godog.Table) error { 30 ctx := context.Background() 31 for _, r := range parseSubmitAMMTable(table) { 32 row := ammRow{ 33 r: r, 34 } 35 fail, eStr := row.err() 36 if err := exec.SubmitAMM(ctx, row.toSubmission()); err != nil { 37 if !fail { 38 return err 39 } 40 if err.Error() != eStr { 41 return fmt.Errorf("expected error %s, instead got: %s (%v)", eStr, err.Error(), err) 42 } 43 } 44 } 45 return nil 46 } 47 48 func PartiesAmendTheFollowingAMMs(exec Execution, table *godog.Table) error { 49 ctx := context.Background() 50 for _, r := range parseAmendAMMTable(table) { 51 row := ammRow{ 52 r: r, 53 isAmend: true, 54 } 55 fail, eStr := row.err() 56 if err := exec.AmendAMM(ctx, row.toAmendment()); err != nil { 57 if !fail { 58 return err 59 } 60 if err.Error() != eStr { 61 return fmt.Errorf("expected error %s, instead got: %s (%v)", eStr, err.Error(), err) 62 } 63 } 64 } 65 return nil 66 } 67 68 func PartiesCancelTheFollowingAMMs(exec Execution, table *godog.Table) error { 69 ctx := context.Background() 70 for _, r := range parseCancelAMMTable(table) { 71 row := ammRow{ 72 r: r, 73 } 74 fail, eStr := row.err() 75 if err := exec.CancelAMM(ctx, row.toCancel()); err != nil { 76 if !fail { 77 return err 78 } 79 if err.Error() != eStr { 80 return fmt.Errorf("expected error %s, instead got: %s (%v)", eStr, err.Error(), err) 81 } 82 } 83 } 84 return nil 85 } 86 87 func parseSubmitAMMTable(table *godog.Table) []RowWrapper { 88 return StrictParseTable(table, []string{ 89 "party", // str 90 "market id", // str 91 "amount", // uint 92 "slippage", // dec 93 "base", // uint 94 "proposed fee", // dec 95 }, []string{ 96 "lower bound", // uint 97 "upper bound", // uint 98 "lower leverage", // dec 99 "upper leverage", // dec 100 "data source id", 101 "minimum price change trigger", 102 "error", 103 }) 104 } 105 106 func parseAmendAMMTable(table *godog.Table) []RowWrapper { 107 return StrictParseTable(table, []string{ 108 "party", // str 109 "market id", // str 110 "slippage", // dec 111 }, []string{ 112 "proposed fee", // dec 113 "amount", // uint 114 "base", // uint 115 "lower bound", // uint 116 "upper bound", // uint 117 "lower leverage", // dec 118 "upper leverage", // dec 119 "data source id", 120 "minimum price change trigger", 121 "error", 122 }) 123 } 124 125 func parseCancelAMMTable(table *godog.Table) []RowWrapper { 126 return StrictParseTable(table, []string{ 127 "party", 128 "market id", 129 "method", 130 }, []string{ 131 "error", 132 }) 133 } 134 135 type ammRow struct { 136 r RowWrapper 137 isAmend bool 138 } 139 140 func (a ammRow) toSubmission() *types.SubmitAMM { 141 if !a.r.HasColumn("lower bound") && !a.r.HasColumn("upper bound") { 142 panic("required at least one upper bound and lower bound") 143 } 144 145 return &types.SubmitAMM{ 146 AMMBaseCommand: types.AMMBaseCommand{ 147 MarketID: a.marketID(), 148 Party: a.party(), 149 SlippageTolerance: a.slippage(), 150 ProposedFee: a.proposedFee(), 151 MinimumPriceChangeTrigger: a.minimumPriceChangeTrigger(), 152 }, 153 CommitmentAmount: a.amount(), 154 Parameters: &types.ConcentratedLiquidityParameters{ 155 Base: a.base(), 156 LowerBound: a.lowerBound(), 157 UpperBound: a.upperBound(), 158 LeverageAtLowerBound: a.lowerLeverage(), 159 LeverageAtUpperBound: a.upperLeverage(), 160 DataSourceID: a.dataSourceID(), 161 }, 162 } 163 } 164 165 func (a ammRow) toAmendment() *types.AmendAMM { 166 ret := &types.AmendAMM{ 167 AMMBaseCommand: types.AMMBaseCommand{ 168 MarketID: a.marketID(), 169 Party: a.party(), 170 SlippageTolerance: a.slippage(), 171 ProposedFee: a.proposedFee(), 172 MinimumPriceChangeTrigger: a.minimumPriceChangeTrigger(), 173 }, 174 } 175 if a.r.HasColumn("amount") { 176 ret.CommitmentAmount = a.amount() 177 } 178 params := &types.ConcentratedLiquidityParameters{ 179 DataSourceID: a.dataSourceID(), 180 } 181 paramSet := false 182 if a.r.HasColumn("base") { 183 params.Base = a.base() 184 paramSet = true 185 } 186 if a.r.HasColumn("lower bound") { 187 params.LowerBound = a.lowerBound() 188 paramSet = true 189 } 190 if a.r.HasColumn("upper bound") { 191 params.UpperBound = a.upperBound() 192 paramSet = true 193 } 194 if a.r.HasColumn("lower leverage") { 195 params.LeverageAtLowerBound = a.lowerLeverage() 196 paramSet = true 197 } 198 if a.r.HasColumn("upper leverage") { 199 params.LeverageAtUpperBound = a.upperLeverage() 200 paramSet = true 201 } 202 if paramSet { 203 ret.Parameters = params 204 } 205 return ret 206 } 207 208 func (a ammRow) toCancel() *types.CancelAMM { 209 return &types.CancelAMM{ 210 MarketID: a.marketID(), 211 Party: a.party(), 212 Method: a.method(), 213 } 214 } 215 216 func (a ammRow) party() string { 217 return a.r.MustStr("party") 218 } 219 220 func (a ammRow) marketID() string { 221 return a.r.MustStr("market id") 222 } 223 224 func (a ammRow) proposedFee() num.Decimal { 225 if !a.isAmend { 226 return a.r.MustDecimal("proposed fee") 227 } 228 229 if a.r.HasColumn("proposed fee") { 230 return a.r.MustDecimal("proposed fee") 231 } 232 return num.DecimalZero() 233 } 234 235 func (a ammRow) amount() *num.Uint { 236 return a.r.MustUint("amount") 237 } 238 239 func (a ammRow) slippage() num.Decimal { 240 return a.r.MustDecimal("slippage") 241 } 242 243 func (a ammRow) base() *num.Uint { 244 return a.r.MustUint("base") 245 } 246 247 func (a ammRow) lowerBound() *num.Uint { 248 if !a.r.HasColumn("lower bound") { 249 return nil 250 } 251 return a.r.MustUint("lower bound") 252 } 253 254 func (a ammRow) upperBound() *num.Uint { 255 if !a.r.HasColumn("upper bound") { 256 return nil 257 } 258 return a.r.MustUint("upper bound") 259 } 260 261 func (a ammRow) dataSourceID() *string { 262 if !a.r.HasColumn("data source id") { 263 return nil 264 } 265 return ptr.From(a.r.Str("data source id")) 266 } 267 268 func (a ammRow) minimumPriceChangeTrigger() num.Decimal { 269 if !a.r.HasColumn("minimum price change trigger") { 270 return num.DecimalZero() 271 } 272 return a.r.MustDecimal("minimum price change trigger") 273 } 274 275 func (a ammRow) lowerLeverage() *num.Decimal { 276 if !a.r.HasColumn("lower leverage") { 277 return nil 278 } 279 return ptr.From(a.r.MustDecimal("lower leverage")) 280 } 281 282 func (a ammRow) upperLeverage() *num.Decimal { 283 if !a.r.HasColumn("upper leverage") { 284 return nil 285 } 286 return ptr.From(a.r.MustDecimal("upper leverage")) 287 } 288 289 func (a ammRow) method() types.AMMCancellationMethod { 290 if !a.r.HasColumn("method") { 291 return types.AMMCancellationMethodUnspecified 292 } 293 return a.r.MustAMMCancelationMethod("method") 294 } 295 296 func (a ammRow) err() (bool, string) { 297 if !a.r.HasColumn("error") { 298 return false, "" 299 } 300 str := a.r.MustStr("error") 301 return true, str 302 }