Skip to content

Commit

Permalink
GSW-1839 fix: position tests (#450)
Browse files Browse the repository at this point in the history
* fix: position
- use `new` operator to use pointer value from other contract
- reposition should update values based on new tick ranges
* fix: gnoA scenario tests
* chore: remove deprecated
* fix: mint params should use updated value
* chore: revert unittest file extension changes
* fix: testing fail issue
* test : Add missing test code
* refactor: Use liquidity ratio dash liquidity amount for decreasLiquidity
* refactor: getter and rpc
* fix: Fixed token path ordering issue when creating pools
* refactor: api refactoring
* fix : full test fail

---------

Co-authored-by: 0xTopaz <[email protected]>
  • Loading branch information
r3v4s and onlyhyde authored Dec 27, 2024
1 parent 1e27ad9 commit 43d2606
Show file tree
Hide file tree
Showing 44 changed files with 2,183 additions and 918 deletions.
1 change: 1 addition & 0 deletions emission/emission.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"gno.land/p/demo/ufmt"

"gno.land/r/gnoswap/v1/common"
"gno.land/r/gnoswap/v1/consts"
"gno.land/r/gnoswap/v1/gns"
)

Expand Down
2 changes: 1 addition & 1 deletion emission/mint_gns.gno
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ var emissionAddr std.Address = consts.EMISSION_ADDR

// mintGns mints GNS to emission address
func mintGns() uint64 {
return gns.Mint(a2u(emissionAddr))
return gns.MintGns(a2u(emissionAddr))
}
44 changes: 36 additions & 8 deletions pool/pool_manager.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ import (

"gno.land/p/demo/avl"
"gno.land/p/demo/ufmt"
u256 "gno.land/p/gnoswap/uint256"

"gno.land/r/gnoswap/v1/common"
"gno.land/r/gnoswap/v1/consts"

en "gno.land/r/gnoswap/v1/emission"

"gno.land/r/gnoswap/v1/gns"

u256 "gno.land/p/gnoswap/uint256"
)

var (
Expand Down Expand Up @@ -57,6 +55,32 @@ func newPoolParams(
}
}

func (p *createPoolParams) updateWithWrapping() *createPoolParams {
token0Path, token1Path := p.wrap()

if !p.isInOrder() {
token0Path, token1Path = token1Path, token0Path

oldTick := common.TickMathGetTickAtSqrtRatio(p.sqrtPriceX96)
if oldTick > consts.MAX_TICK || oldTick < consts.MIN_TICK {
panic(addDetailToError(
errInvalidTickRange,
ufmt.Sprintf("expected tick(%d) to be within range", oldTick),
))
}
newPrice := common.TickMathGetSqrtRatioAtTick(oldTick * int32(-1))
if newPrice.IsZero() {
panic(addDetailToError(
errOverFlow,
ufmt.Sprintf("expected newPrice(%s) to be non-zero", newPrice.ToString()),
))
}
p.sqrtPriceX96 = new(u256.Uint).Set(newPrice)
}

return newPoolParams(token0Path, token1Path, p.fee, p.sqrtPriceX96.ToString())
}

