MCPcopy
hub / github.com/canopy-network/canopy / HandleBatchDeposit

Method HandleBatchDeposit

fsm/dex.go:456–522  ·  view source on GitHub ↗

HandleBatchDeposit() handles local/remote liquidity deposits. local=true: x=local pool (actual token movement), y=counter mirror. local=false: x=counter mirror, y=local pool.

(batch *lib.DexBatch, chainId uint64, x, y *uint64, local bool)

Source from the content-addressed store, hash-verified

454// HandleBatchDeposit() handles local/remote liquidity deposits.
455// local=true: x=local pool (actual token movement), y=counter mirror. local=false: x=counter mirror, y=local pool.
456func (s *StateMachine) HandleBatchDeposit(batch *lib.DexBatch, chainId uint64, x, y *uint64, local bool) lib.ErrorI {
457 if len(batch.Deposits) == 0 {
458 return nil
459 }
460 // get the liquidity pool
461 p, err := s.GetPool(chainId + LiquidityPoolAddend)
462 if err != nil {
463 return err
464 }
465 // define variables
466 var totalDeposit, distributed uint64
467 // x = the initial 'deposit' pool balance
468 // y = the 'counter' pool balance
469 // L = initial pool points
470 L := p.TotalPoolPoints
471 // sum all deposits
472 for _, deposit := range batch.Deposits {
473 totalDeposit += deposit.Amount
474 }
475 // nothing to add or failed invariant check
476 if totalDeposit == 0 || *x == 0 || *y == 0 {
477 return nil
478 }
479 // if no liq points yet assigned - initialize to 'dead' address
480 if L == 0 {
481 // calculate the initial pool points using L = √( x * y )
482 L = lib.SqrtProductUint64(*x, *y)
483 // add points to the dead address
484 p.AddPoints(deadAddr.Bytes(), L)
485 }
486 // using integer math and geometric mean of reserves:
487 // deltaPoolPoints = L * ( √((x + totalDeposit) * y) - √(x * y) ) / √(x * y) or simplified as:
488 // deltaPoolPoints = L * (newK - oldK) / oldK (in a 1 sided deposit scenario dY=0 thus this formula)
489 oldK := lib.SqrtProductUint64(*x, *y)
490 if oldK == 0 {
491 return ErrInvalidLiquidityPool()
492 }
493 newK := lib.SqrtProductUint64(*x+totalDeposit, *y)
494 // totalDL is calculated as if all deposits is just 1 big deposit
495 totalDL := lib.SafeMulDiv(L, newK-oldK, oldK)
496 // distribute the points
497 for _, deposit := range batch.Deposits {
498 // calculate pro-rate share for this particular deposit
499 share := lib.SafeMulDiv(totalDL, deposit.Amount, totalDeposit)
500 // update the distributed counter
501 distributed += share
502 // add points to pool
503 p.AddPoints(deposit.Address, share)
504 // if 'local' request - (actually move from holding pool to liquidity pool, don't *just* update the ledger)
505 if local {
506 if err = s.PoolSub(chainId+HoldingPoolAddend, deposit.Amount); err != nil {
507 return err
508 }
509 p.Amount += deposit.Amount
510 }
511 // update the reserve
512 *x += deposit.Amount
513 // emit a deposit event

Calls 9

GetPoolMethod · 0.95
PoolSubMethod · 0.95
SetPoolMethod · 0.95
SqrtProductUint64Function · 0.92
SafeMulDivFunction · 0.92
ErrInvalidLiquidityPoolFunction · 0.85
AddPointsMethod · 0.80
BytesMethod · 0.65

Tested by 1