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

z1h_on_send_packet_voucher_bypass_filetest.gno

5.88 Kb · 143 lines
  1// PKGPATH: gno.land/r/aib/main
  2package main
  3
  4// Regression test: a voucher send must be rejected when it does not originate
  5// from transfer.Transfer. OnSendPacket is reachable directly through the public
  6// core.SendPacket router, so the direct-user-call guard in transfer.Transfer is
  7// not sufficient on its own — OnSendPacket must also require that voucher (and
  8// GRC20) sends were initiated through transfer.Transfer, mirroring the existing
  9// native-branch pendingNativeEscrow check.
 10//
 11// Here core.SendPacket is invoked directly with a voucher payload whose Sender
 12// equals OriginCaller; the immediate caller is a realm (this main), not a user.
 13// Until the OnSendPacket-level guard lands this test FAILS because the send
 14// succeeds and burns the owner's voucher.
 15
 16import (
 17	"encoding/hex"
 18	"time"
 19
 20	tmtesting "gno.land/p/aib/ibc/lightclient/tendermint/testing"
 21	"gno.land/p/aib/ibc/types"
 22
 23	"gno.land/p/aib/ics23"
 24	"gno.land/r/aib/ibc/apps/transfer"
 25	"gno.land/r/aib/ibc/core"
 26)
 27
 28func main(cur realm) {
 29	var (
 30		chainID        = "chain-id-2"
 31		trustedHeight  = types.NewHeight(2, 2)
 32		clientState    = tmtesting.NewClientState(chainID, trustedHeight)
 33		apphash, _     = hex.DecodeString("0eadf50c7992d8e1366b8ea63ab7d1346de4762c3d449764ef7dc404ba48381f")
 34		trustedValset  = tmtesting.GenValset()
 35		consensusState = tmtesting.GenConsensusState(time.Now(), apphash, trustedValset.Hash())
 36		counterpartyID = "07-tendermint-42"
 37	)
 38	clientID := core.CreateClient(cross(cur), clientState, consensusState)
 39	core.RegisterCounterparty(cross(cur), clientID, [][]byte{[]byte("iavlStoreKey"), []byte("prefix2")}, counterpartyID)
 40
 41	// The voucher owner is the signing EOA (OriginCaller). RecvPacket mints 100
 42	// vouchers to it so the balance is non-zero.
 43	owner := cur.Previous().Address()
 44	recvPacket(cur, clientID, counterpartyID, trustedHeight, owner)
 45
 46	// Build a voucher send packet and submit it straight to the core router,
 47	// bypassing transfer.Transfer and its guard. The guard must instead reject
 48	// this at the OnSendPacket layer.
 49	data := transfer.NewFungibleTokenPacketData("transfer/"+clientID+"/uphoton", "100", owner.String(), "atone1user", "")
 50	msg := types.MsgSendPacket{
 51		SourceClient: clientID,
 52		Payloads: []types.Payload{{
 53			SourcePort:      transfer.PortID,
 54			DestinationPort: transfer.PortID,
 55			Encoding:        transfer.EncodingProtobuf,
 56			Value:           data.ProtoMarshal(),
 57			Version:         transfer.V1,
 58		}},
 59		TimeoutTimestamp: uint64(time.Now().Add(time.Hour).Unix()),
 60	}
 61	core.SendPacket(cross(cur), msg)
 62}
 63
 64func recvPacket(cur realm, clientID, counterpartyID string, trustedHeight types.Height, receiver address) {
 65	payload := transfer.NewFungibleTokenPacketData("uphoton", "100", "atone1user", receiver.String(), "")
 66	payloadBz := payload.ProtoMarshal()
 67
 68	specs := ics23.IavlSpec()
 69	// NOTE proof generated by:
 70	// 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"}]}'
 71	proof := []ics23.CommitmentProof{
 72
 73		// iavl proof
 74		ics23.CommitmentProof_Exist{
 75			Exist: &ics23.ExistenceProof{
 76				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"),
 77				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"),
 78				Leaf: &ics23.LeafOp{
 79					Hash:         specs.LeafSpec.Hash,
 80					PrehashKey:   specs.LeafSpec.PrehashKey,
 81					PrehashValue: specs.LeafSpec.PrehashValue,
 82					Length:       specs.LeafSpec.Length,
 83					Prefix:       []byte("\x00\x02\x02"),
 84				},
 85				Path: []*ics23.InnerOp{
 86					{
 87						Hash:   specs.InnerSpec.Hash,
 88						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"),
 89						Suffix: []byte(""),
 90					},
 91					{
 92						Hash:   specs.InnerSpec.Hash,
 93						Prefix: []byte("\x04\x08\x02\x20"),
 94						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"),
 95					},
 96					{
 97						Hash:   specs.InnerSpec.Hash,
 98						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"),
 99						Suffix: []byte(""),
100					},
101				},
102			},
103		},
104
105		// rootmulti proof
106		ics23.CommitmentProof_Exist{
107			Exist: &ics23.ExistenceProof{
108				Key:   []byte("\x69\x61\x76\x6c\x53\x74\x6f\x72\x65\x4b\x65\x79"),
109				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"),
110				Leaf: &ics23.LeafOp{
111					Hash:         specs.LeafSpec.Hash,
112					PrehashKey:   specs.LeafSpec.PrehashKey,
113					PrehashValue: specs.LeafSpec.PrehashValue,
114					Length:       specs.LeafSpec.Length,
115					Prefix:       []byte("\x00"),
116				},
117				Path: []*ics23.InnerOp{},
118			},
119		},
120	}
121	recvMsg := types.MsgRecvPacket{
122		Packet: types.Packet{
123			Sequence:          1,
124			SourceClient:      counterpartyID,
125			DestinationClient: clientID,
126			TimeoutTimestamp:  uint64(time.Now().Add(time.Hour).Unix()),
127			Payloads: []types.Payload{{
128				SourcePort:      transfer.PortID,
129				DestinationPort: transfer.PortID,
130				Encoding:        transfer.EncodingProtobuf,
131				Value:           payloadBz,
132				Version:         transfer.V1,
133			}},
134		},
135		ProofCommitment: proof,
136		ProofHeight:     trustedHeight,
137	}
138
139	core.RecvPacket(cross(cur), recvMsg)
140}
141
142// Error:
143// send packet failed for payload #0 app "transfer": voucher packet must be initiated through transfer.Transfer