Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expect full denoms in Banker.IssueCoin and Banker.RemoveCoin #2107

Closed
thehowl opened this issue May 14, 2024 · 1 comment · Fixed by #3239
Closed

Expect full denoms in Banker.IssueCoin and Banker.RemoveCoin #2107

thehowl opened this issue May 14, 2024 · 1 comment · Fixed by #3239
Assignees

Comments

@thehowl
Copy link
Member

thehowl commented May 14, 2024

From #875 (review):

That said, soon after this is merged, I think we'll need to change this API again. This current implementation creates an inconsistency within the Banker API. All other banker methods now require you to pass in the full realm path to the token you're referring to, but IssueCoin and RemoveCoin do not.

Thus, I think a few more changes are in order:

  1. There should be a RealmDenom(pkgpath, denom string) function in std, which creates a realm denomination (ie. /gno.land/r/morgan:bitcoin). There can be a helper method Realm.Denom(denom string) (so you can do std.CurrentRealm().Denom("bitcoin")
  2. Instead of modifying denom's value in the native function, we should check it matches what we expect. ie. strings.HasPrefix(denom, RealmDenom(std.CurrentRealm().PkgPath()), then check the last part of the denom to see that it matches the Gno regex. (This can all be done in gno, without needing to put it in native code)

Related with #1475 #1576

@MikaelVallenet
Copy link
Member

I will start to work on it in few days after finishing time pkg PR

@Kouteki Kouteki moved this from Todo to In Progress in 🧙‍♂️gno.land core team Nov 29, 2024
thehowl added a commit that referenced this issue Dec 12, 2024
fix #2107 

--------------------------

## Problem

> From [#875
(review)](#875 (review)):
> 
> > That said, soon after this is merged, I think we'll need to change
this API again. This current implementation creates an inconsistency
within the Banker API. All other banker methods now require you to pass
in the full realm path to the token you're referring to, but IssueCoin
and RemoveCoin do not.
> > Thus, I think a few more changes are in order:
> > 
> > 1. There should be a `RealmDenom(pkgpath, denom string)` function in
`std`, which creates a realm denomination (ie.
`/gno.land/r/morgan:bitcoin`). There can be a helper method
`Realm.Denom(denom string)` (so you can do
`std.CurrentRealm().Denom("bitcoin")`
> > 2. Instead of modifying `denom`'s value in the native function, we
should check it matches what we expect. ie. `strings.HasPrefix(denom,
RealmDenom(std.CurrentRealm().PkgPath())`, then check the last part of
the denom to see that it matches the Gno regex. (This can all be done in
gno, without needing to put it in native code)
> 
> Related with #1475 #1576

-------------------------

## Solution

BREAKING CHANGE: All previous realm calling IssueCoin or RemoveCoin are
now expected to append the prefix "/" + realmPkgPath + ":" before the
denom, it should be done by using ``std.CurrentRealm().CoinDenom(denom
string)`` or by using ``std.CoinDenom(pkgPath, denom string)``

For now to avoid to mix coins and fix security issues like being able to
issue coins from other realm, when a realm issue a coin, the pkg path of
the realm is added as a prefix to the coin.

the thing is some function expect only the base denom ``bitcoin`` (issue
& remove) but the others like get require the qualified denom
``gno.land/r/demo/banktest:bitcoin``. it can be confusing

I also answer the requirements of the comment @thehowl made:

- Two functions are now available ``std.CoinDenom(pkgpath, demon
string)`` && the method ``std.Realm.CoinDenom(denom string)``
- the denom's value is changed in the `.gno` file and not the native.

Here is an example of how it looks like:

```go
func IssueNewCoin(denom string, amount int64) string {
	std.AssertOriginCall()
	banker := std.GetBanker(std.BankerTypeRealmIssue)
	addr := std.PrevRealm().Addr()
	banker.IssueCoin(addr, std.CurrentRealm().CoinDenom(denom), amount)
	return std.CurrentRealm().Denom(denom)
}

func RemoveCoin(denom string, amount int64) {
	std.AssertOriginCall()
	banker := std.GetBanker(std.BankerTypeRealmIssue)
	addr := std.PrevRealm().Addr()
	banker.RemoveCoin(addr, std.CurrentRealm().CoinDenom(denom), amount)
}

func GetCoins(denom string) uint64 {
	banker := std.GetBanker(std.BankerTypeReadonly)
	addr := std.PrevRealm().Addr()
	coins := banker.GetCoins(addr)
	for _, coin := range coins {
		if coin.Denom == std.CurrentRealm().CoinDenom(denom) {
			return uint64(coin.Amount)
		}
	}
	return 0
}
```

<details><summary>Contributors' checklist...</summary>

- [x] Added new tests, or not needed, or not feasible
- [x] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [x] Updated the official documentation or not needed
- [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [x] Added references to related issues and PRs
- [x] Provided any useful hints for running manual tests
</details>

---------

Co-authored-by: Morgan Bazalgette <[email protected]>
Co-authored-by: Leon Hudak <[email protected]>
@github-project-automation github-project-automation bot moved this from In Progress to Done in 🧙‍♂️gno.land core team Dec 12, 2024
albttx pushed a commit that referenced this issue Jan 10, 2025
fix #2107 

--------------------------

## Problem

> From [#875
(review)](#875 (review)):
> 
> > That said, soon after this is merged, I think we'll need to change
this API again. This current implementation creates an inconsistency
within the Banker API. All other banker methods now require you to pass
in the full realm path to the token you're referring to, but IssueCoin
and RemoveCoin do not.
> > Thus, I think a few more changes are in order:
> > 
> > 1. There should be a `RealmDenom(pkgpath, denom string)` function in
`std`, which creates a realm denomination (ie.
`/gno.land/r/morgan:bitcoin`). There can be a helper method
`Realm.Denom(denom string)` (so you can do
`std.CurrentRealm().Denom("bitcoin")`
> > 2. Instead of modifying `denom`'s value in the native function, we
should check it matches what we expect. ie. `strings.HasPrefix(denom,
RealmDenom(std.CurrentRealm().PkgPath())`, then check the last part of
the denom to see that it matches the Gno regex. (This can all be done in
gno, without needing to put it in native code)
> 
> Related with #1475 #1576

-------------------------

## Solution

BREAKING CHANGE: All previous realm calling IssueCoin or RemoveCoin are
now expected to append the prefix "/" + realmPkgPath + ":" before the
denom, it should be done by using ``std.CurrentRealm().CoinDenom(denom
string)`` or by using ``std.CoinDenom(pkgPath, denom string)``

For now to avoid to mix coins and fix security issues like being able to
issue coins from other realm, when a realm issue a coin, the pkg path of
the realm is added as a prefix to the coin.

the thing is some function expect only the base denom ``bitcoin`` (issue
& remove) but the others like get require the qualified denom
``gno.land/r/demo/banktest:bitcoin``. it can be confusing

I also answer the requirements of the comment @thehowl made:

- Two functions are now available ``std.CoinDenom(pkgpath, demon
string)`` && the method ``std.Realm.CoinDenom(denom string)``
- the denom's value is changed in the `.gno` file and not the native.

Here is an example of how it looks like:

```go
func IssueNewCoin(denom string, amount int64) string {
	std.AssertOriginCall()
	banker := std.GetBanker(std.BankerTypeRealmIssue)
	addr := std.PrevRealm().Addr()
	banker.IssueCoin(addr, std.CurrentRealm().CoinDenom(denom), amount)
	return std.CurrentRealm().Denom(denom)
}

func RemoveCoin(denom string, amount int64) {
	std.AssertOriginCall()
	banker := std.GetBanker(std.BankerTypeRealmIssue)
	addr := std.PrevRealm().Addr()
	banker.RemoveCoin(addr, std.CurrentRealm().CoinDenom(denom), amount)
}

func GetCoins(denom string) uint64 {
	banker := std.GetBanker(std.BankerTypeReadonly)
	addr := std.PrevRealm().Addr()
	coins := banker.GetCoins(addr)
	for _, coin := range coins {
		if coin.Denom == std.CurrentRealm().CoinDenom(denom) {
			return uint64(coin.Amount)
		}
	}
	return 0
}
```

<details><summary>Contributors' checklist...</summary>

- [x] Added new tests, or not needed, or not feasible
- [x] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [x] Updated the official documentation or not needed
- [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [x] Added references to related issues and PRs
- [x] Provided any useful hints for running manual tests
</details>

---------

Co-authored-by: Morgan Bazalgette <[email protected]>
Co-authored-by: Leon Hudak <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Teritori (confirmed)
Development

Successfully merging a pull request may close this issue.

6 participants