-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpool_manager.gno
147 lines (122 loc) · 3.74 KB
/
pool_manager.gno
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package pool
import (
"std"
"strconv"
bar "gno.land/r/bar"
foo "gno.land/r/foo"
"gno.land/p/demo/ufmt"
)
var (
admins []std.Address
initialized bool = false
feeAmountTickSpacing map[uint16]int32 = make(map[uint16]int32) // map[fee_amount]tick_spacing
pools map[string]*Pool = make(map[string]*Pool) // map[pool_key]*Pool
)
func InitManual() {
require(!initialized, "[POOl] pool_manager.gno__InitManual() || contract must not be initialized")
feeAmountTickSpacing[100] = 2
feeAmountTickSpacing[500] = 10
feeAmountTickSpacing[3000] = 60
feeAmountTickSpacing[10000] = 200
admins = append(admins, PrevRealmAddr())
initialized = true
}
func CreatePool(
tokenA string, // XXX inter-contract token0 pkg_path
tokenB string, // XXX inter-contract token1 pkg_path
fee uint16,
sqrtPriceX96 bigint,
) *Pool {
require(initialized, "[POOl] pool_manager.gno__CreatePool() || contract must be initialized")
require(tokenA != tokenB, ufmt.Sprintf("[POOl] pool_manager.gno__CreatePool() || token pair cannot be the same__tokenA(%s) != tokenB(%s)", tokenA, tokenB))
// r3v4_xxx: check whether token pair has been deployed successfuly
var token0, token1 string
if tokenA < tokenB {
token0 = tokenA
token1 = tokenB
} else {
token0 = tokenB
token1 = tokenA
}
// check tickSpacing for fee
tickSpacing := feeAmountTickSpacing[fee]
require(tickSpacing > 0, ufmt.Sprintf("[POOL] pool_manager.gno__CreatePool() || tickSpacing(%d) > 0", tickSpacing))
// calculate poolKey
poolKey := GetPoolKey(token0, token1, fee)
// check whether the pool already exist
pool, exist := pools[poolKey]
require(!exist, ufmt.Sprintf("[POOl] pool_manager.gno__CreatePool() || pool(%s) already exist", poolKey))
if !exist {
pool = newPool(token0, token1, fee, tickSpacing, sqrtPriceX96)
pools[poolKey] = pool
}
return pool
}
func GetPool(token0, token1 string, fee uint16) *Pool {
poolKey := GetPoolKey(token0, token1, fee)
pool, exist := pools[poolKey]
require(exist, ufmt.Sprintf("[POOL] pool_manager.gno__GetPool() || pool(%s) not found", poolKey))
return pool
}
func GetPoolFromPoolKey(poolKey string) *Pool {
pool, exist := pools[poolKey]
require(exist, ufmt.Sprintf("[POOL] pool_manager.gno__GetPoolFromPoolKey() || pool(%s) not found", poolKey))
return pool
}
func GetPoolKey(token0, token1 string, fee uint16) string {
if token0 < token1 {
return token0 + "_" + token1 + "_" + strconv.Itoa(int(fee))
} else {
return token1 + "_" + token0 + "_" + strconv.Itoa(int(fee))
}
}
func newPool(
token0 string,
token1 string,
fee uint16,
tickSpacing int32,
sqrtPriceX96 bigint,
) *Pool {
maxLiquidityPerTick := tickTickSpacingToMaxLiquidityPerTick(tickSpacing)
tick := TickMathGetTickAtSqrtRatio(sqrtPriceX96)
slot0 := Slot0{
sqrtPriceX96: sqrtPriceX96,
tick: tick,
feeProtocol: 0,
unlocked: true,
}
balances := Balances{
token0: 0,
token1: 0,
}
protocolFees := ProtocolFees{
token0: 0,
token1: 0,
}
// r3v4_xxx: dynamic import need to support multi token
return &Pool{
token0: foo.GetGRC20(), // token0.GetGRC20() // gno.land/r/foo.GetGRC20()
token1: bar.GetGRC20(), // token1.GetGRC20() // gno.land/r/bar.GetGRC20()
balances: balances,
fee: fee,
tickSpacing: tickSpacing,
maxLiquidityPerTick: maxLiquidityPerTick,
slot0: slot0,
feeGrowthGlobal0X128: 0,
feeGrowthGlobal1X128: 0,
protocolFees: protocolFees,
liquidity: 0,
ticks: Ticks{},
tickBitmaps: TickBitmaps{},
positions: Positions{},
}
}
func isAdmin(target std.Address) bool {
for _, admin := range admins {
if admin == target {
return true
}
}
// target isn't one of admins
return false
}