From dbf7248656233c1701c85cf2380a4d514841e278 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Fri, 17 Jan 2025 14:49:17 +0900 Subject: [PATCH 1/7] feat: manage accumulated protocol_fee list --- _deploy/r/gnoswap/common/access.gno | 8 + protocol_fee/errors.gno | 9 +- protocol_fee/protocol_fee.gno | 5 - protocol_fee/protocol_fee_test.gno | 2 +- protocol_fee/token_list_with_amount.gno | 126 ++++++++++ protocol_fee/token_list_with_amount_test.gno | 237 +++++++++++++++++++ protocol_fee/utils.gno | 11 +- 7 files changed, 382 insertions(+), 16 deletions(-) create mode 100644 protocol_fee/token_list_with_amount.gno create mode 100644 protocol_fee/token_list_with_amount_test.gno diff --git a/_deploy/r/gnoswap/common/access.gno b/_deploy/r/gnoswap/common/access.gno index 0297c4a60..30a0c8e36 100644 --- a/_deploy/r/gnoswap/common/access.gno +++ b/_deploy/r/gnoswap/common/access.gno @@ -58,6 +58,14 @@ func RouterOnly(caller std.Address) error { return nil } +// PoolOnly checks if the caller is the pool contract. +func PoolOnly(caller std.Address) error { + if caller != consts.POOL_ADDR { + return ufmt.Errorf(ErrNoPermission, caller.String()) + } + return nil +} + // PositionOnly checks if the caller is the position contract. func PositionOnly(caller std.Address) error { if caller != consts.POSITION_ADDR { diff --git a/protocol_fee/errors.gno b/protocol_fee/errors.gno index 6ed788f5d..bc8e9fa7f 100644 --- a/protocol_fee/errors.gno +++ b/protocol_fee/errors.gno @@ -7,12 +7,9 @@ import ( ) var ( - errNoPermission = errors.New("[GNOSWAP-PROTOCOL_FEE-001] caller has no permission") - errNotRegistered = errors.New("[GNOSWAP-PROTOCOL_FEE-002] not registered token") - errAlreadyRegistered = errors.New("[GNOSWAP-PROTOCOL_FEE-003] already registered token") - errLocked = errors.New("[GNOSWAP-PROTOCOL_FEE-004] can't transfer token while locked") - errInvalidInput = errors.New("[GNOSWAP-PROTOCOL_FEE-005] invalid input data") - errInvalidPct = errors.New("[GNOSWAP-PROTOCOL_FEE-006] invalid percentage") + errNoPermission = errors.New("[GNOSWAP-PROTOCOL_FEE-001] caller has no permission") + errInvalidPct = errors.New("[GNOSWAP-PROTOCOL_FEE-002] invalid percentage") + errInvalidAmount = errors.New("[GNOSWAP-PROTOCOL_FEE-003] invalid amount") ) func addDetailToError(err error, detail string) string { diff --git a/protocol_fee/protocol_fee.gno b/protocol_fee/protocol_fee.gno index 7ee21f4b5..4fbd76eac 100644 --- a/protocol_fee/protocol_fee.gno +++ b/protocol_fee/protocol_fee.gno @@ -135,11 +135,6 @@ func ClearAccuTransferToGovStaker() { accuToGovStaker = avl.NewTree() } -// assertOnlyNotHalted panics if the contract is halted. -func assertOnlyNotHalted() { - common.IsHalted() -} - // addAccuToGovStaker adds the amount to the accuToGovStaker by token path. func addAccuToGovStaker(path string, amount uint64) { before := GetAccuTransferToGovStakerByTokenPath(path) diff --git a/protocol_fee/protocol_fee_test.gno b/protocol_fee/protocol_fee_test.gno index 4feb35538..9cb75b770 100644 --- a/protocol_fee/protocol_fee_test.gno +++ b/protocol_fee/protocol_fee_test.gno @@ -61,7 +61,7 @@ func TestSetDevOpsPctByAdminInvalidFee(t *testing.T) { uassert.PanicsWithMessage( t, - `[GNOSWAP-PROTOCOL_FEE-006] invalid percentage || pct(100001) should not be bigger than 10000`, + `[GNOSWAP-PROTOCOL_FEE-002] invalid percentage || pct(100001) should not be bigger than 10000`, func() { SetDevOpsPctByAdmin(100001) }, diff --git a/protocol_fee/token_list_with_amount.gno b/protocol_fee/token_list_with_amount.gno new file mode 100644 index 000000000..396d3e6e9 --- /dev/null +++ b/protocol_fee/token_list_with_amount.gno @@ -0,0 +1,126 @@ +package protocol_fee + +import ( + "std" + "strings" + + "gno.land/p/demo/ufmt" + + "gno.land/r/gnoswap/v1/common" + "gno.land/r/gnoswap/v1/consts" +) + +var ( + tokenListWithAmount = make(map[string]uint64) // tokenPath -> amount +) + +// TokenList returns only the token path. +// If positive is true, it returns only the token path with amount > 0. +// If positive is false, it returns all the token path. +func TokenList(positive bool) []string { + tokens := []string{} + + for tokenPath, amount := range tokenListWithAmount { + if positive && amount == 0 { + continue + } + + tokens = append(tokens, tokenPath) + } + + return tokens +} + +// TokenListWithAmount returns the token path and amount. +func TokenListWithAmount() map[string]uint64 { + return tokenListWithAmount +} + +// AddToProtocolFee adds the amount to the tokenListWithAmount +// Only `pool + router + staker` can execute this function. +func AddToProtocolFee(tokenPath string, amount uint64) { + assertOnlyPoolRouterStaker() + tokenListWithAmount[tokenPath] += amount +} + +// ClearTokenListWithAmount clears the tokenListWithAmount. +// only `gov/staker` can execute this function. +func ClearTokenListWithAmount() { + assertOnlyGovStaker() + tokenListWithAmount = map[string]uint64{} +} + +// TransferProtocolFee transfers the protocol fee to devOps and gov/staker. +// It returns list of token with amount has been sent to gov/staker. +func TransferProtocolFee() map[string]uint64 { + assertOnlyGovStaker() + + sentToDevOps := []string{} + sentToGovStaker := []string{} + toReturn := map[string]uint64{} + + for token, amount := range tokenListWithAmount { + balance := common.BalanceOf(token, consts.PROTOCOL_FEE_ADDR) + + // amount in `tokenListWithAmount` is corrupted, it should be equal to balance + if amount != balance { + panic(errInvalidAmount.Error()) + } + + if balance > 0 { + toDevOps := balance * devOpsPct / 10000 // default 0% + toGovStaker := balance - toDevOps // default 100% + + tokenTeller := common.GetTokenTeller(token) + if toDevOps > 0 { + tokenTeller.Transfer(consts.DEV_OPS, toDevOps) + sentToDevOps = append(sentToDevOps, makeEventString(token, toDevOps)) + } + + if toGovStaker > 0 { + tokenTeller.Transfer(consts.GOV_STAKER_ADDR, toGovStaker) + sentToGovStaker = append(sentToGovStaker, makeEventString(token, toGovStaker)) + + toReturn[token] = toGovStaker + } + } + } + + ClearTokenListWithAmount() + + prevAddr, prevRealm := getPrev() + std.Emit( + "TransferProtocolFee", + "prevAddr", prevAddr, + "prevRealm", prevRealm, + "toDevOps", strings.Join(sentToDevOps, ","), + "toGovStaker", strings.Join(sentToGovStaker, ","), + ) + + return toReturn +} + +// assertOnlyPoolRouterStaker panics if the caller is not the pool, router, or staker contract. +func assertOnlyPoolRouterStaker() { + caller := std.PrevRealm().Addr() + + poolOnlyErr := common.PoolOnly(caller) + routerOnlyErr := common.RouterOnly(caller) + stakerOnlyErr := common.StakerOnly(caller) + + if poolOnlyErr != nil && routerOnlyErr != nil && stakerOnlyErr != nil { + panic(errNoPermission) + } +} + +// assertOnlyGovStaker panics if the caller is not the gov/staker contract. +func assertOnlyGovStaker() { + caller := std.PrevRealm().Addr() + if err := common.GovStakerOnly(caller); err != nil { + panic(err.Error()) + } +} + +func makeEventString(tokenPath string, amount uint64) string { + return tokenPath + "*FEE*" + ufmt.Sprintf("%d", amount) +} diff --git a/protocol_fee/token_list_with_amount_test.gno b/protocol_fee/token_list_with_amount_test.gno new file mode 100644 index 000000000..c6767d2d4 --- /dev/null +++ b/protocol_fee/token_list_with_amount_test.gno @@ -0,0 +1,237 @@ +package protocol_fee + +import ( + "std" + "testing" + + "gno.land/p/demo/uassert" + + "gno.land/r/gnoswap/v1/common" + "gno.land/r/gnoswap/v1/consts" + + _ "gno.land/r/onbloc/baz" + _ "gno.land/r/onbloc/foo" +) + +var ( + dummyRealm = std.NewCodeRealm("gno.land/r/dummy") + + adminAddr = consts.ADMIN + adminUser = common.AddrToUser(adminAddr) + adminRealm = std.NewUserRealm(adminAddr) +) + +func TestTokenList(t *testing.T) { + tokenListWithAmount = map[string]uint64{ + "gno.land/r/foo": 100, + "gno.land/r/bar": 0, + "gno.land/r/baz": 200, + } + + uassert.Equal(t, len(TokenList(true)), 2) + uassert.Equal(t, len(TokenList(false)), 3) +} + +func TestAddToProtocolFee(t *testing.T) { + tokenListWithAmount = map[string]uint64{} + + tests := []struct { + name string + tokenPath string + amount uint64 + want uint64 + }{ + { + name: "add foo to protocol fee", + tokenPath: "gno.land/r/foo", + amount: 100, + want: 100, + }, + { + name: "add baz to protocol fee", + tokenPath: "gno.land/r/baz", + amount: 50, + want: 50, + }, + { + name: "add more baz to protocol fee", + tokenPath: "gno.land/r/baz", + amount: 10, + want: 60, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + std.TestSetRealm(std.NewCodeRealm(consts.POOL_PATH)) + AddToProtocolFee(test.tokenPath, test.amount) + + uassert.Equal(t, tokenListWithAmount[test.tokenPath], test.want) + }) + } +} + +func TestClearTokenListWithAmount(t *testing.T) { + tokenListWithAmount = map[string]uint64{ + "gno.land/r/foo": 100, + "gno.land/r/baz": 200, + } + + tests := []struct { + name string + prevRealm std.Realm + want map[string]uint64 + shouldPanic bool + panicMsg string + }{ + { + name: "no permission to clear", + prevRealm: dummyRealm, + shouldPanic: true, + panicMsg: "caller(g1lvx5ssxvuz5tttx6uza3myv8xy6w36a46fv7sy) has no permission", + }, + { + name: "clear protocol fee", + prevRealm: std.NewCodeRealm(consts.GOV_STAKER_PATH), + want: map[string]uint64{}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + std.TestSetRealm(test.prevRealm) + + if test.shouldPanic { + uassert.PanicsWithMessage(t, test.panicMsg, func() { + ClearTokenListWithAmount() + }) + } else { + ClearTokenListWithAmount() + uassert.Equal(t, len(tokenListWithAmount), len(test.want)) + } + }) + } +} + +func TestTransferProtocolFee(t *testing.T) { + // change devOpsPct to 49% (51% is for gov/staker) + devOpsPct = 4900 + + // send(and add) to protocol fee + transferToProtocolFee(t, "gno.land/r/onbloc/foo", 100) + transferToProtocolFee(t, "gno.land/r/onbloc/baz", 201) + + // call TransferProtocolFee + std.TestSetRealm(std.NewCodeRealm(consts.GOV_STAKER_PATH)) + + devOpsOldFoo := common.BalanceOf("gno.land/r/onbloc/foo", consts.DEV_OPS) + devOpsOldBaz := common.BalanceOf("gno.land/r/onbloc/baz", consts.DEV_OPS) + govStkaerOldFoo := common.BalanceOf("gno.land/r/onbloc/foo", consts.GOV_STAKER_ADDR) + govStkaerOldBaz := common.BalanceOf("gno.land/r/onbloc/baz", consts.GOV_STAKER_ADDR) + uassert.Equal(t, devOpsOldFoo, uint64(0)) + uassert.Equal(t, devOpsOldBaz, uint64(0)) + uassert.Equal(t, govStkaerOldFoo, uint64(0)) + uassert.Equal(t, govStkaerOldBaz, uint64(0)) + + sentToGovStaker := TransferProtocolFee() + // foo 100 + // -> devOps 49% => 49 + // -> gov/staker 51% => 51 + + // baz 201 + // -> devOps 49% => 98 + // -> gov/staker 51% => 103 + + // emitted event + // EVENTS: [{"type":"TransferProtocolFee","attrs":[{"key":"prevAddr","value":"g17e3ykyqk9jmqe2y9wxe9zhep3p7cw56davjqwa"},{"key":"prevRealm","value":"gno.land/r/gnoswap/v1/gov/staker"},{"key":"toDevOps","value":"gno.land/r/onbloc/foo*FEE*49,gno.land/r/onbloc/baz*FEE*98"},{"key":"toGovStaker","value":"gno.land/r/onbloc/foo*FEE*51,gno.land/r/onbloc/baz*FEE*103"}],"pkg_path":"gno.land/r/gnoswap/v1/protocol_fee","func":"TransferProtocolFee"}] + + devOpsNewFoo := common.BalanceOf("gno.land/r/onbloc/foo", consts.DEV_OPS) + devOpsNewBaz := common.BalanceOf("gno.land/r/onbloc/baz", consts.DEV_OPS) + uassert.Equal(t, devOpsNewFoo, uint64(49)) + uassert.Equal(t, devOpsNewBaz, uint64(98)) + + govStkaerNewFoo := common.BalanceOf("gno.land/r/onbloc/foo", consts.GOV_STAKER_ADDR) + govStkaerNewBaz := common.BalanceOf("gno.land/r/onbloc/baz", consts.GOV_STAKER_ADDR) + uassert.Equal(t, govStkaerNewFoo, uint64(51)) + uassert.Equal(t, govStkaerNewBaz, uint64(103)) + + uassert.Equal(t, len(sentToGovStaker), 2) + uassert.Equal(t, sentToGovStaker["gno.land/r/onbloc/foo"], uint64(51)) + uassert.Equal(t, sentToGovStaker["gno.land/r/onbloc/baz"], uint64(103)) +} + +func TestAssertOnlyPoolRouterStaker(t *testing.T) { + tests := []struct { + name string + prevRealm std.Realm + shouldPanic bool + panicMsg string + }{ + { + name: "caller is pool contract", + prevRealm: std.NewCodeRealm(consts.POOL_PATH), + }, + { + name: "caller is router contract", + prevRealm: std.NewCodeRealm(consts.ROUTER_PATH), + }, + { + name: "caller is staker contract", + prevRealm: std.NewCodeRealm(consts.STAKER_PATH), + }, + { + name: "caller is stranger", + prevRealm: dummyRealm, + shouldPanic: true, + panicMsg: "[GNOSWAP-PROTOCOL_FEE-001] caller has no permission", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + std.TestSetRealm(test.prevRealm) + + if test.shouldPanic { + uassert.PanicsWithMessage(t, test.panicMsg, func() { + assertOnlyPoolRouterStaker() + }) + } else { + uassert.NotPanics(t, func() { + assertOnlyPoolRouterStaker() + }) + } + }) + } +} + +func TestAssertOnlyGovStaker(t *testing.T) { + tests := []struct { + name string + prevRealm std.Realm + shouldPanic bool + panicMsg string + }{ + { + name: "caller is gov/staker contract", + prevRealm: std.NewCodeRealm(consts.GOV_STAKER_PATH), + }, + { + name: "caller is stranger", + prevRealm: dummyRealm, + shouldPanic: true, + panicMsg: "[GNOSWAP-PROTOCOL_FEE-001] caller has no permission", + }, + } +} + +// helper +func transferToProtocolFee(t *testing.T, tokenPath string, amount uint64) { + t.Helper() + + std.TestSetRealm(adminRealm) + + tokenTeller := common.GetTokenTeller(tokenPath) + tokenTeller.Transfer(consts.PROTOCOL_FEE_ADDR, amount) + + tokenListWithAmount[tokenPath] += amount +} diff --git a/protocol_fee/utils.gno b/protocol_fee/utils.gno index ad8b9fb56..65a8b670a 100644 --- a/protocol_fee/utils.gno +++ b/protocol_fee/utils.gno @@ -2,13 +2,16 @@ package protocol_fee import ( "std" -) -func isUserCall() bool { - return std.PrevRealm().IsUser() -} + "gno.land/r/gnoswap/v1/common" +) func getPrev() (string, string) { prev := std.PrevRealm() return prev.Addr().String(), prev.PkgPath() } + +// assertOnlyNotHalted panics if the contract is halted. +func assertOnlyNotHalted() { + common.IsHalted() +} From 3b9f8df2d67c7e9ccd881b1bbc6c04b7acdae917 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Fri, 17 Jan 2025 15:18:48 +0900 Subject: [PATCH 2/7] feat: `pool` adds token(+amount) to protocol_fee --- pool/pool_manager.gno | 4 ++++ pool/protocol_fee_withdrawal.gno | 4 ++++ pool/protocol_fee_withdrawal_test.gno | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pool/pool_manager.gno b/pool/pool_manager.gno index 8edcb1af9..2248ea447 100644 --- a/pool/pool_manager.gno +++ b/pool/pool_manager.gno @@ -11,7 +11,10 @@ import ( "gno.land/r/gnoswap/v1/common" "gno.land/r/gnoswap/v1/consts" + en "gno.land/r/gnoswap/v1/emission" + pf "gno.land/r/gnoswap/v1/protocol_fee" + "gno.land/r/gnoswap/v1/gns" ) @@ -189,6 +192,7 @@ func CreatePool( if poolCreationFee > 0 { gns.TransferFrom(a2u(std.PrevRealm().Addr()), a2u(consts.PROTOCOL_FEE_ADDR), poolCreationFee) + pf.AddToProtocolFee(consts.GNS_PATH, poolCreationFee) std.Emit( "PoolCreationFee", diff --git a/pool/protocol_fee_withdrawal.gno b/pool/protocol_fee_withdrawal.gno index d7d208b9b..80dc72451 100644 --- a/pool/protocol_fee_withdrawal.gno +++ b/pool/protocol_fee_withdrawal.gno @@ -5,8 +5,10 @@ import ( "gno.land/p/demo/ufmt" u256 "gno.land/p/gnoswap/uint256" + "gno.land/r/gnoswap/v1/common" "gno.land/r/gnoswap/v1/consts" + pf "gno.land/r/gnoswap/v1/protocol_fee" ) // withdrawalFeeBPS is the fee that is charged when a user withdraws their collected fees @@ -68,9 +70,11 @@ func HandleWithdrawalFee( token0Teller := common.GetTokenTeller(token0Path) checkTransferError(token0Teller.TransferFrom(positionCaller, consts.PROTOCOL_FEE_ADDR, feeAmount0.Uint64())) + pf.AddToProtocolFee(token0Path, feeAmount0.Uint64()) token1Teller := common.GetTokenTeller(token1Path) checkTransferError(token1Teller.TransferFrom(positionCaller, consts.PROTOCOL_FEE_ADDR, feeAmount1.Uint64())) + pf.AddToProtocolFee(token1Path, feeAmount1.Uint64()) prevAddr, prevPkgPath := getPrevAsString() std.Emit( diff --git a/pool/protocol_fee_withdrawal_test.gno b/pool/protocol_fee_withdrawal_test.gno index 7cbac5d39..53f9e0668 100644 --- a/pool/protocol_fee_withdrawal_test.gno +++ b/pool/protocol_fee_withdrawal_test.gno @@ -46,7 +46,7 @@ func TestHandleWithdrawalFee(t *testing.T) { HandleWithdrawalFee(0, "pkgPath", "1000", "pkgPath", "1000", "poolPath", users.Resolve(admin)) }, verify: nil, - expected: "[GNOSWAP-COMMON-004] token is not registered || token(pkgPath) is not registered", + expected: "[GNOSWAP-COMMON-004] token is not registered || token(pkgPath)", shouldPanic: true, }, { From 0449d07b12cfe767cedea141b4de7f5cd2ddd7fb Mon Sep 17 00:00:00 2001 From: n3wbie Date: Fri, 17 Jan 2025 15:18:58 +0900 Subject: [PATCH 3/7] feat: `router` adds token(+amount) to protocol_fee --- router/protocol_fee_swap.gno | 3 +++ 1 file changed, 3 insertions(+) diff --git a/router/protocol_fee_swap.gno b/router/protocol_fee_swap.gno index 362620293..067a60ff2 100644 --- a/router/protocol_fee_swap.gno +++ b/router/protocol_fee_swap.gno @@ -9,6 +9,8 @@ import ( "gno.land/p/demo/ufmt" u256 "gno.land/p/gnoswap/uint256" + + pf "gno.land/r/gnoswap/v1/protocol_fee" ) const ( @@ -99,6 +101,7 @@ func handleSwapFee( outputTeller := common.GetTokenTeller(outputToken) outputTeller.TransferFrom(std.PrevRealm().Addr(), consts.PROTOCOL_FEE_ADDR, feeAmountUint64) + pf.AddToProtocolFee(outputToken, feeAmountUint64) prevAddr, prevRealm := getPrev() From d38ad21ecbd8a821501ebb520cbd8297b548bb96 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Fri, 17 Jan 2025 15:23:14 +0900 Subject: [PATCH 4/7] feat: `staker` adds token(+amount) to protocol_fee --- staker/protocol_fee_unstaking.gno | 3 +++ 1 file changed, 3 insertions(+) diff --git a/staker/protocol_fee_unstaking.gno b/staker/protocol_fee_unstaking.gno index 42b11eb25..82c04e688 100644 --- a/staker/protocol_fee_unstaking.gno +++ b/staker/protocol_fee_unstaking.gno @@ -49,6 +49,8 @@ func handleUnstakingFee( if internal { // staker contract has fee gns.Transfer(a2u(consts.PROTOCOL_FEE_ADDR), feeAmount) + pf.AddToProtocolFee(consts.GNS_PATH, feeAmount) + std.Emit( "ProtocolFeeInternalReward", "prevAddr", prevAddr, @@ -62,6 +64,7 @@ func handleUnstakingFee( // external contract has fee teller := common.GetTokenTeller(tokenPath) teller.Transfer(consts.PROTOCOL_FEE_ADDR, feeAmount) + pf.AddToProtocolFee(tokenPath, feeAmount) std.Emit( "ProtocolFeeExternalReward", From ad464fca7922b2f00b5db4aa0a06efe3d8b2e383 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Sun, 19 Jan 2025 10:44:26 +0900 Subject: [PATCH 5/7] fix: amount and balance checking --- protocol_fee/token_list_with_amount.gno | 26 ++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/protocol_fee/token_list_with_amount.gno b/protocol_fee/token_list_with_amount.gno index 396d3e6e9..772cfbb1c 100644 --- a/protocol_fee/token_list_with_amount.gno +++ b/protocol_fee/token_list_with_amount.gno @@ -14,7 +14,7 @@ var ( tokenListWithAmount = make(map[string]uint64) // tokenPath -> amount ) -// TokenList returns only the token path. +// TokenList returns only the list of token path. // If positive is true, it returns only the token path with amount > 0. // If positive is false, it returns all the token path. func TokenList(positive bool) []string { @@ -47,7 +47,7 @@ func AddToProtocolFee(tokenPath string, amount uint64) { // only `gov/staker` can execute this function. func ClearTokenListWithAmount() { assertOnlyGovStaker() - tokenListWithAmount = map[string]uint64{} + clearTokenListWithAmount() } // TransferProtocolFee transfers the protocol fee to devOps and gov/staker. @@ -62,12 +62,17 @@ func TransferProtocolFee() map[string]uint64 { for token, amount := range tokenListWithAmount { balance := common.BalanceOf(token, consts.PROTOCOL_FEE_ADDR) - // amount in `tokenListWithAmount` is corrupted, it should be equal to balance - if amount != balance { - panic(errInvalidAmount.Error()) + // anyone can just send certain grc20 token to `protocol_fee` contract + // therefore, we don't need any guard logic to check whether protocol_fee's xxx token balance is equal to `amount` + // however, amount always should be less than or equal to balance + if amount > balance { + panic(addDetailToError( + errInvalidAmount, + ufmt.Sprintf("amount: %d should be less than or equal to balance: %d", amount, balance), + )) } - if balance > 0 { + if amount > 0 { toDevOps := balance * devOpsPct / 10000 // default 0% toGovStaker := balance - toDevOps // default 100% @@ -86,7 +91,7 @@ func TransferProtocolFee() map[string]uint64 { } } - ClearTokenListWithAmount() + clearTokenListWithAmount() prevAddr, prevRealm := getPrev() std.Emit( @@ -100,6 +105,11 @@ func TransferProtocolFee() map[string]uint64 { return toReturn } +// clearTokenListWithAmount clears the tokenListWithAmount. +func clearTokenListWithAmount() { + tokenListWithAmount = map[string]uint64{} +} + // assertOnlyPoolRouterStaker panics if the caller is not the pool, router, or staker contract. func assertOnlyPoolRouterStaker() { caller := std.PrevRealm().Addr() @@ -121,6 +131,8 @@ func assertOnlyGovStaker() { } } +// assert + func makeEventString(tokenPath string, amount uint64) string { return tokenPath + "*FEE*" + ufmt.Sprintf("%d", amount) } From e058f8c5df6240f664e3a3f2329629c23fd69b79 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Sun, 19 Jan 2025 10:49:13 +0900 Subject: [PATCH 6/7] chore --- protocol_fee/token_list_with_amount.gno | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/protocol_fee/token_list_with_amount.gno b/protocol_fee/token_list_with_amount.gno index 772cfbb1c..ef600d73f 100644 --- a/protocol_fee/token_list_with_amount.gno +++ b/protocol_fee/token_list_with_amount.gno @@ -51,6 +51,7 @@ func ClearTokenListWithAmount() { } // TransferProtocolFee transfers the protocol fee to devOps and gov/staker. +// only `gov/staker` can execute this function. // It returns list of token with amount has been sent to gov/staker. func TransferProtocolFee() map[string]uint64 { assertOnlyGovStaker() @@ -131,8 +132,6 @@ func assertOnlyGovStaker() { } } -// assert - func makeEventString(tokenPath string, amount uint64) string { return tokenPath + "*FEE*" + ufmt.Sprintf("%d", amount) } From 62a17c1f103da31ed03fd9d8eb75c9b563784aca Mon Sep 17 00:00:00 2001 From: Dongwon <74406335+dongwon8247@users.noreply.github.com> Date: Sun, 19 Jan 2025 16:13:11 +0900 Subject: [PATCH 7/7] Update protocol_fee/token_list_with_amount_test.gno Co-authored-by: Lee ByeongJun --- protocol_fee/token_list_with_amount_test.gno | 2 -- 1 file changed, 2 deletions(-) diff --git a/protocol_fee/token_list_with_amount_test.gno b/protocol_fee/token_list_with_amount_test.gno index c6767d2d4..12d1dd0f9 100644 --- a/protocol_fee/token_list_with_amount_test.gno +++ b/protocol_fee/token_list_with_amount_test.gno @@ -9,8 +9,6 @@ import ( "gno.land/r/gnoswap/v1/common" "gno.land/r/gnoswap/v1/consts" - _ "gno.land/r/onbloc/baz" - _ "gno.land/r/onbloc/foo" ) var (