Skip to content

Commit

Permalink
build: git action CI to test contract (#484)
Browse files Browse the repository at this point in the history
* build: gitaction to test contract
* Update .github/workflows/run_test.yml
* build: CI to run parallel test

---------

Co-authored-by: Lee ByeongJun <[email protected]>
Co-authored-by: 0xTopaz <[email protected]>
  • Loading branch information
3 people authored Jan 24, 2025
1 parent c731050 commit 9edf011
Show file tree
Hide file tree
Showing 166 changed files with 908 additions and 1,476 deletions.
120 changes: 120 additions & 0 deletions .github/workflows/run_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: run-test

on:
pull_request:
branches:
- main

jobs:
test-gnoswap:
runs-on: ubuntu-latest
# fail-fast: false ensures that if one matrix entry fails,
# it doesn't cancel the others.
strategy:
fail-fast: false
matrix:
include:
- name: "p/uint256"
folder: "gno/examples/gno.land/p/gnoswap/uint256"
- name: "p/int256"
folder: "gno/examples/gno.land/p/gnoswap/int256"
- name: "p/gnsmath"
folder: "gno/examples/gno.land/p/gnoswap/gnsmath"
- name: "r/common"
folder: "gno/examples/gno.land/r/gnoswap/v1/common"
- name: "r/gns"
folder: "gno/examples/gno.land/r/gnoswap/v1/gns"
- name: "r/gnft"
folder: "gno/examples/gno.land/r/gnoswap/v1/gnft"
- name: "r/gov/xgns"
folder: "gno/examples/gno.land/r/gnoswap/v1/gov/xgns"
- name: "r/emission"
folder: "gno/examples/gno.land/r/gnoswap/v1/emission"
- name: "r/protocol_fee"
folder: "gno/examples/gno.land/r/gnoswap/v1/protocol_fee"
- name: "r/pool"
folder: "gno/examples/gno.land/r/gnoswap/v1/pool"
- name: "r/position"
folder: "gno/examples/gno.land/r/gnoswap/v1/position"
- name: "r/router"
folder: "gno/examples/gno.land/r/gnoswap/v1/router"
- name: "r/staker"
folder: "gno/examples/gno.land/r/gnoswap/v1/staker"
- name: "r/community_pool"
folder: "gno/examples/gno.land/r/gnoswap/v1/community_pool"
- name: "r/gov/staker"
folder: "gno/examples/gno.land/r/gnoswap/v1/gov/staker"
- name: "r/gov/governance"
folder: "gno/examples/gno.land/r/gnoswap/v1/gov/governance"
- name: "r/launchpad"
folder: "gno/examples/gno.land/r/gnoswap/v1/launchpad"

steps:
# 1. Check out gnoswap repository (with your workflow file, etc.)
- name: Check out gnoswap repo
uses: actions/checkout@v4

# 2. Check out gno(master) into ./gno
- name: Check out gno(master)
uses: actions/checkout@v4
with:
repository: gnolang/gno
ref: master # can be used with tag also (e.g `chain/test5.0`)
path: ./gno

# 3. Install Go
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.22"

# 4. Configure gnovm
- name: Config gnovm
run: |
sed -i 's/ctx.Timestamp += (count \* 5)/ctx.Timestamp += (count \* 2)/g' ./gno/gnovm/tests/stdlibs/std/std.go
# 5. Build/install `gno` CLI
- name: Install gno
run: |
cd gno
make install.gno
# 6. Set up Python
- name: Set up python
uses: actions/setup-python@v4
with:
python-version: 3.12

# 7. Check out your gnoswap repo into ./tmp/gnoswap
- name: Checkout gnoswap(main)
uses: actions/checkout@v4
with:
path: ./tmp/gnoswap

# 8. Run setup.py (copy contracts into gno)
- name: Run setup.py
run: |
cd tmp/gnoswap
python3 setup.py -w /home/runner/work/gnoswap/gnoswap
# 9. Now run the tests in parallel via the matrix.
# Each job will handle ONE contract from the matrix.
- name: "Run tests for ${{ matrix.name }}"
# if any test fails, we keep going to test all contracts:
# continue-on-error: true
run: |
FOLDER="${{ matrix.folder }}"
# 1) Run unit tests first
gno test ./"$FOLDER" \
-root-dir /home/runner/work/gnoswap/gnoswap/gno -v
# 2) Remove all _test.gno except _helper_test.gno
find ./"$FOLDER" -type f -name "*_test.gno" \
! -name "_helper_test.gno" \
-exec rm -f {} +
# 3) One-by-one gnoA tests: rename *.gnoA => *.gno, run, revert
cd ./"$FOLDER"
TESTFILES=$(ls | grep '_test.gnoA$' || true)
for f in $TESTFILES; do
base="${f%.gnoA}"
mv "$f" "$base.gno"
gno test . \
-root-dir /home/runner/work/gnoswap/gnoswap/gno -v
mv "$base.gno" "$f"
done
2 changes: 1 addition & 1 deletion contract/p/gnoswap/gnsmath/sqrt_price_math_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func TestSqrtPriceMathGetNextSqrtPriceFromInput(t *testing.T) {
amountIn: u256.MustFromDecimal("1024"),
zeroForOne: false,
shouldPanic: true,
panicMsg: "sqrtPx96 + quotient overflow uint160",
panicMsg: "GetNextSqrtPriceFromAmount1RoundingDown sqrtPx96 + quotient overflow uint160",
},
{
name: "any input amount cannot underflow the price",
Expand Down
34 changes: 17 additions & 17 deletions contract/p/gnoswap/gnsmath/swap_math_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ func TestSwapMathComputeSwapStepStr(t *testing.T) {
}{
{
name: "exact amount in that gets capped at price target in one for zero",
currentX96: encodePriceSqrt(t, "1", "1"),
targetX96: encodePriceSqrt(t, "101", "100"),
currentX96: encodePriceSqrtTest(t, "1", "1"),
targetX96: encodePriceSqrtTest(t, "101", "100"),
liquidity: u256.MustFromDecimal("2000000000000000000"),
amountRemaining: i256.MustFromDecimal("1000000000000000000"),
feePips: 600,
sqrtNextX96: encodePriceSqrt(t, "101", "100"),
sqrtNextX96: encodePriceSqrtTest(t, "101", "100"),
chkSqrtNextX96: func(sqrtRatioNextX96, priceTarget *u256.Uint) {
uassert.True(t, sqrtRatioNextX96.Eq(priceTarget))
},
Expand All @@ -37,12 +37,12 @@ func TestSwapMathComputeSwapStepStr(t *testing.T) {
},
{
name: "exact amount out that gets capped at price target in one for zero",
currentX96: encodePriceSqrt(t, "1", "1"),
targetX96: encodePriceSqrt(t, "101", "100"),
currentX96: encodePriceSqrtTest(t, "1", "1"),
targetX96: encodePriceSqrtTest(t, "101", "100"),
liquidity: u256.MustFromDecimal("2000000000000000000"),
amountRemaining: i256.MustFromDecimal("-1000000000000000000"),
feePips: 600,
sqrtNextX96: encodePriceSqrt(t, "101", "100"),
sqrtNextX96: encodePriceSqrtTest(t, "101", "100"),
chkSqrtNextX96: func(sqrtRatioNextX96, priceTarget *u256.Uint) {
uassert.True(t, sqrtRatioNextX96.Eq(priceTarget))
},
Expand All @@ -52,11 +52,11 @@ func TestSwapMathComputeSwapStepStr(t *testing.T) {
},
{
name: "exact amount in that is fully spent in one for zero",
currentX96: encodePriceSqrt(t, "1", "1"),
targetX96: encodePriceSqrt(t, "1000", "100"),
currentX96: encodePriceSqrtTest(t, "1", "1"),
targetX96: encodePriceSqrtTest(t, "1000", "100"),
liquidity: u256.MustFromDecimal("2000000000000000000"),
amountRemaining: i256.MustFromDecimal("1000000000000000000"),
sqrtNextX96: encodePriceSqrt(t, "1000", "100"),
sqrtNextX96: encodePriceSqrtTest(t, "1000", "100"),
feePips: 600,
chkSqrtNextX96: func(sqrtRatioNextX96, priceTarget *u256.Uint) {
uassert.True(t, sqrtRatioNextX96.Lte(priceTarget))
Expand All @@ -67,12 +67,12 @@ func TestSwapMathComputeSwapStepStr(t *testing.T) {
},
{
name: "exact amount out that is fully received in one for zero",
currentX96: encodePriceSqrt(t, "1", "1"),
targetX96: encodePriceSqrt(t, "1000", "100"),
currentX96: encodePriceSqrtTest(t, "1", "1"),
targetX96: encodePriceSqrtTest(t, "1000", "100"),
liquidity: u256.MustFromDecimal("2000000000000000000"),
amountRemaining: i256.MustFromDecimal("-1000000000000000000"),
feePips: 600,
sqrtNextX96: encodePriceSqrt(t, "1000", "100"),
sqrtNextX96: encodePriceSqrtTest(t, "1000", "100"),
chkSqrtNextX96: func(sqrtRatioNextX96, priceTarget *u256.Uint) {
uassert.True(t, sqrtRatioNextX96.Lt(priceTarget))
},
Expand Down Expand Up @@ -188,7 +188,7 @@ func TestSwapMathComputeSwapStepStrFail(t *testing.T) {
liquidity: nil,
amountRemaining: nil,
feePips: 600,
sqrtNextX96: encodePriceSqrt(t, "101", "100"),
sqrtNextX96: encodePriceSqrtTest(t, "101", "100"),
chkSqrtNextX96: func(sqrtRatioNextX96, priceTarget *u256.Uint) {
uassert.True(t, sqrtRatioNextX96.Eq(priceTarget))
},
Expand Down Expand Up @@ -230,8 +230,8 @@ func TestSwapMathComputeSwapStepStrFail(t *testing.T) {
}
}

// encodePriceSqrt calculates the sqrt((reserve1 << 192) / reserve0)
func encodePriceSqrt(t *testing.T, reserve1, reserve0 string) *u256.Uint {
// encodePriceSqrtTest calculates the sqrt((reserve1 << 192) / reserve0)
func encodePriceSqrtTest(t *testing.T, reserve1, reserve0 string) *u256.Uint {
t.Helper()

reserve1Uint := u256.MustFromDecimal(reserve1)
Expand All @@ -249,11 +249,11 @@ func encodePriceSqrt(t *testing.T, reserve1, reserve0 string) *u256.Uint {
ratioX192 := new(u256.Uint).Div(numerator, reserve0Uint)

// Return sqrt(ratioX192)
return sqrt(t, ratioX192)
return sqrtTest(t, ratioX192)
}

// sqrt computes the integer square root of a u256.Uint
func sqrt(t *testing.T, x *u256.Uint) *u256.Uint {
func sqrtTest(t *testing.T, x *u256.Uint) *u256.Uint {
t.Helper()

if x.IsZero() {
Expand Down
4 changes: 2 additions & 2 deletions contract/r/gnoswap/common/grc20reg_helper_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,15 @@ func TestBalanceOf(t *testing.T) {
defaultHolder := std.Address("g1manfred47kzduec920z88wfr64ylksmdcedlf5")

// result from grc2reg and (direct import/call) should be the same
uassert.Equal(t, foo20.BalanceOf(AddrToUser(defaultHolder)), BalanceOf(tokenPath, defaultHolder))
uassert.Equal(t, foo20.BalanceOf(defaultHolder), BalanceOf(tokenPath, defaultHolder))
}

func TestAllowance(t *testing.T) {
owner := std.Address("g1manfred47kzduec920z88wfr64ylksmdcedlf5")
spender := std.Address("g1pf6dv9fjk3rn0m4jjcne306ga4he3mzmupfjl6")

// result from grc2reg and (direct import/call) should be the same
uassert.Equal(t, foo20.Allowance(AddrToUser(owner), AddrToUser(spender)), Allowance(tokenPath, owner, spender))
uassert.Equal(t, foo20.Allowance(owner, spender), Allowance(tokenPath, owner, spender))
}

// areSlicesEqual compares two slices of strings
Expand Down
7 changes: 4 additions & 3 deletions contract/r/gnoswap/emission/callback.gno
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ func SetCallbackStakerEmissionChange(callback func(amount uint64)) {
// Called when per-block emission is changed from the gns side.
// It does not process non-immediate emission changes, such as halving.
func callbackEmissionChange(amount uint64) {
callbackStakerEmissionChange(calculateAmount(amount, GetDistributionBpsPct(LIQUIDITY_STAKER)))
calculatedAmount := calculateAmount(amount, GetDistributionBpsPct(LIQUIDITY_STAKER))
callbackStakerEmissionChange(calculatedAmount)
}

func init() {
func RegisterGnsChangeCallback() {
assertStakerOnly()
gns.SetCallbackEmissionChange(callbackEmissionChange)
}

2 changes: 1 addition & 1 deletion contract/r/gnoswap/emission/emission.gno
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func MintAndDistributeGns() uint64 {
return 0
}
// Mint new tokens and add any leftover amounts from previous distribution
mintedEmissionRewardAmount := gns.MintGns(a2u(consts.EMISSION_ADDR))
mintedEmissionRewardAmount := gns.MintGns(consts.EMISSION_ADDR)

distributableAmount := mintedEmissionRewardAmount
prevLeftAmount := GetLeftGNSAmount()
Expand Down
14 changes: 0 additions & 14 deletions contract/r/gnoswap/gns/_helper_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package gns
import (
"std"
"testing"
"time"

"gno.land/p/demo/grc/grc20"
"gno.land/p/demo/ownable"
Expand All @@ -15,12 +14,9 @@ func resetObject(t *testing.T) {
t.Helper()

resetGnsTokenObject(t)
resetHalvingRelatedObject(t)

height := std.GetHeight()
lastMintedHeight = height
startHeight = height
startTimestamp = time.Now().Unix()
}

func resetGnsTokenObject(t *testing.T) {
Expand All @@ -31,13 +27,3 @@ func resetGnsTokenObject(t *testing.T) {
owner = ownable.NewWithAddress(consts.ADMIN)
privateLedger.Mint(owner.Owner(), INITIAL_MINT_AMOUNT)
}

func resetHalvingRelatedObject(t *testing.T) {
t.Helper()

startHeight = std.GetHeight()
startTimestamp = time.Now().Unix()

emissionState = GetEmissionState()
setEndTimestamp(startTimestamp + consts.TIMESTAMP_YEAR*HALVING_END_YEAR)
}
37 changes: 4 additions & 33 deletions contract/r/gnoswap/gns/tests/gns_calculate_and_mint_test.gnoA
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ var (
func TestCalculateAmountToMint(t *testing.T) {
t.Run("1 block for same year 01", func(t *testing.T) {
amount := calculateAmountToMint(GetLastMintedHeight()+1, GetLastMintedHeight()+1)
uassert.Equal(t, amountPerBlockPerHalvingYear[0], amount)
uassert.Equal(t, GetAmountPerBlockPerHalvingYear(1), amount)
})

t.Run("2 block for same year 01", func(t *testing.T) {
amount := calculateAmountToMint(GetLastMintedHeight()+2, GetLastMintedHeight()+3)
uassert.Equal(t, amountPerBlockPerHalvingYear[1]*2, amount)
uassert.Equal(t, GetAmountPerBlockPerHalvingYear(1)*2, amount)
})

t.Run("entire block for year 01 + 1 block for year 02", func(t *testing.T) {
Expand All @@ -33,7 +33,7 @@ func TestCalculateAmountToMint(t *testing.T) {
uassert.Equal(t, GetHalvingYearMaxAmount(1), GetHalvingYearMintAmount(1))

// minted 1 block for year 02
uassert.Equal(t, amountPerBlockPerHalvingYear[1], GetHalvingYearMintAmount(2))
uassert.Equal(t, GetAmountPerBlockPerHalvingYear(1), GetHalvingYearMintAmount(2))
})

t.Run("entire block for 12 years", func(t *testing.T) {
Expand All @@ -55,7 +55,7 @@ func TestMintGns(t *testing.T) {
std.TestSetRealm(adminRealm)
std.TestSkipHeights(123) // pass some block to bypass last block check
common.SetHaltByAdmin(true) // set halt
uassert.PanicsWithMessage(t, "[GNOSWAP-COMMON-002] halted || gnoswap halted", func() {
uassert.PanicsWithMessage(t, "[GNOSWAP-COMMON-002] halted || GnoSwap is halted", func() {
MintGns(consts.ADMIN)
})

Expand All @@ -74,33 +74,4 @@ func TestMintGns(t *testing.T) {
mintedAmount := MintGns(consts.ADMIN)
uassert.Equal(t, uint64(0), mintedAmount)
})

t.Run("mint by year, until emission ends", func(t *testing.T) {
resetObject(t)
for year := int64(1); year <= 12; year++ {
skipUntilLastHeightOfHalvingYear(t, year)

std.TestSetRealm(emissionRealm)
mintedAmount := MintGns(consts.ADMIN)

uassert.Equal(t, GetHalvingYearMaxAmount(year), mintedAmount)
uassert.Equal(t, GetHalvingYearMaxAmount(year), GetHalvingYearMintAmount(year))
uassert.Equal(t, GetHalvingYearAccuAmount(year), GetMintedEmissionAmount())
}
})

t.Run("no more emission after it ends", func(t *testing.T) {
std.TestSkipHeights(blockPerYear)

std.TestSetRealm(emissionRealm)
mintedAmount := MintGns(consts.ADMIN)
uassert.Equal(t, uint64(0), mintedAmount)
})
}

func skipUntilLastHeightOfHalvingYear(t *testing.T, year int64) {
t.Helper()

lastHeight := GetHalvingYearEndBlock(year)
std.TestSkipHeights(lastHeight - std.GetHeight())
}
Loading

0 comments on commit 9edf011

Please sign in to comment.