code.vegaprotocol.io/vega@v0.79.0/core/execution/common/amm_score_stake.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 common 17 18 import "code.vegaprotocol.io/vega/libs/num" 19 20 type AMMState struct { 21 stake num.Decimal // stake during epoch 22 score num.Decimal // running liquidity score 23 lastTick int64 // last time update 24 ltD num.Decimal // last time update, just in decimal because it saves on pointless conversions between int64 and num.Decimal 25 } 26 27 func newAMMState(count int64) *AMMState { 28 // prevent underflow 29 if count == 0 { 30 count = 1 31 } 32 return &AMMState{ 33 stake: num.DecimalZero(), 34 score: num.DecimalZero(), 35 lastTick: count - 1, 36 ltD: num.DecimalFromInt64(count - 1), 37 } 38 } 39 40 // UpdateTick is equivalent to calls to UpdateStake, UpdateScore, and IncrementTick. 41 func (a *AMMState) UpdateTick(stake, score num.Decimal) { 42 tick := a.ltD.Add(num.DecimalOne()) 43 a.stake = a.ltD.Mul(a.stake).Add(stake).Div(tick) 44 a.score = a.ltD.Mul(a.score).Add(score).Div(tick) 45 a.lastTick++ 46 a.ltD = a.ltD.Add(num.DecimalOne()) 47 } 48 49 // UpdateStake updates the time-weighted average stake during epoch. 50 func (a *AMMState) UpdateStake(stake num.Decimal) { 51 tick := a.ltD.Add(num.DecimalOne()) 52 // ((current_tick - 1) * old_stake + new_stake)/current_tick 53 // ((1 * 100) + 100)/ 2 == 100, checks out 54 a.stake = a.ltD.Mul(a.stake).Add(stake).Div(tick) 55 } 56 57 // UpdateScore updates the current epoch score. 58 func (a *AMMState) UpdateScore(score num.Decimal) { 59 tick := a.ltD.Add(num.DecimalOne()) 60 // ((current_tick - 1) * old_score + new_score)/current_tick 61 // (( 2 * 50 ) + 200) / 3 = 100, checks out 62 a.score = a.ltD.Mul(a.score).Add(score).Div(tick) 63 } 64 65 // IncrementTick increments the internal tick/time counter. 66 func (a *AMMState) IncrementTick() { 67 a.lastTick++ 68 a.ltD.Add(num.DecimalOne()) 69 } 70 71 // StartEpoch resets the internal tick counter, ready for the new epoch to start. 72 func (a *AMMState) StartEpoch() { 73 a.lastTick = 0 74 a.ltD = num.DecimalZero() 75 }