func (p *createPoolParams) isSameTokenPath() bool {
return p.token0Path == p.token1Path
}
Expand Down Expand Up @@ -113,12 +137,16 @@ func CreatePool(
sqrtPriceX96 string,
) {
assertOnlyNotHalted()
assertOnlyRegistered(token0Path)
assertOnlyRegistered(token1Path)

poolInfo := newPoolParams(token0Path, token1Path, fee, sqrtPriceX96)
poolInfo = poolInfo.updateWithWrapping()
if poolInfo.isSameTokenPath() {
panic(addDetailToError(
errDuplicateTokenInPool,
ufmt.Sprintf(
"pool_manager.gno__CreatePool() || expected token0Path(%s) != token1Path(%s)",
"expected token0Path(%s) != token1Path(%s)",
poolInfo.token0Path, poolInfo.token1Path,
),
))
Expand All @@ -137,7 +165,7 @@ func CreatePool(
panic(addDetailToError(
errDuplicateTokenInPool,
ufmt.Sprintf(
"pool_manager.gno__CreatePool() || expected token0Path(%s) != token1Path(%s)",
"expected token0Path(%s) != token1Path(%s)",
token0Path, token1Path,
),
))
Expand All @@ -146,7 +174,7 @@ func CreatePool(
if !poolInfo.isInOrder() {
panic(addDetailToError(
errTokenSortOrder,
ufmt.Sprintf("pool_manager.gno__CreatePool() || expected token0Path(%s) < token1Path(%s)", token0Path, token1Path),
ufmt.Sprintf("expected token0Path(%s) < token1Path(%s)", token0Path, token1Path),
))
}

Expand All @@ -157,7 +185,7 @@ func CreatePool(
if exist {
panic(addDetailToError(
errPoolAlreadyExists,
ufmt.Sprintf("pool_manager.gno__CreatePool() || expected poolPath(%s) not to exist", poolPath),
ufmt.Sprintf("expected poolPath(%s) not to exist", poolPath),
))
}

Expand Down
18 changes: 12 additions & 6 deletions pool/pool_manager_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func TestCreatePool(t *testing.T) {
sqrtPrice string
shouldPanic bool
panicMsg string
inOrder bool
}{
{
name: "success - normal token pair",
Expand All @@ -107,16 +108,17 @@ func TestCreatePool(t *testing.T) {
fee: 3000,
sqrtPrice: "4295128740",
shouldPanic: true,
panicMsg: "[GNOSWAP-POOL-011] same token used in single pool || pool_manager.gno__CreatePool() || expected token0Path(gno.land/r/onbloc/bar) != token1Path(gno.land/r/onbloc/bar",
panicMsg: "[GNOSWAP-POOL-011] same token used in single pool || expected token0Path(gno.land/r/onbloc/bar) != token1Path(gno.land/r/onbloc/bar",
},
{
name: "fail - tokens not in order",
name: "success - when tokens not in order, reverse order and create pool",
token0Path: fooPath,
token1Path: barPath,
token1Path: bazPath,
fee: 3000,
sqrtPrice: "4295128740",
shouldPanic: true,
panicMsg: "[GNOSWAP-POOL-012] tokens must be in lexicographical order || pool_manager.gno__CreatePool() || expected token0Path(gno.land/r/onbloc/foo) < token1Path(gno.land/r/onbloc/bar)",
shouldPanic: false,
panicMsg: "[GNOSWAP-POOL-012] tokens must be in lexicographical order || expected token0Path(gno.land/r/onbloc/foo) < token1Path(gno.land/r/onbloc/baz)",
inOrder: true,
},
{
name: "fail - pool already exists",
Expand All @@ -125,7 +127,7 @@ func TestCreatePool(t *testing.T) {
fee: 3000,
sqrtPrice: "4295128740",
shouldPanic: true,
panicMsg: "[GNOSWAP-POOL-013] pool already created || pool_manager.gno__CreatePool() || expected poolPath(gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:3000) not to exist",
panicMsg: "[GNOSWAP-POOL-013] pool already created || expected poolPath(gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:3000) not to exist",
},
}

Expand Down Expand Up @@ -158,6 +160,10 @@ func TestCreatePool(t *testing.T) {
// check if GNOT was properly wrapped
expectedToken0 := tt.token0Path
expectedToken1 := tt.token1Path
if tt.inOrder {
expectedToken0, expectedToken1 = expectedToken1, expectedToken0
}

if expectedToken0 == consts.GNOT {
expectedToken0 = consts.WRAPPED_WUGNOT
}
Expand Down
26 changes: 0 additions & 26 deletions position/_GET_no_receiver_string.gno

This file was deleted.

80 changes: 0 additions & 80 deletions position/_RPC_dry.gno

This file was deleted.

34 changes: 33 additions & 1 deletion position/_helper_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"gno.land/r/onbloc/qux"
"gno.land/r/onbloc/usdc"

rr "gno.land/r/gnoswap/v1/router"
sr "gno.land/r/gnoswap/v1/staker"
)

Expand Down Expand Up @@ -162,15 +163,28 @@ func (QuxToken) Approve() func(spender pusers.AddressOrName, amount uint64) {
return qux.Approve
}

func init() {
std.TestSetRealm(std.NewUserRealm("g1er355fkjksqpdtwmhf5penwa82p0rhqxkkyhk5"))
rr.RegisterGRC20Interface(wugnotPath, WugnotToken{})
rr.RegisterGRC20Interface(gnsPath, GNSToken{})
rr.RegisterGRC20Interface(barPath, BarToken{})
rr.RegisterGRC20Interface(bazPath, BazToken{})
rr.RegisterGRC20Interface(fooPath, FooToken{})
rr.RegisterGRC20Interface(oblPath, OBLToken{})
rr.RegisterGRC20Interface(quxPath, QuxToken{})
}

var (
admin = pusers.AddressOrName(consts.ADMIN)
adminAddr = std.Address(consts.ADMIN)
admin = pusers.AddressOrName(adminAddr)
alice = pusers.AddressOrName(testutils.TestAddress("alice"))
bob = pusers.AddressOrName(testutils.TestAddress("bob"))
pool = pusers.AddressOrName(consts.POOL_ADDR)
protocolFee = pusers.AddressOrName(consts.PROTOCOL_FEE_ADDR)
router = pusers.AddressOrName(consts.ROUTER_ADDR)
adminRealm = std.NewUserRealm(users.Resolve(admin))
posRealm = std.NewCodeRealm(consts.POSITION_PATH)
rouRealm = std.NewCodeRealm(consts.ROUTER_PATH)

// addresses used in tests
addrUsedInTest = []std.Address{addr01, addr02}
Expand Down Expand Up @@ -504,6 +518,13 @@ func MintPositionAll(t *testing.T, caller std.Address) {

}

func CreatePoolWithoutFee(t *testing.T) {
std.TestSetRealm(adminRealm)
// set pool create fee to 0 for testing
pl.SetPoolCreationFeeByAdmin(0)
CreatePool(t, barPath, fooPath, fee500, common.TickMathGetSqrtRatioAtTick(0).ToString(), users.Resolve(admin))
}

func MakeMintPositionWithoutFee(t *testing.T) (uint64, string, string, string) {
t.Helper()

Expand Down Expand Up @@ -552,6 +573,13 @@ func LPTokenUnStake(t *testing.T, owner pusers.AddressOrName, tokenId uint64, un
sr.UnstakeToken(tokenId, unwrap)
}

func getPoolFromLpTokenId(t *testing.T, lpTokenId uint64) *pl.Pool {
t.Helper()

position := MustGetPosition(lpTokenId)
return pl.GetPoolFromPoolPath(position.poolKey)
}

func wugnotApprove(t *testing.T, owner, spender pusers.AddressOrName, amount uint64) {
t.Helper()
std.TestSetRealm(std.NewUserRealm(users.Resolve(owner)))
Expand Down Expand Up @@ -757,6 +785,7 @@ func burnAllNFT(t *testing.T) {
}

func TestBeforeResetPositionObject(t *testing.T) {
t.Skip("only available for single file(current file) test")
// make actual data to test resetting not only position's state but also pool's state
std.TestSetRealm(adminRealm)

Expand All @@ -772,20 +801,23 @@ func TestBeforeResetPositionObject(t *testing.T) {
}

func TestResetObject(t *testing.T) {
t.Skip("only available for single file(current file) test")
resetObject(t)

uassert.Equal(t, positions.Size(), 0, "positions should be empty")
uassert.Equal(t, nextId, uint64(1), "nextId should be 1")
}

func TestBurnTokens(t *testing.T) {
t.Skip("only available for single file(current file) test")
burnTokens(t)

uassert.Equal(t, foo.BalanceOf(a2u(addr01)), uint64(0)) // 100_000_000 -> 0
uassert.Equal(t, bar.BalanceOf(a2u(addr01)), uint64(0)) // 100_000_000 -> 0
}

func TestBurnAllNFT(t *testing.T) {
t.Skip("only available for single file(current file) test")
burnAllNFT(t)
uassert.Equal(t, gnft.TotalSupply(), uint64(0), "gnft total supply should be 0")
}
5 changes: 2 additions & 3 deletions position/_RPC_api.gno → position/api.gno
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"time"

"gno.land/p/demo/json"

i256 "gno.land/p/gnoswap/int256"
"gno.land/r/gnoswap/v1/common"
"gno.land/r/gnoswap/v1/consts"
Expand Down Expand Up @@ -111,7 +110,7 @@ func ApiGetPositions() string {
func ApiGetPosition(lpTokenId uint64) string {
rpcPositions := []RpcPosition{}

position, exist := GetPosition(lpTokenId)
_, exist := GetPosition(lpTokenId)
if !exist {
return ""
}
Expand Down Expand Up @@ -392,7 +391,7 @@ func rpcMakePosition(lpTokenId uint64) RpcPosition {
currentX96,
lowerX96,
upperX96,
i256.FromUint256(position.liquidity),
position.liquidity,
)

unclaimedFee0 := i256.Zero()
Expand Down
Loading

0 comments on commit 43d2606

Please sign in to comment.