Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

z5ad_transfer_voucher_native_coins_filetest.gno

5.68 Kb · 139 lines
  1// PKGPATH: gno.land/r/aib/main
  2package main
  3
  4// Regression test: an IBC voucher Transfer that attaches native coins via the
  5// tx send field must be rejected, mirroring the guard the GRC20 branch already
  6// enforces. The voucher GRC20 token is burnt in OnSendPacket, so any native
  7// coins sent alongside would be stuck at this realm.
  8//
  9// The voucher transfer is otherwise valid here (direct user call, existing
 10// voucher, sufficient balance), so the only reason it fails is the attached
 11// native coins.
 12
 13import (
 14	"chain"
 15	"encoding/hex"
 16	"testing"
 17	"time"
 18
 19	tmtesting "gno.land/p/aib/ibc/lightclient/tendermint/testing"
 20	"gno.land/p/aib/ibc/types"
 21
 22	"gno.land/p/aib/ics23"
 23	"gno.land/r/aib/ibc/apps/transfer"
 24	"gno.land/r/aib/ibc/core"
 25)
 26
 27func main(cur realm) {
 28	var (
 29		chainID        = "chain-id-2"
 30		trustedHeight  = types.NewHeight(2, 2)
 31		clientState    = tmtesting.NewClientState(chainID, trustedHeight)
 32		apphash, _     = hex.DecodeString("0eadf50c7992d8e1366b8ea63ab7d1346de4762c3d449764ef7dc404ba48381f")
 33		trustedValset  = tmtesting.GenValset()
 34		consensusState = tmtesting.GenConsensusState(time.Now(), apphash, trustedValset.Hash())
 35		counterpartyID = "07-tendermint-42"
 36	)
 37	clientID := core.CreateClient(cross(cur), clientState, consensusState)
 38	core.RegisterCounterparty(cross(cur), clientID, [][]byte{[]byte("iavlStoreKey"), []byte("prefix2")}, counterpartyID)
 39
 40	// The voucher owner is the signing EOA (OriginCaller). RecvPacket mints 100
 41	// vouchers to it so the balance is non-zero.
 42	owner := cur.Previous().Address()
 43	recvPacket(cur, clientID, counterpartyID, trustedHeight, owner)
 44
 45	// ibc/CAEF9CA8CE6C302D73A831A49E34E59149D3A9AD96CCEBDFBF62F6D5710D92D8
 46	voucherDenom := transfer.NewDenom("uphoton", transfer.NewHop(transfer.PortID, clientID)).IBCDenom()
 47	println("\nvoucher balance before:", transfer.VoucherBalanceOf(voucherDenom, owner))
 48
 49	// Direct user call so the IsUserCall guard passes, but native coins are
 50	// attached to the tx. The guard must reject the transfer before any voucher
 51	// is burnt.
 52	testing.SetRealm(testing.NewUserRealm(owner))
 53	testing.SetOriginSend(chain.NewCoins(chain.NewCoin("ugnot", 100)))
 54	transfer.Transfer(cross(cur), clientID, "atone1user", voucherDenom, 100, uint64(time.Now().Add(time.Hour).Unix()), "memo")
 55
 56	// Reached only if the guard is missing.
 57	println("\nvoucher balance after:", transfer.VoucherBalanceOf(voucherDenom, owner))
 58}
 59
 60func recvPacket(cur realm, clientID, counterpartyID string, trustedHeight types.Height, receiver address) {
 61	payload := transfer.NewFungibleTokenPacketData("uphoton", "100", "atone1user", receiver.String(), "")
 62	payloadBz := payload.ProtoMarshal()
 63
 64	specs := ics23.IavlSpec()
 65	// NOTE proof generated by:
 66	// go run -C ./cmd/gen-proof . 'prefix2' '07-tendermint-42' 'packet' '{"sequence":1,"source_client":"07-tendermint-42","destination_client":"07-tendermint-1","timeout_timestamp":1234571490,"payloads":[{"source_port":"transfer","destination_port":"transfer","encoding":"application/x-protobuf", "value":"Cgd1cGhvdG9uEgMxMDAaCmF0b25lMXVzZXIiKGcxd3ltdTQ3ZHJocjBrdXEyMDk4bTc5Mmx5dGd0ajJueXg3N3lyc20=","version":"ics20-1"}]}'
 67	proof := []ics23.CommitmentProof{
 68
 69		// iavl proof
 70		ics23.CommitmentProof_Exist{
 71			Exist: &ics23.ExistenceProof{
 72				Key:   []byte("\x70\x72\x65\x66\x69\x78\x32\x30\x37\x2d\x74\x65\x6e\x64\x65\x72\x6d\x69\x6e\x74\x2d\x34\x32\x01\x00\x00\x00\x00\x00\x00\x00\x01"),
 73				Value: []byte("\x12\x6c\xcc\xff\x00\xd6\xb9\x73\x09\xb3\x8b\x1b\xec\x0f\xe2\xef\xc9\x54\xe5\xac\x1d\x90\x47\x36\xd0\x32\xbc\xc0\xb1\x66\xc4\x8f"),
 74				Leaf: &ics23.LeafOp{
 75					Hash:         specs.LeafSpec.Hash,
 76					PrehashKey:   specs.LeafSpec.PrehashKey,
 77					PrehashValue: specs.LeafSpec.PrehashValue,
 78					Length:       specs.LeafSpec.Length,
 79					Prefix:       []byte("\x00\x02\x02"),
 80				},
 81				Path: []*ics23.InnerOp{
 82					{
 83						Hash:   specs.InnerSpec.Hash,
 84						Prefix: []byte("\x02\x04\x02\x20\x35\xf8\xea\x80\x53\x90\xe0\x84\x85\x4f\x39\x9b\x42\xcc\xde\xae\xa3\x3a\x1d\xed\xc1\x15\x63\x8a\xc4\x8d\x06\x00\x63\x7d\xba\x1f\x20"),
 85						Suffix: []byte(""),
 86					},
 87					{
 88						Hash:   specs.InnerSpec.Hash,
 89						Prefix: []byte("\x04\x08\x02\x20"),
 90						Suffix: []byte("\x20\x79\x8e\x2c\xaa\x96\xfd\xfb\xa3\x76\xdd\xeb\x47\x99\x99\x54\xd2\xf4\x7e\x65\x16\x22\x64\xb0\x53\x6a\xb5\xdf\xf7\xfc\x0a\x2e\x07"),
 91					},
 92					{
 93						Hash:   specs.InnerSpec.Hash,
 94						Prefix: []byte("\x06\x0c\x02\x20\x9a\xf3\x7d\xd5\x95\xa0\x19\x08\x03\xb5\xe0\x5a\xae\xf4\x2a\xe3\xfa\xd4\x99\xe4\xfb\xe3\x7f\x7c\xd3\x1c\xad\xff\x22\xa9\xee\x74\x20"),
 95						Suffix: []byte(""),
 96					},
 97				},
 98			},
 99		},
100
101		// rootmulti proof
102		ics23.CommitmentProof_Exist{
103			Exist: &ics23.ExistenceProof{
104				Key:   []byte("\x69\x61\x76\x6c\x53\x74\x6f\x72\x65\x4b\x65\x79"),
105				Value: []byte("\x4f\xa3\xdf\x13\x8a\x86\x32\xc8\x3f\xd8\x84\x92\x00\xe0\xf1\xd8\x8a\x05\x36\x85\x32\x15\x1b\x45\x67\xf6\x86\xec\xf1\xfb\x9f\x45"),
106				Leaf: &ics23.LeafOp{
107					Hash:         specs.LeafSpec.Hash,
108					PrehashKey:   specs.LeafSpec.PrehashKey,
109					PrehashValue: specs.LeafSpec.PrehashValue,
110					Length:       specs.LeafSpec.Length,
111					Prefix:       []byte("\x00"),
112				},
113				Path: []*ics23.InnerOp{},
114			},
115		},
116	}
117	recvPacket := types.MsgRecvPacket{
118		Packet: types.Packet{
119			Sequence:          1,
120			SourceClient:      counterpartyID,
121			DestinationClient: clientID,
122			TimeoutTimestamp:  uint64(time.Now().Add(time.Hour).Unix()),
123			Payloads: []types.Payload{{
124				SourcePort:      transfer.PortID,
125				DestinationPort: transfer.PortID,
126				Encoding:        transfer.EncodingProtobuf,
127				Value:           payloadBz,
128				Version:         transfer.V1,
129			}},
130		},
131		ProofCommitment: proof,
132		ProofHeight:     trustedHeight,
133	}
134
135	core.RecvPacket(cross(cur), recvPacket)
136}
137
138// Error:
139// voucher transfer must not include native coins