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  }