Skip to content

Commit

Permalink
GSW-1968 refactor: common contract
Browse files Browse the repository at this point in the history
- Math function-focused modifications
  • Loading branch information
onlyhyde committed Dec 21, 2024
1 parent cf9d52f commit 71a0c2d
Show file tree
Hide file tree
Showing 15 changed files with 980 additions and 174 deletions.
12 changes: 10 additions & 2 deletions _deploy/r/gnoswap/common/access.gno
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const (
ErrNoPermission = "caller(%s) has no permission"
)

// AssertCaller checks if the caller is the given address.
func AssertCaller(caller, addr std.Address) error {
if caller != addr {
return ufmt.Errorf(ErrNoPermission, caller.String())
Expand All @@ -25,55 +26,63 @@ func SatisfyCond(cond bool) error {
return nil
}

// AdminOnly checks if the caller is the admin.
func AdminOnly(caller std.Address) error {
if caller != consts.ADMIN {
return ufmt.Errorf(ErrNoPermission, caller.String())
}
return nil
}

// GovernanceOnly checks if the caller is the gov governance contract.
func GovernanceOnly(caller std.Address) error {
if caller != consts.GOV_GOVERNANCE_ADDR {
return ufmt.Errorf(ErrNoPermission, caller.String())
}
return nil
}

// GovStakerOnly checks if the caller is the gov staker contract.
func GovStakerOnly(caller std.Address) error {
if caller != consts.GOV_STAKER_ADDR {
return ufmt.Errorf(ErrNoPermission, caller.String())
}
return nil
}

// RouterOnly checks if the caller is the router contract.
func RouterOnly(caller std.Address) error {
if caller != consts.ROUTER_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 {
return ufmt.Errorf(ErrNoPermission, caller.String())
}
return nil
}

// StakerOnly checks if the caller is the staker contract.
func StakerOnly(caller std.Address) error {
if caller != consts.STAKER_ADDR {
return ufmt.Errorf(ErrNoPermission, caller.String())
}
return nil
}

// LaunchpadOnly checks if the caller is the launchpad contract.
func LaunchpadOnly(caller std.Address) error {
if caller != consts.LAUNCHPAD_ADDR {
return ufmt.Errorf(ErrNoPermission, caller.String())
}
return nil
}

// EmissionOnly checks if the caller is the emission contract.
func EmissionOnly(caller std.Address) error {
if caller != consts.EMISSION_ADDR {
return ufmt.Errorf(ErrNoPermission, caller.String())
Expand All @@ -90,8 +99,7 @@ func TokenRegisterOnly(caller std.Address) error {
return nil
}

// realm assertion

// UserOnly checks if the caller is a user.
func UserOnly(prev std.Realm) error {
if !prev.IsUser() {
return ufmt.Errorf("caller(%s) is not a user", prev.PkgPath())
Expand Down
2 changes: 1 addition & 1 deletion _deploy/r/gnoswap/common/address_and_username.gno
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ func UserToAddr(user pusers.AddressOrName) std.Address {
// It panics with a detailed error message if the address is invalid.
func assertValidAddr(addr std.Address) {
if !addr.IsValid() {
panic(addDetailToError(errInvalidAddr, addr.String()))
panic(newErrorWithDetail(errInvalidAddr, addr.String()))
}
}
16 changes: 13 additions & 3 deletions _deploy/r/gnoswap/common/errors.gno
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,19 @@ var (
errInvalidAddr = errors.New("[GNOSWAP-COMMON-005] invalid address")
errOverflow = errors.New("[GNOSWAP-COMMON-006] overflow")
errInvalidTokenId = errors.New("[GNOSWAP-COMMON-007] invalid tokenId")
errInvalidInput = errors.New("[GNOSWAP-COMMON-008] invalid input data")
errOverFlow = errors.New("[GNOSWAP-COMMON-009] overflow")
errIdenticalTicks = errors.New("[GNOSWAP-COMMON-010] identical ticks")
)

func addDetailToError(err error, detail string) string {
finalErr := ufmt.Errorf("%s || %s", err.Error(), detail)
return finalErr.Error()
// newErrorWithDetail appends additional context or details to an existing error message.
//
// Parameters:
// - err: The original error (error).
// - detail: Additional context or detail to append to the error message (string).
//
// Returns:
// - string: The combined error message in the format "<original_error> || <detail>".
func newErrorWithDetail(err error, detail string) string {
return ufmt.Errorf("%s || %s", err.Error(), detail).Error()
}
4 changes: 2 additions & 2 deletions _deploy/r/gnoswap/common/grc20reg_helper.gno
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func IsRegistered(path string) error {
// if token is not registered, it will panic
func MustRegistered(path string) {
if err := IsRegistered(path); err != nil {
panic(addDetailToError(
panic(newErrorWithDetail(
errNotRegistered,
ufmt.Sprintf("token(%s)", path),
ufmt.Sprintf("token(%s) is not registered", path),
))
}
}
Expand Down
4 changes: 2 additions & 2 deletions _deploy/r/gnoswap/common/grc721_token_id.gno
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
// output: grc721.TokenID
func TokenIdFrom(tokenId interface{}) grc721.TokenID {
if tokenId == nil {
panic(addDetailToError(
panic(newErrorWithDetail(
errInvalidTokenId,
"can not be nil",
))
Expand All @@ -33,7 +33,7 @@ func TokenIdFrom(tokenId interface{}) grc721.TokenID {
return tokenId.(grc721.TokenID)
default:
estimatedType := ufmt.Sprintf("%T", tokenId)
panic(addDetailToError(
panic(newErrorWithDetail(
errInvalidTokenId,
ufmt.Sprintf("unsupported tokenId type: %s", estimatedType),
))
Expand Down
105 changes: 52 additions & 53 deletions _deploy/r/gnoswap/common/halt.gno
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,49 @@ import (
"std"

"gno.land/p/demo/ufmt"

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

var (
halted bool = false
)
// halted is a global flag that indicates whether the system is currently halted.
// When true, most operations are disabled to prevent further actions.
// Default value is false, meaning the system is active by default.
var halted bool = false

// GetHalt returns the current halted status of the system.
//
// Returns:
// - bool: true if the system is halted, false otherwise.
func GetHalt() bool {
return halted
}

// IsHalted checks if the system is currently halted.
// If the system is halted, the function panics with an errHalted error.
//
// Panics:
// - If the halted flag is true, indicating that the system is inactive.
func IsHalted() {
if halted {
panic(addDetailToError(
panic(newErrorWithDetail(
errHalted,
"gnoswap halted",
"GnoSwap is halted",
))
}
}

// SetHaltByAdmin sets the halt status.
// SetHaltByAdmin allows an admin to set the halt status of the system.
// Only an admin can execute this function. If a non-admin attempts to call this function,
// the function panics with an errNoPermission error.
//
// Parameters:
// - halt (bool): The new halt status to set (true to halt, false to unhalt).
//
// Panics:
// - If the caller is not an admin, the function will panic with an errNoPermission error.
func SetHaltByAdmin(halt bool) {
caller := std.PrevRealm().Addr()
err := AdminOnly(caller)
if err != nil {
panic(addDetailToError(
caller := getPrevAddr()
if err := AdminOnly(caller); err != nil {
panic(newErrorWithDetail(
errNoPermission,
ufmt.Sprintf(
"only admin(%s) can set halt, called from %s",
Expand All @@ -39,34 +55,22 @@ func SetHaltByAdmin(halt bool) {
),
))
}

setHalt(halt)

prevAddr, prevRealm := getPrev()
if halt {
std.Emit(
"SetHaltByAdmin",
"prevAddr", prevAddr,
"prevRealm", prevRealm,
"halt", ufmt.Sprintf("%t", halt),
)
} else {
std.Emit(
"UnsetHaltByAdmin",
"prevAddr", prevAddr,
"prevRealm", prevRealm,
"halt", ufmt.Sprintf("%t", halt),
)
}
}

// SetHalt sets the halt status.
// Only governance contract can execute this function via proposal
// SetHalt allows the governance contract to set the halt status of the system.
// Only the governance contract can execute this function through a proposal process.
// If the caller is not the governance contract, the function panics with an errNoPermission error.
//
// Parameters:
// - halt (bool): The new halt status to set (true to halt, false to unhalt).
//
// Panics:
// - If the caller is not the governance contract, the function will panic with an errNoPermission error.
func SetHalt(halt bool) {
caller := std.PrevRealm().Addr()
err := GovernanceOnly(caller)
if err != nil {
panic(addDetailToError(
caller := getPrevAddr()
if err := GovernanceOnly(caller); err != nil {
panic(newErrorWithDetail(
errNoPermission,
ufmt.Sprintf(
"only governance(%s) can set halt, called from %s",
Expand All @@ -75,27 +79,22 @@ func SetHalt(halt bool) {
),
))
}

setHalt(halt)

prevAddr, prevRealm := getPrev()
if halt {
std.Emit(
"SetHalt",
"prevAddr", prevAddr,
"prevRealm", prevRealm,
"halt", ufmt.Sprintf("%t", halt),
)
} else {
std.Emit(
"UnsetHalt",
"prevAddr", prevAddr,
"prevRealm", prevRealm,
"halt", ufmt.Sprintf("%t", halt),
)
}
}

// setHalt updates the halted flag to the specified value.
// This is an internal function that should only be called by SetHalt or SetHaltByAdmin.
//
// Parameters:
// - halt (bool): The new halt status to set.
func setHalt(halt bool) {
halted = halt

prevAddr, prevRealm := getPrevAsString()
std.Emit(
"setHalt",
"prevAddr", prevAddr,
"prevRealm", prevRealm,
"halt", ufmt.Sprintf("%t", halt),
)
}
44 changes: 34 additions & 10 deletions _deploy/r/gnoswap/common/limit_caller.gno
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,49 @@ import (
"std"

"gno.land/p/demo/ufmt"

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

var (
limitCaller bool = true
)
// limitCaller is a global boolean flag that controls whether function calls are restricted.
// Default value is true, meaning call restrictions are enabled by default.
var limitCaller bool = true

// GetLimitCaller returns the current state of the limitCaller flag.
// If true, call restrictions are active; if false, call restrictions are disabled.
//
// Returns:
// - bool: Current state of the limitCaller (true if active, false if inactive).
func GetLimitCaller() bool {
return limitCaller
}

// SetLimitCaller updates the limitCaller flag to either enable or disable call restrictions.
// This function can only be called by an admin. If a non-admin attempts to call this function,
// the function will panic.
//
// Parameters:
// - v (bool): The new state for the limitCaller flag (true to enable, false to disable).
//
// Panics:
// - If the caller is not an admin, the function panics with an errNoPermission error.
func SetLimitCaller(v bool) {
caller := std.PrevRealm().Addr()
if caller != consts.ADMIN {
panic(addDetailToError(
caller := getPrevAddr()
if err := AdminOnly(caller); err != nil {
panic(newErrorWithDetail(
errNoPermission,
ufmt.Sprintf("limit_caller.gno__SetLimitCaller() || only admin(%s) can set limit caller, called from %s", consts.ADMIN, caller),
))
ufmt.Sprintf(
"only Admin can set halt, called from %s",
caller,
)),
)
}

limitCaller = v

prevAddr, prevPkgPath := getPrevAsString()
std.Emit(
"SetLimitCaller",
"prevAddr", prevAddr,
"prevRealm", prevPkgPath,
"halt", ufmt.Sprintf("%t", v),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,23 @@ import (
"testing"

"gno.land/p/demo/uassert"

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

var adminRealm = std.NewUserRealm(consts.ADMIN)

func TestSetLimitCaller(t *testing.T) {
t.Run("initial check", func(t *testing.T) {
uassert.True(t, GetLimitCaller())
})

t.Run("with non-admin privilege, panics", func(t *testing.T) {
uassert.PanicsWithMessage(t,
`[GNOSWAP-COMMON-001] caller has no permission || limit_caller.gno__SetLimitCaller() || only admin(g17290cwvmrapvp869xfnhhawa8sm9edpufzat7d) can set limit caller, called from g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm`,
`[GNOSWAP-COMMON-001] caller has no permission || only Admin can set halt, called from g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm`,
func() { SetLimitCaller(false) },
)
})

t.Run("with admin privilege, success", func(t *testing.T) {
std.TestSetRealm(adminRealm)
std.TestSetRealm(std.NewUserRealm(consts.ADMIN))
SetLimitCaller(false)
uassert.False(t, GetLimitCaller())
})
Expand Down
Loading

0 comments on commit 71a0c2d

Please sign in to comment.