From 074a2412726f41bf22131c6c4efb39de8dc48cf0 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Mon, 29 Jan 2024 14:01:37 +0300 Subject: [PATCH] [#74] proxy: Allow to own NNS domains Because `Verify` is flexible enough, any funds transferred to the proxy contract can be moved out with the help of the committee. Thus, implementing onNEP11Payment() is enough. Signed-off-by: Evgenii Stratonikov --- proxy/proxy_contract.go | 9 +++++++++ tests/nns_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/proxy/proxy_contract.go b/proxy/proxy_contract.go index d9c1515..613bc17 100644 --- a/proxy/proxy_contract.go +++ b/proxy/proxy_contract.go @@ -19,6 +19,15 @@ func OnNEP17Payment(from interop.Hash160, amount int, data any) { } } +// OnNEP11Payment is a callback for NEP-11 compatible NNS contract. +func OnNEP11Payment(from interop.Hash160, amount int, token []byte, data any) { + caller := runtime.GetCallingScriptHash() + nnsHash := management.GetContractByID(1).Hash + if !common.BytesEqual(caller, []byte(nnsHash)) { + common.AbortWithMessage("proxy contract accepts NNS tokens only") + } +} + func _deploy(data any, isUpdate bool) { if isUpdate { args := data.([]any) diff --git a/tests/nns_test.go b/tests/nns_test.go index 6eeb3b6..dc2621c 100644 --- a/tests/nns_test.go +++ b/tests/nns_test.go @@ -10,7 +10,10 @@ import ( "git.frostfs.info/TrueCloudLab/frostfs-contract/nns" "github.com/nspcc-dev/neo-go/pkg/core/interop/storage" + "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/neotest" + "github.com/nspcc-dev/neo-go/pkg/rpcclient/gas" + "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/stretchr/testify/require" ) @@ -395,3 +398,34 @@ func TestNNSResolve(t *testing.T) { c.Invoke(t, records, "resolve", "test.com.", int64(nns.TXT)) c.InvokeFail(t, "invalid domain name format", "resolve", "test.com..", int64(nns.TXT)) } + +func TestNNSAndProxy(t *testing.T) { + c := newNNSInvoker(t, false) + proxyHash := deployProxyContract(t, c.Executor) + proxySigner := neotest.NewContractSigner(proxyHash, func(*transaction.Transaction) []any { return nil }) + + g := c.NewInvoker(gas.Hash, c.Validator) + g.Invoke(t, true, "transfer", + c.Validator.ScriptHash(), proxyHash, 100_0000_0000, nil) + + cc := c.WithSigners(proxySigner, c.Committee) + cc.Invoke(t, true, "register", "ns", proxyHash, + "ops@frostfs.info", 100, 100, 100, 100) + + checkBalance := func(t *testing.T, owner util.Uint160, balance int64) { + s, err := cc.TestInvoke(t, "balanceOf", owner) + require.NoError(t, err) + require.Equal(t, 1, s.Len()) + require.Equal(t, int64(balance), s.Pop().BigInt().Int64()) + } + + checkBalance(t, proxyHash, 1) + checkBalance(t, c.CommitteeHash, 0) + + t.Run("ensure domain is not lost", func(t *testing.T) { + cc.Invoke(t, true, "transfer", c.CommitteeHash, "ns", nil) + + checkBalance(t, proxyHash, 0) + checkBalance(t, c.CommitteeHash, 1) + }) +}