forked from ava-labs/hypersdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate_order.go
135 lines (114 loc) · 3.81 KB
/
create_order.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright (C) 2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package actions
import (
"context"
"fmt"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/vms/platformvm/warp"
"github.com/ava-labs/hypersdk/chain"
"github.com/ava-labs/hypersdk/codec"
"github.com/ava-labs/hypersdk/consts"
"github.com/ava-labs/hypersdk/examples/tokenvm/storage"
"github.com/ava-labs/hypersdk/state"
"github.com/ava-labs/hypersdk/utils"
)
var _ chain.Action = (*CreateOrder)(nil)
type CreateOrder struct {
// [In] is the asset you trade for [Out].
In ids.ID `json:"in"`
// [InTick] is the amount of [In] required to purchase
// [OutTick] of [Out].
InTick uint64 `json:"inTick"`
// [Out] is the asset you receive when trading for [In].
//
// This is the asset that is actually provided by the creator.
Out ids.ID `json:"out"`
// [OutTick] is the amount of [Out] the counterparty gets per [InTick] of
// [In].
OutTick uint64 `json:"outTick"`
// [Supply] is the initial amount of [In] that the actor is locking up.
Supply uint64 `json:"supply"`
// Notes:
// * Users are allowed to have any number of orders for the same [In]-[Out] pair.
// * Using [InTick] and [OutTick] blocks ensures we avoid any odd rounding
// errors.
// * Users can fill orders with any multiple of [InTick] and will get
// refunded any unused assets.
}
func (*CreateOrder) GetTypeID() uint8 {
return createOrderID
}
func (c *CreateOrder) StateKeys(actor codec.Address, txID ids.ID) state.Keys {
return state.Keys{
string(storage.BalanceKey(actor, c.Out)): state.Read | state.Write,
string(storage.OrderKey(txID)): state.Write,
}
}
func (*CreateOrder) StateKeysMaxChunks() []uint16 {
return []uint16{storage.BalanceChunks, storage.OrderChunks}
}
func (*CreateOrder) OutputsWarpMessage() bool {
return false
}
func (c *CreateOrder) Execute(
ctx context.Context,
_ chain.Rules,
mu state.Mutable,
_ int64,
actor codec.Address,
txID ids.ID,
_ bool,
) (bool, uint64, []byte, *warp.UnsignedMessage, error) {
if c.In == c.Out {
return false, CreateOrderComputeUnits, OutputSameInOut, nil, nil
}
if c.InTick == 0 {
return false, CreateOrderComputeUnits, OutputInTickZero, nil, nil
}
if c.OutTick == 0 {
return false, CreateOrderComputeUnits, OutputOutTickZero, nil, nil
}
if c.Supply == 0 {
return false, CreateOrderComputeUnits, OutputSupplyZero, nil, nil
}
if c.Supply%c.OutTick != 0 {
return false, CreateOrderComputeUnits, OutputSupplyMisaligned, nil, nil
}
if err := storage.SubBalance(ctx, mu, actor, c.Out, c.Supply); err != nil {
return false, CreateOrderComputeUnits, utils.ErrBytes(err), nil, nil
}
if err := storage.SetOrder(ctx, mu, txID, c.In, c.InTick, c.Out, c.OutTick, c.Supply, actor); err != nil {
return false, CreateOrderComputeUnits, utils.ErrBytes(err), nil, nil
}
return true, CreateOrderComputeUnits, nil, nil, nil
}
func (*CreateOrder) MaxComputeUnits(chain.Rules) uint64 {
return CreateOrderComputeUnits
}
func (*CreateOrder) Size() int {
return consts.IDLen*2 + consts.Uint64Len*3
}
func (c *CreateOrder) Marshal(p *codec.Packer) {
p.PackID(c.In)
p.PackUint64(c.InTick)
p.PackID(c.Out)
p.PackUint64(c.OutTick)
p.PackUint64(c.Supply)
}
func UnmarshalCreateOrder(p *codec.Packer, _ *warp.Message) (chain.Action, error) {
var create CreateOrder
p.UnpackID(false, &create.In) // empty ID is the native asset
create.InTick = p.UnpackUint64(true)
p.UnpackID(false, &create.Out) // empty ID is the native asset
create.OutTick = p.UnpackUint64(true)
create.Supply = p.UnpackUint64(true)
return &create, p.Err()
}
func (*CreateOrder) ValidRange(chain.Rules) (int64, int64) {
// Returning -1, -1 means that the action is always valid.
return -1, -1
}
func PairID(in ids.ID, out ids.ID) string {
return fmt.Sprintf("%s-%s", in.String(), out.String())
}