diff --git a/Batch__test_8cpp_source.html b/Batch__test_8cpp_source.html index b5c90cb843..dee0133c0d 100644 --- a/Batch__test_8cpp_source.html +++ b/Batch__test_8cpp_source.html @@ -4329,7 +4329,7 @@ $(function() {
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:261
ripple::test::jtx::Env::rpc
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:788
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
-
ripple::test::jtx::MPTTester
Definition: mpt.h:145
+
ripple::test::jtx::MPTTester
Definition: mpt.h:146
ripple::test::jtx::MPTTester::create
void create(MPTCreate const &arg=MPTCreate{})
Definition: mpt.cpp:86
ripple::test::jtx::batch::inner
Adds a new Batch Txn on a JTx and autofills.
Definition: batch.h:61
ripple::test::jtx::batch::msig
Set a batch nested multi-signature on a JTx.
Definition: batch.h:135
diff --git a/BookChanges__test_8cpp_source.html b/BookChanges__test_8cpp_source.html index 3073cb3254..89799c5bce 100644 --- a/BookChanges__test_8cpp_source.html +++ b/BookChanges__test_8cpp_source.html @@ -242,7 +242,7 @@ $(function() {
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:117
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:261
ripple::test::jtx::Env::rpc
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:788
-
ripple::test::jtx::PermissionedDEX
Definition: permissioned_dex.h:35
+
ripple::test::jtx::PermissionedDEX
Definition: permissioned_dex.h:37
ripple::test::jtx::domain
Set the domain on a JTx.
Definition: domain.h:30
ripple::test::jtx::path
Add a path.
Definition: paths.h:58
ripple::test::jtx::sendmax
Sets the SendMax on a JTx.
Definition: sendmax.h:33
diff --git a/Book__test_8cpp_source.html b/Book__test_8cpp_source.html index 2620464b0a..769f96e685 100644 --- a/Book__test_8cpp_source.html +++ b/Book__test_8cpp_source.html @@ -2142,13 +2142,13 @@ $(function() {
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:261
ripple::test::jtx::Env::rpc
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:788
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
-
ripple::test::jtx::PermissionedDEX
Definition: permissioned_dex.h:35
-
ripple::test::jtx::PermissionedDEX::carol
Account carol
Definition: permissioned_dex.h:41
-
ripple::test::jtx::PermissionedDEX::bob
Account bob
Definition: permissioned_dex.h:40
-
ripple::test::jtx::PermissionedDEX::alice
Account alice
Definition: permissioned_dex.h:39
-
ripple::test::jtx::PermissionedDEX::domainID
uint256 domainID
Definition: permissioned_dex.h:43
-
ripple::test::jtx::PermissionedDEX::gw
Account gw
Definition: permissioned_dex.h:37
-
ripple::test::jtx::PermissionedDEX::USD
IOU USD
Definition: permissioned_dex.h:42
+
ripple::test::jtx::PermissionedDEX
Definition: permissioned_dex.h:37
+
ripple::test::jtx::PermissionedDEX::carol
Account carol
Definition: permissioned_dex.h:43
+
ripple::test::jtx::PermissionedDEX::bob
Account bob
Definition: permissioned_dex.h:42
+
ripple::test::jtx::PermissionedDEX::alice
Account alice
Definition: permissioned_dex.h:41
+
ripple::test::jtx::PermissionedDEX::domainID
uint256 domainID
Definition: permissioned_dex.h:45
+
ripple::test::jtx::PermissionedDEX::gw
Account gw
Definition: permissioned_dex.h:39
+
ripple::test::jtx::PermissionedDEX::USD
IOU USD
Definition: permissioned_dex.h:44
ripple::test::jtx::domain
Set the domain on a JTx.
Definition: domain.h:30
ripple::test::jtx::owners
Match the number of items in the account's owner directory.
Definition: owners.h:73
ripple::test::jtx::require
Check a set of conditions.
Definition: require.h:65
diff --git a/Delegate__test_8cpp_source.html b/Delegate__test_8cpp_source.html index dfe37a68e3..dd318e5daa 100644 --- a/Delegate__test_8cpp_source.html +++ b/Delegate__test_8cpp_source.html @@ -1613,7 +1613,7 @@ $(function() {
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
ripple::test::jtx::Env::balance
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Definition: Env.cpp:179
ripple::test::jtx::Env::le
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:263
-
ripple::test::jtx::MPTTester
Definition: mpt.h:145
+
ripple::test::jtx::MPTTester
Definition: mpt.h:146
ripple::test::jtx::balance
A balance matches.
Definition: balance.h:39
ripple::test::jtx::did::uri
Sets the optional URI on a DIDSet.
Definition: did.h:60
ripple::test::jtx::domain
Set the domain on a JTx.
Definition: domain.h:30
diff --git a/EscrowToken__test_8cpp_source.html b/EscrowToken__test_8cpp_source.html index 8ddab4f40d..562c8ca258 100644 --- a/EscrowToken__test_8cpp_source.html +++ b/EscrowToken__test_8cpp_source.html @@ -3993,7 +3993,7 @@ $(function() {
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
ripple::test::jtx::Env::le
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:263
ripple::test::jtx::IOU
Converts to IOU Issue or STAmount.
Definition: src/test/jtx/amount.h:348
-
ripple::test::jtx::MPTTester
Definition: mpt.h:145
+
ripple::test::jtx::MPTTester
Definition: mpt.h:146
ripple::test::jtx::MPTTester::create
void create(MPTCreate const &arg=MPTCreate{})
Definition: mpt.cpp:86
ripple::test::jtx::MPT
Converts to MPT Issue or STAmount.
Definition: src/test/jtx/amount.h:425
ripple::test::jtx::MPT::mpt
ripple::MPTID const & mpt() const
Definition: src/test/jtx/amount.h:436
diff --git a/LedgerEntry__test_8cpp_source.html b/LedgerEntry__test_8cpp_source.html index bbcbb9726d..267d9856a8 100644 --- a/LedgerEntry__test_8cpp_source.html +++ b/LedgerEntry__test_8cpp_source.html @@ -2852,7 +2852,7 @@ $(function() {
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:117
ripple::test::jtx::Env::rpc
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:788
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
-
ripple::test::jtx::MPTTester
Definition: mpt.h:145
+
ripple::test::jtx::MPTTester
Definition: mpt.h:146
ripple::test::jtx::MPTTester::create
void create(MPTCreate const &arg=MPTCreate{})
Definition: mpt.cpp:86
ripple::test::jtx::oracle::Oracle
Oracle class facilitates unit-testing of the Price Oracle feature.
Definition: Oracle.h:120
std::chrono::duration
diff --git a/MPToken__test_8cpp_source.html b/MPToken__test_8cpp_source.html index 57e2a7703c..76800a0ddf 100644 --- a/MPToken__test_8cpp_source.html +++ b/MPToken__test_8cpp_source.html @@ -2473,10 +2473,10 @@ $(function() {
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:117
ripple::test::jtx::Env::rpc
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:788
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
-
ripple::test::jtx::MPTTester
Definition: mpt.h:145
+
ripple::test::jtx::MPTTester
Definition: mpt.h:146
ripple::test::jtx::MPTTester::authorize
void authorize(MPTAuthorize const &arg=MPTAuthorize{})
Definition: mpt.cpp:145
ripple::test::jtx::MPTTester::set
void set(MPTSet const &set={})
Definition: mpt.cpp:218
-
ripple::test::jtx::MPTTester::issuanceID
MPTID const & issuanceID() const
Definition: mpt.h:205
+
ripple::test::jtx::MPTTester::issuanceID
MPTID const & issuanceID() const
Definition: mpt.h:206
ripple::test::jtx::MPTTester::create
void create(MPTCreate const &arg=MPTCreate{})
Definition: mpt.cpp:86
ripple::test::jtx::MPTTester::destroy
void destroy(MPTDestroy const &arg=MPTDestroy{})
Definition: mpt.cpp:116
ripple::test::jtx::MPT
Converts to MPT Issue or STAmount.
Definition: src/test/jtx/amount.h:425
diff --git a/PermissionedDEX__test_8cpp_source.html b/PermissionedDEX__test_8cpp_source.html index 9288f4947b..476fb6ccc2 100644 --- a/PermissionedDEX__test_8cpp_source.html +++ b/PermissionedDEX__test_8cpp_source.html @@ -1709,7 +1709,7 @@ $(function() {
ripple::test::jtx::Env::enableFeature
void enableFeature(uint256 const feature)
Definition: Env.cpp:637
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
ripple::test::jtx::Env::le
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:263
-
ripple::test::jtx::PermissionedDEX
Definition: permissioned_dex.h:35
+
ripple::test::jtx::PermissionedDEX
Definition: permissioned_dex.h:37
ripple::test::jtx::balance
A balance matches.
Definition: balance.h:39
ripple::test::jtx::domain
Set the domain on a JTx.
Definition: domain.h:30
ripple::test::jtx::flags
Match set account flags.
Definition: flags.h:128
diff --git a/Subscribe__test_8cpp_source.html b/Subscribe__test_8cpp_source.html index eaa47881cf..fa945de78a 100644 --- a/Subscribe__test_8cpp_source.html +++ b/Subscribe__test_8cpp_source.html @@ -1718,13 +1718,13 @@ $(function() {
ripple::test::jtx::Env::apply
Env & apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
Definition: Env.h:579
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
ripple::test::jtx::Env::memoize
void memoize(Account const &account)
Associate AccountID with account.
Definition: Env.cpp:152
-
ripple::test::jtx::PermissionedDEX
Definition: permissioned_dex.h:35
-
ripple::test::jtx::PermissionedDEX::carol
Account carol
Definition: permissioned_dex.h:41
-
ripple::test::jtx::PermissionedDEX::bob
Account bob
Definition: permissioned_dex.h:40
-
ripple::test::jtx::PermissionedDEX::alice
Account alice
Definition: permissioned_dex.h:39
-
ripple::test::jtx::PermissionedDEX::domainID
uint256 domainID
Definition: permissioned_dex.h:43
-
ripple::test::jtx::PermissionedDEX::gw
Account gw
Definition: permissioned_dex.h:37
-
ripple::test::jtx::PermissionedDEX::USD
IOU USD
Definition: permissioned_dex.h:42
+
ripple::test::jtx::PermissionedDEX
Definition: permissioned_dex.h:37
+
ripple::test::jtx::PermissionedDEX::carol
Account carol
Definition: permissioned_dex.h:43
+
ripple::test::jtx::PermissionedDEX::bob
Account bob
Definition: permissioned_dex.h:42
+
ripple::test::jtx::PermissionedDEX::alice
Account alice
Definition: permissioned_dex.h:41
+
ripple::test::jtx::PermissionedDEX::domainID
uint256 domainID
Definition: permissioned_dex.h:45
+
ripple::test::jtx::PermissionedDEX::gw
Account gw
Definition: permissioned_dex.h:39
+
ripple::test::jtx::PermissionedDEX::USD
IOU USD
Definition: permissioned_dex.h:44
ripple::test::jtx::domain
Set the domain on a JTx.
Definition: domain.h:30
ripple::test::jtx::fee
Set the fee on a JTx.
Definition: fee.h:37
ripple::test::jtx::path
Add a path.
Definition: paths.h:58
diff --git a/Vault__test_8cpp_source.html b/Vault__test_8cpp_source.html index 48cffb41b1..d3a59ec658 100644 --- a/Vault__test_8cpp_source.html +++ b/Vault__test_8cpp_source.html @@ -95,3153 +95,3143 @@ $(function() {
17*/
18//==============================================================================
19
-
20#include <test/jtx/AMM.h>
+
20#include <test/jtx.h>
21#include <test/jtx/AMMTest.h>
-
22#include <test/jtx/Account.h>
-
23#include <test/jtx/Env.h>
-
24#include <test/jtx/amount.h>
-
25#include <test/jtx/credentials.h>
-
26#include <test/jtx/fee.h>
-
27#include <test/jtx/flags.h>
-
28#include <test/jtx/mpt.h>
-
29#include <test/jtx/permissioned_domains.h>
-
30#include <test/jtx/utility.h>
-
31#include <test/jtx/vault.h>
-
32
-
33#include <xrpld/ledger/View.h>
-
34
-
35#include <xrpl/basics/base_uint.h>
-
36#include <xrpl/beast/unit_test/suite.h>
-
37#include <xrpl/json/json_forwards.h>
-
38#include <xrpl/json/json_value.h>
-
39#include <xrpl/protocol/AccountID.h>
-
40#include <xrpl/protocol/Asset.h>
-
41#include <xrpl/protocol/Feature.h>
-
42#include <xrpl/protocol/Indexes.h>
-
43#include <xrpl/protocol/Issue.h>
-
44#include <xrpl/protocol/MPTIssue.h>
-
45#include <xrpl/protocol/Protocol.h>
-
46#include <xrpl/protocol/SField.h>
-
47#include <xrpl/protocol/STAmount.h>
-
48#include <xrpl/protocol/STNumber.h>
-
49#include <xrpl/protocol/TER.h>
-
50#include <xrpl/protocol/TxFlags.h>
-
51#include <xrpl/protocol/XRPAmount.h>
-
52#include <xrpl/protocol/jss.h>
-
53
-
54namespace ripple {
+
22
+
23#include <xrpld/ledger/View.h>
+
24
+
25#include <xrpl/basics/base_uint.h>
+
26#include <xrpl/beast/unit_test/suite.h>
+
27#include <xrpl/json/json_forwards.h>
+
28#include <xrpl/json/json_value.h>
+
29#include <xrpl/protocol/AccountID.h>
+
30#include <xrpl/protocol/Asset.h>
+
31#include <xrpl/protocol/Feature.h>
+
32#include <xrpl/protocol/Indexes.h>
+
33#include <xrpl/protocol/Issue.h>
+
34#include <xrpl/protocol/MPTIssue.h>
+
35#include <xrpl/protocol/Protocol.h>
+
36#include <xrpl/protocol/SField.h>
+
37#include <xrpl/protocol/STAmount.h>
+
38#include <xrpl/protocol/STNumber.h>
+
39#include <xrpl/protocol/TER.h>
+
40#include <xrpl/protocol/TxFlags.h>
+
41#include <xrpl/protocol/XRPAmount.h>
+
42#include <xrpl/protocol/jss.h>
+
43
+
44namespace ripple {
+
45
+
46class Vault_test : public beast::unit_test::suite
+
47{
+
48 using PrettyAsset = ripple::test::jtx::PrettyAsset;
+
49 using PrettyAmount = ripple::test::jtx::PrettyAmount;
+
50
+
51 static auto constexpr negativeAmount =
+
52 [](PrettyAsset const& asset) -> PrettyAmount {
+
53 return {STAmount{asset.raw(), 1ul, 0, true, STAmount::unchecked{}}, ""};
+
54 };
55
-
56class Vault_test : public beast::unit_test::suite
-
57{
-
58 using PrettyAsset = ripple::test::jtx::PrettyAsset;
-
59 using PrettyAmount = ripple::test::jtx::PrettyAmount;
+
56 void
+
57 testSequences()
+
58 {
+
59 using namespace test::jtx;
60
-
61 static auto constexpr negativeAmount =
-
62 [](PrettyAsset const& asset) -> PrettyAmount {
-
63 return {STAmount{asset.raw(), 1ul, 0, true, STAmount::unchecked{}}, ""};
-
64 };
-
65
-
66 void
-
67 testSequences()
-
68 {
-
69 using namespace test::jtx;
-
70
-
71 auto const testSequence = [this](
-
72 std::string const& prefix,
-
73 Env& env,
-
74 Account const& issuer,
-
75 Account const& owner,
-
76 Account const& depositor,
-
77 Account const& charlie,
-
78 Vault& vault,
-
79 PrettyAsset const& asset) {
-
80 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
81 tx[sfData] = "AFEED00E";
-
82 tx[sfAssetsMaximum] = asset(100).number();
-
83 env(tx);
-
84 env.close();
-
85 BEAST_EXPECT(env.le(keylet));
-
86
-
87 auto const share = [&env, keylet = keylet, this]() -> PrettyAsset {
-
88 auto const vault = env.le(keylet);
-
89 BEAST_EXPECT(vault != nullptr);
-
90 return MPTIssue(vault->at(sfShareMPTID));
-
91 }();
-
92
-
93 // Several 3rd party accounts which cannot receive funds
-
94 Account alice{"alice"};
-
95 Account dave{"dave"};
-
96 Account erin{"erin"}; // not authorized by issuer
-
97 env.fund(XRP(1000), alice, dave, erin);
-
98 env(fset(alice, asfDepositAuth));
-
99 env(fset(dave, asfRequireDest));
-
100 env.close();
-
101
-
102 {
-
103 testcase(prefix + " fail to deposit more than assets held");
-
104 auto tx = vault.deposit(
-
105 {.depositor = depositor,
-
106 .id = keylet.key,
-
107 .amount = asset(10000)});
-
108 env(tx, ter(tecINSUFFICIENT_FUNDS));
-
109 }
-
110
-
111 {
-
112 testcase(prefix + " deposit non-zero amount");
-
113 auto tx = vault.deposit(
-
114 {.depositor = depositor,
-
115 .id = keylet.key,
-
116 .amount = asset(50)});
-
117 env(tx);
-
118 }
-
119
-
120 {
-
121 testcase(prefix + " deposit non-zero amount again");
-
122 auto tx = vault.deposit(
-
123 {.depositor = depositor,
-
124 .id = keylet.key,
-
125 .amount = asset(50)});
-
126 env(tx);
-
127 }
-
128
-
129 {
-
130 testcase(prefix + " fail to delete non-empty vault");
-
131 auto tx = vault.del({.owner = owner, .id = keylet.key});
-
132 env(tx, ter(tecHAS_OBLIGATIONS));
-
133 }
-
134
-
135 {
-
136 testcase(prefix + " fail to update because wrong owner");
-
137 auto tx = vault.set({.owner = issuer, .id = keylet.key});
-
138 tx[sfAssetsMaximum] = asset(50).number();
-
139 env(tx, ter(tecNO_PERMISSION));
-
140 }
-
141
-
142 {
-
143 testcase(
-
144 prefix + " fail to set maximum lower than current amount");
-
145 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
146 tx[sfAssetsMaximum] = asset(50).number();
-
147 env(tx, ter(tecLIMIT_EXCEEDED));
-
148 }
-
149
-
150 {
-
151 testcase(prefix + " set maximum higher than current amount");
-
152 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
153 tx[sfAssetsMaximum] = asset(150).number();
-
154 env(tx);
-
155 }
-
156
-
157 {
-
158 testcase(prefix + " set data");
-
159 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
160 tx[sfData] = "0";
-
161 env(tx);
-
162 }
-
163
-
164 {
-
165 testcase(prefix + " fail to set domain on public vault");
-
166 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
167 tx[sfDomainID] = to_string(base_uint<256>(42ul));
-
168 env(tx, ter{tecNO_PERMISSION});
-
169 }
-
170
-
171 {
-
172 testcase(prefix + " fail to deposit more than maximum");
-
173 auto tx = vault.deposit(
-
174 {.depositor = depositor,
-
175 .id = keylet.key,
-
176 .amount = asset(100)});
-
177 env(tx, ter(tecLIMIT_EXCEEDED));
-
178 }
-
179
-
180 {
-
181 testcase(prefix + " reset maximum to zero i.e. not enforced");
-
182 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
183 tx[sfAssetsMaximum] = asset(0).number();
-
184 env(tx);
-
185 }
-
186
-
187 {
-
188 testcase(prefix + " fail to withdraw more than assets held");
-
189 auto tx = vault.withdraw(
-
190 {.depositor = depositor,
-
191 .id = keylet.key,
-
192 .amount = asset(1000)});
-
193 env(tx, ter(tecINSUFFICIENT_FUNDS));
-
194 }
-
195
-
196 {
-
197 testcase(prefix + " deposit some more");
-
198 auto tx = vault.deposit(
-
199 {.depositor = depositor,
-
200 .id = keylet.key,
-
201 .amount = asset(100)});
-
202 env(tx);
-
203 }
-
204
-
205 {
-
206 testcase(prefix + " clawback some");
-
207 auto code =
-
208 asset.raw().native() ? ter(temMALFORMED) : ter(tesSUCCESS);
-
209 auto tx = vault.clawback(
-
210 {.issuer = issuer,
-
211 .id = keylet.key,
-
212 .holder = depositor,
-
213 .amount = asset(10)});
-
214 env(tx, code);
-
215 }
-
216
+
61 auto const testSequence = [this](
+
62 std::string const& prefix,
+
63 Env& env,
+
64 Account const& issuer,
+
65 Account const& owner,
+
66 Account const& depositor,
+
67 Account const& charlie,
+
68 Vault& vault,
+
69 PrettyAsset const& asset) {
+
70 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
71 tx[sfData] = "AFEED00E";
+
72 tx[sfAssetsMaximum] = asset(100).number();
+
73 env(tx);
+
74 env.close();
+
75 BEAST_EXPECT(env.le(keylet));
+
76
+
77 auto const share = [&env, keylet = keylet, this]() -> PrettyAsset {
+
78 auto const vault = env.le(keylet);
+
79 BEAST_EXPECT(vault != nullptr);
+
80 return MPTIssue(vault->at(sfShareMPTID));
+
81 }();
+
82
+
83 // Several 3rd party accounts which cannot receive funds
+
84 Account alice{"alice"};
+
85 Account dave{"dave"};
+
86 Account erin{"erin"}; // not authorized by issuer
+
87 env.fund(XRP(1000), alice, dave, erin);
+
88 env(fset(alice, asfDepositAuth));
+
89 env(fset(dave, asfRequireDest));
+
90 env.close();
+
91
+
92 {
+
93 testcase(prefix + " fail to deposit more than assets held");
+
94 auto tx = vault.deposit(
+
95 {.depositor = depositor,
+
96 .id = keylet.key,
+
97 .amount = asset(10000)});
+
98 env(tx, ter(tecINSUFFICIENT_FUNDS));
+
99 }
+
100
+
101 {
+
102 testcase(prefix + " deposit non-zero amount");
+
103 auto tx = vault.deposit(
+
104 {.depositor = depositor,
+
105 .id = keylet.key,
+
106 .amount = asset(50)});
+
107 env(tx);
+
108 }
+
109
+
110 {
+
111 testcase(prefix + " deposit non-zero amount again");
+
112 auto tx = vault.deposit(
+
113 {.depositor = depositor,
+
114 .id = keylet.key,
+
115 .amount = asset(50)});
+
116 env(tx);
+
117 }
+
118
+
119 {
+
120 testcase(prefix + " fail to delete non-empty vault");
+
121 auto tx = vault.del({.owner = owner, .id = keylet.key});
+
122 env(tx, ter(tecHAS_OBLIGATIONS));
+
123 }
+
124
+
125 {
+
126 testcase(prefix + " fail to update because wrong owner");
+
127 auto tx = vault.set({.owner = issuer, .id = keylet.key});
+
128 tx[sfAssetsMaximum] = asset(50).number();
+
129 env(tx, ter(tecNO_PERMISSION));
+
130 }
+
131
+
132 {
+
133 testcase(
+
134 prefix + " fail to set maximum lower than current amount");
+
135 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
136 tx[sfAssetsMaximum] = asset(50).number();
+
137 env(tx, ter(tecLIMIT_EXCEEDED));
+
138 }
+
139
+
140 {
+
141 testcase(prefix + " set maximum higher than current amount");
+
142 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
143 tx[sfAssetsMaximum] = asset(150).number();
+
144 env(tx);
+
145 }
+
146
+
147 {
+
148 testcase(prefix + " set data");
+
149 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
150 tx[sfData] = "0";
+
151 env(tx);
+
152 }
+
153
+
154 {
+
155 testcase(prefix + " fail to set domain on public vault");
+
156 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
157 tx[sfDomainID] = to_string(base_uint<256>(42ul));
+
158 env(tx, ter{tecNO_PERMISSION});
+
159 }
+
160
+
161 {
+
162 testcase(prefix + " fail to deposit more than maximum");
+
163 auto tx = vault.deposit(
+
164 {.depositor = depositor,
+
165 .id = keylet.key,
+
166 .amount = asset(100)});
+
167 env(tx, ter(tecLIMIT_EXCEEDED));
+
168 }
+
169
+
170 {
+
171 testcase(prefix + " reset maximum to zero i.e. not enforced");
+
172 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
173 tx[sfAssetsMaximum] = asset(0).number();
+
174 env(tx);
+
175 }
+
176
+
177 {
+
178 testcase(prefix + " fail to withdraw more than assets held");
+
179 auto tx = vault.withdraw(
+
180 {.depositor = depositor,
+
181 .id = keylet.key,
+
182 .amount = asset(1000)});
+
183 env(tx, ter(tecINSUFFICIENT_FUNDS));
+
184 }
+
185
+
186 {
+
187 testcase(prefix + " deposit some more");
+
188 auto tx = vault.deposit(
+
189 {.depositor = depositor,
+
190 .id = keylet.key,
+
191 .amount = asset(100)});
+
192 env(tx);
+
193 }
+
194
+
195 {
+
196 testcase(prefix + " clawback some");
+
197 auto code =
+
198 asset.raw().native() ? ter(temMALFORMED) : ter(tesSUCCESS);
+
199 auto tx = vault.clawback(
+
200 {.issuer = issuer,
+
201 .id = keylet.key,
+
202 .holder = depositor,
+
203 .amount = asset(10)});
+
204 env(tx, code);
+
205 }
+
206
+
207 {
+
208 testcase(prefix + " clawback all");
+
209 auto code = asset.raw().native() ? ter(tecNO_PERMISSION)
+
210 : ter(tesSUCCESS);
+
211 auto tx = vault.clawback(
+
212 {.issuer = issuer, .id = keylet.key, .holder = depositor});
+
213 env(tx, code);
+
214 }
+
215
+
216 if (!asset.raw().native())
217 {
-
218 testcase(prefix + " clawback all");
-
219 auto code = asset.raw().native() ? ter(tecNO_PERMISSION)
-
220 : ter(tesSUCCESS);
-
221 auto tx = vault.clawback(
-
222 {.issuer = issuer, .id = keylet.key, .holder = depositor});
-
223 env(tx, code);
+
218 testcase(prefix + " deposit again");
+
219 auto tx = vault.deposit(
+
220 {.depositor = depositor,
+
221 .id = keylet.key,
+
222 .amount = asset(200)});
+
223 env(tx);
224 }
225
-
226 if (!asset.raw().native())
-
227 {
-
228 testcase(prefix + " deposit again");
-
229 auto tx = vault.deposit(
+
226 {
+
227 testcase(
+
228 prefix + " fail to withdraw to 3rd party lsfDepositAuth");
+
229 auto tx = vault.withdraw(
230 {.depositor = depositor,
231 .id = keylet.key,
-
232 .amount = asset(200)});
-
233 env(tx);
-
234 }
-
235
-
236 {
-
237 testcase(
-
238 prefix + " fail to withdraw to 3rd party lsfDepositAuth");
-
239 auto tx = vault.withdraw(
-
240 {.depositor = depositor,
-
241 .id = keylet.key,
-
242 .amount = asset(100)});
-
243 tx[sfDestination] = alice.human();
-
244 env(tx, ter{tecNO_PERMISSION});
-
245 }
-
246
-
247 if (!asset.raw().native())
-
248 {
-
249 testcase(
-
250 prefix + " fail to withdraw to 3rd party no authorization");
-
251 auto tx = vault.withdraw(
-
252 {.depositor = depositor,
-
253 .id = keylet.key,
-
254 .amount = asset(100)});
-
255 tx[sfDestination] = erin.human();
-
256 env(tx,
-
257 ter{asset.raw().holds<Issue>() ? tecNO_LINE : tecNO_AUTH});
-
258 }
-
259
-
260 if (!asset.raw().native() && asset.raw().holds<Issue>())
-
261 {
-
262 testcase(prefix + " temporary authorization for 3rd party");
-
263 env(trust(erin, asset(1000)));
-
264 env(trust(issuer, asset(0), erin, tfSetfAuth));
-
265 env(pay(issuer, erin, asset(10)));
-
266
-
267 // Erin deposits all in vault, then sends shares to depositor
-
268 auto tx = vault.deposit(
-
269 {.depositor = erin, .id = keylet.key, .amount = asset(10)});
+
232 .amount = asset(100)});
+
233 tx[sfDestination] = alice.human();
+
234 env(tx, ter{tecNO_PERMISSION});
+
235 }
+
236
+
237 if (!asset.raw().native())
+
238 {
+
239 testcase(
+
240 prefix + " fail to withdraw to 3rd party no authorization");
+
241 auto tx = vault.withdraw(
+
242 {.depositor = depositor,
+
243 .id = keylet.key,
+
244 .amount = asset(100)});
+
245 tx[sfDestination] = erin.human();
+
246 env(tx,
+
247 ter{asset.raw().holds<Issue>() ? tecNO_LINE : tecNO_AUTH});
+
248 }
+
249
+
250 if (!asset.raw().native() && asset.raw().holds<Issue>())
+
251 {
+
252 testcase(prefix + " temporary authorization for 3rd party");
+
253 env(trust(erin, asset(1000)));
+
254 env(trust(issuer, asset(0), erin, tfSetfAuth));
+
255 env(pay(issuer, erin, asset(10)));
+
256
+
257 // Erin deposits all in vault, then sends shares to depositor
+
258 auto tx = vault.deposit(
+
259 {.depositor = erin, .id = keylet.key, .amount = asset(10)});
+
260 env(tx);
+
261 env(pay(erin, depositor, share(10)));
+
262
+
263 testcase(prefix + " withdraw to authorized 3rd party");
+
264 // Depositor withdraws shares, destined to Erin
+
265 tx = vault.withdraw(
+
266 {.depositor = depositor,
+
267 .id = keylet.key,
+
268 .amount = asset(10)});
+
269 tx[sfDestination] = erin.human();
270 env(tx);
-
271 env(pay(erin, depositor, share(10)));
-
272
-
273 testcase(prefix + " withdraw to authorized 3rd party");
-
274 // Depositor withdraws shares, destined to Erin
-
275 tx = vault.withdraw(
-
276 {.depositor = depositor,
-
277 .id = keylet.key,
-
278 .amount = asset(10)});
-
279 tx[sfDestination] = erin.human();
-
280 env(tx);
-
281 // Erin returns assets to issuer
-
282 env(pay(erin, issuer, asset(10)));
-
283
-
284 testcase(prefix + " fail to pay to unauthorized 3rd party");
-
285 env(trust(erin, asset(0)));
-
286 // Erin has MPToken but is no longer authorized to hold assets
-
287 env(pay(depositor, erin, share(1)), ter{tecNO_LINE});
-
288 }
-
289
-
290 {
-
291 testcase(
-
292 prefix +
-
293 " fail to withdraw to 3rd party lsfRequireDestTag");
+
271 // Erin returns assets to issuer
+
272 env(pay(erin, issuer, asset(10)));
+
273
+
274 testcase(prefix + " fail to pay to unauthorized 3rd party");
+
275 env(trust(erin, asset(0)));
+
276 // Erin has MPToken but is no longer authorized to hold assets
+
277 env(pay(depositor, erin, share(1)), ter{tecNO_LINE});
+
278 }
+
279
+
280 {
+
281 testcase(
+
282 prefix +
+
283 " fail to withdraw to 3rd party lsfRequireDestTag");
+
284 auto tx = vault.withdraw(
+
285 {.depositor = depositor,
+
286 .id = keylet.key,
+
287 .amount = asset(100)});
+
288 tx[sfDestination] = dave.human();
+
289 env(tx, ter{tecDST_TAG_NEEDED});
+
290 }
+
291
+
292 {
+
293 testcase(prefix + " withdraw to authorized 3rd party");
294 auto tx = vault.withdraw(
295 {.depositor = depositor,
296 .id = keylet.key,
297 .amount = asset(100)});
-
298 tx[sfDestination] = dave.human();
-
299 env(tx, ter{tecDST_TAG_NEEDED});
+
298 tx[sfDestination] = charlie.human();
+
299 env(tx);
300 }
301
302 {
-
303 testcase(prefix + " withdraw to authorized 3rd party");
+
303 testcase(prefix + " withdraw to issuer");
304 auto tx = vault.withdraw(
305 {.depositor = depositor,
306 .id = keylet.key,
-
307 .amount = asset(100)});
-
308 tx[sfDestination] = charlie.human();
+
307 .amount = asset(50)});
+
308 tx[sfDestination] = issuer.human();
309 env(tx);
310 }
311
312 {
-
313 testcase(prefix + " withdraw to issuer");
+
313 testcase(prefix + " withdraw remaining assets");
314 auto tx = vault.withdraw(
315 {.depositor = depositor,
316 .id = keylet.key,
317 .amount = asset(50)});
-
318 tx[sfDestination] = issuer.human();
-
319 env(tx);
-
320 }
-
321
-
322 {
-
323 testcase(prefix + " withdraw remaining assets");
-
324 auto tx = vault.withdraw(
-
325 {.depositor = depositor,
-
326 .id = keylet.key,
-
327 .amount = asset(50)});
-
328 env(tx);
-
329 }
-
330
-
331 {
-
332 testcase(prefix + " fail to delete because wrong owner");
-
333 auto tx = vault.del({.owner = issuer, .id = keylet.key});
-
334 env(tx, ter(tecNO_PERMISSION));
-
335 }
-
336
-
337 {
-
338 testcase(prefix + " delete empty vault");
-
339 auto tx = vault.del({.owner = owner, .id = keylet.key});
-
340 env(tx);
-
341 BEAST_EXPECT(!env.le(keylet));
-
342 }
-
343 };
-
344
-
345 auto testCases = [this, &testSequence](
-
346 std::string prefix,
-
347 std::function<PrettyAsset(
-
348 Env & env,
-
349 Account const& issuer,
-
350 Account const& owner,
-
351 Account const& depositor,
-
352 Account const& charlie)> setup) {
-
353 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
354 Account issuer{"issuer"};
-
355 Account owner{"owner"};
-
356 Account depositor{"depositor"};
-
357 Account charlie{"charlie"}; // authorized 3rd party
-
358 Vault vault{env};
-
359 env.fund(XRP(1000), issuer, owner, depositor, charlie);
-
360 env.close();
-
361 env(fset(issuer, asfAllowTrustLineClawback));
-
362 env(fset(issuer, asfRequireAuth));
-
363 env.close();
-
364 env.require(flags(issuer, asfAllowTrustLineClawback));
-
365 env.require(flags(issuer, asfRequireAuth));
-
366
-
367 PrettyAsset asset = setup(env, issuer, owner, depositor, charlie);
-
368 testSequence(
-
369 prefix, env, issuer, owner, depositor, charlie, vault, asset);
-
370 };
+
318 env(tx);
+
319 }
+
320
+
321 {
+
322 testcase(prefix + " fail to delete because wrong owner");
+
323 auto tx = vault.del({.owner = issuer, .id = keylet.key});
+
324 env(tx, ter(tecNO_PERMISSION));
+
325 }
+
326
+
327 {
+
328 testcase(prefix + " delete empty vault");
+
329 auto tx = vault.del({.owner = owner, .id = keylet.key});
+
330 env(tx);
+
331 BEAST_EXPECT(!env.le(keylet));
+
332 }
+
333 };
+
334
+
335 auto testCases = [this, &testSequence](
+
336 std::string prefix,
+
337 std::function<PrettyAsset(
+
338 Env & env,
+
339 Account const& issuer,
+
340 Account const& owner,
+
341 Account const& depositor,
+
342 Account const& charlie)> setup) {
+
343 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
344 Account issuer{"issuer"};
+
345 Account owner{"owner"};
+
346 Account depositor{"depositor"};
+
347 Account charlie{"charlie"}; // authorized 3rd party
+
348 Vault vault{env};
+
349 env.fund(XRP(1000), issuer, owner, depositor, charlie);
+
350 env.close();
+
351 env(fset(issuer, asfAllowTrustLineClawback));
+
352 env(fset(issuer, asfRequireAuth));
+
353 env.close();
+
354 env.require(flags(issuer, asfAllowTrustLineClawback));
+
355 env.require(flags(issuer, asfRequireAuth));
+
356
+
357 PrettyAsset asset = setup(env, issuer, owner, depositor, charlie);
+
358 testSequence(
+
359 prefix, env, issuer, owner, depositor, charlie, vault, asset);
+
360 };
+
361
+
362 testCases(
+
363 "XRP",
+
364 [](Env& env,
+
365 Account const& issuer,
+
366 Account const& owner,
+
367 Account const& depositor,
+
368 Account const& charlie) -> PrettyAsset {
+
369 return {xrpIssue(), 1'000'000};
+
370 });
371
372 testCases(
-
373 "XRP",
+
373 "IOU",
374 [](Env& env,
375 Account const& issuer,
376 Account const& owner,
377 Account const& depositor,
-
378 Account const& charlie) -> PrettyAsset {
-
379 return {xrpIssue(), 1'000'000};
-
380 });
-
381
-
382 testCases(
-
383 "IOU",
-
384 [](Env& env,
-
385 Account const& issuer,
-
386 Account const& owner,
-
387 Account const& depositor,
-
388 Account const& charlie) -> Asset {
-
389 PrettyAsset asset = issuer["IOU"];
-
390 env(trust(owner, asset(1000)));
-
391 env(trust(depositor, asset(1000)));
-
392 env(trust(charlie, asset(1000)));
-
393 env(trust(issuer, asset(0), owner, tfSetfAuth));
-
394 env(trust(issuer, asset(0), depositor, tfSetfAuth));
-
395 env(trust(issuer, asset(0), charlie, tfSetfAuth));
-
396 env(pay(issuer, depositor, asset(1000)));
-
397 env.close();
-
398 return asset;
-
399 });
-
400
-
401 testCases(
-
402 "MPT",
-
403 [](Env& env,
-
404 Account const& issuer,
-
405 Account const& owner,
-
406 Account const& depositor,
-
407 Account const& charlie) -> Asset {
-
408 MPTTester mptt{env, issuer, mptInitNoFund};
-
409 mptt.create(
-
410 {.flags =
-
411 tfMPTCanClawback | tfMPTCanTransfer | tfMPTCanLock});
-
412 PrettyAsset asset = mptt.issuanceID();
-
413 mptt.authorize({.account = depositor});
-
414 mptt.authorize({.account = charlie});
-
415 env(pay(issuer, depositor, asset(1000)));
-
416 env.close();
-
417 return asset;
-
418 });
-
419 }
-
420
-
421 void
-
422 testPreflight()
-
423 {
-
424 using namespace test::jtx;
-
425
-
426 struct CaseArgs
-
427 {
-
428 FeatureBitset features =
-
429 supported_amendments() | featureSingleAssetVault;
-
430 };
-
431
-
432 auto testCase = [&, this](
-
433 std::function<void(
-
434 Env & env,
-
435 Account const& issuer,
-
436 Account const& owner,
-
437 Asset const& asset,
-
438 Vault& vault)> test,
-
439 CaseArgs args = {}) {
-
440 Env env{*this, args.features};
-
441 Account issuer{"issuer"};
-
442 Account owner{"owner"};
-
443 Vault vault{env};
-
444 env.fund(XRP(1000), issuer, owner);
+
378 Account const& charlie) -> Asset {
+
379 PrettyAsset asset = issuer["IOU"];
+
380 env(trust(owner, asset(1000)));
+
381 env(trust(depositor, asset(1000)));
+
382 env(trust(charlie, asset(1000)));
+
383 env(trust(issuer, asset(0), owner, tfSetfAuth));
+
384 env(trust(issuer, asset(0), depositor, tfSetfAuth));
+
385 env(trust(issuer, asset(0), charlie, tfSetfAuth));
+
386 env(pay(issuer, depositor, asset(1000)));
+
387 env.close();
+
388 return asset;
+
389 });
+
390
+
391 testCases(
+
392 "MPT",
+
393 [](Env& env,
+
394 Account const& issuer,
+
395 Account const& owner,
+
396 Account const& depositor,
+
397 Account const& charlie) -> Asset {
+
398 MPTTester mptt{env, issuer, mptInitNoFund};
+
399 mptt.create(
+
400 {.flags =
+
401 tfMPTCanClawback | tfMPTCanTransfer | tfMPTCanLock});
+
402 PrettyAsset asset = mptt.issuanceID();
+
403 mptt.authorize({.account = depositor});
+
404 mptt.authorize({.account = charlie});
+
405 env(pay(issuer, depositor, asset(1000)));
+
406 env.close();
+
407 return asset;
+
408 });
+
409 }
+
410
+
411 void
+
412 testPreflight()
+
413 {
+
414 using namespace test::jtx;
+
415
+
416 struct CaseArgs
+
417 {
+
418 FeatureBitset features =
+
419 supported_amendments() | featureSingleAssetVault;
+
420 };
+
421
+
422 auto testCase = [&, this](
+
423 std::function<void(
+
424 Env & env,
+
425 Account const& issuer,
+
426 Account const& owner,
+
427 Asset const& asset,
+
428 Vault& vault)> test,
+
429 CaseArgs args = {}) {
+
430 Env env{*this, args.features};
+
431 Account issuer{"issuer"};
+
432 Account owner{"owner"};
+
433 Vault vault{env};
+
434 env.fund(XRP(1000), issuer, owner);
+
435 env.close();
+
436
+
437 env(fset(issuer, asfAllowTrustLineClawback));
+
438 env(fset(issuer, asfRequireAuth));
+
439 env.close();
+
440
+
441 PrettyAsset asset = issuer["IOU"];
+
442 env(trust(owner, asset(1000)));
+
443 env(trust(issuer, asset(0), owner, tfSetfAuth));
+
444 env(pay(issuer, owner, asset(1000)));
445 env.close();
446
-
447 env(fset(issuer, asfAllowTrustLineClawback));
-
448 env(fset(issuer, asfRequireAuth));
-
449 env.close();
-
450
-
451 PrettyAsset asset = issuer["IOU"];
-
452 env(trust(owner, asset(1000)));
-
453 env(trust(issuer, asset(0), owner, tfSetfAuth));
-
454 env(pay(issuer, owner, asset(1000)));
-
455 env.close();
-
456
-
457 test(env, issuer, owner, asset, vault);
-
458 };
-
459
-
460 testCase(
-
461 [&](Env& env,
-
462 Account const& issuer,
-
463 Account const& owner,
-
464 Asset const& asset,
-
465 Vault& vault) {
-
466 testcase("disabled single asset vault");
-
467
-
468 auto [tx, keylet] =
-
469 vault.create({.owner = owner, .asset = asset});
-
470 env(tx, ter{temDISABLED});
-
471
-
472 {
-
473 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
474 env(tx, ter{temDISABLED});
-
475 }
-
476
-
477 {
-
478 auto tx = vault.deposit(
-
479 {.depositor = owner,
-
480 .id = keylet.key,
-
481 .amount = asset(10)});
-
482 env(tx, ter{temDISABLED});
-
483 }
-
484
-
485 {
-
486 auto tx = vault.withdraw(
-
487 {.depositor = owner,
-
488 .id = keylet.key,
-
489 .amount = asset(10)});
-
490 env(tx, ter{temDISABLED});
-
491 }
-
492
-
493 {
-
494 auto tx = vault.clawback(
-
495 {.issuer = issuer,
-
496 .id = keylet.key,
-
497 .holder = owner,
-
498 .amount = asset(10)});
-
499 env(tx, ter{temDISABLED});
-
500 }
-
501
-
502 {
-
503 auto tx = vault.del({.owner = owner, .id = keylet.key});
-
504 env(tx, ter{temDISABLED});
-
505 }
-
506 },
-
507 {.features = supported_amendments() - featureSingleAssetVault});
-
508
-
509 testCase([&](Env& env,
-
510 Account const& issuer,
-
511 Account const& owner,
-
512 Asset const& asset,
-
513 Vault& vault) {
-
514 testcase("invalid flags");
+
447 test(env, issuer, owner, asset, vault);
+
448 };
+
449
+
450 testCase(
+
451 [&](Env& env,
+
452 Account const& issuer,
+
453 Account const& owner,
+
454 Asset const& asset,
+
455 Vault& vault) {
+
456 testcase("disabled single asset vault");
+
457
+
458 auto [tx, keylet] =
+
459 vault.create({.owner = owner, .asset = asset});
+
460 env(tx, ter{temDISABLED});
+
461
+
462 {
+
463 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
464 env(tx, ter{temDISABLED});
+
465 }
+
466
+
467 {
+
468 auto tx = vault.deposit(
+
469 {.depositor = owner,
+
470 .id = keylet.key,
+
471 .amount = asset(10)});
+
472 env(tx, ter{temDISABLED});
+
473 }
+
474
+
475 {
+
476 auto tx = vault.withdraw(
+
477 {.depositor = owner,
+
478 .id = keylet.key,
+
479 .amount = asset(10)});
+
480 env(tx, ter{temDISABLED});
+
481 }
+
482
+
483 {
+
484 auto tx = vault.clawback(
+
485 {.issuer = issuer,
+
486 .id = keylet.key,
+
487 .holder = owner,
+
488 .amount = asset(10)});
+
489 env(tx, ter{temDISABLED});
+
490 }
+
491
+
492 {
+
493 auto tx = vault.del({.owner = owner, .id = keylet.key});
+
494 env(tx, ter{temDISABLED});
+
495 }
+
496 },
+
497 {.features = supported_amendments() - featureSingleAssetVault});
+
498
+
499 testCase([&](Env& env,
+
500 Account const& issuer,
+
501 Account const& owner,
+
502 Asset const& asset,
+
503 Vault& vault) {
+
504 testcase("invalid flags");
+
505
+
506 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
507 tx[sfFlags] = tfClearDeepFreeze;
+
508 env(tx, ter{temINVALID_FLAG});
+
509
+
510 {
+
511 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
512 tx[sfFlags] = tfClearDeepFreeze;
+
513 env(tx, ter{temINVALID_FLAG});
+
514 }
515
-
516 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
517 tx[sfFlags] = tfClearDeepFreeze;
-
518 env(tx, ter{temINVALID_FLAG});
-
519
-
520 {
-
521 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
522 tx[sfFlags] = tfClearDeepFreeze;
-
523 env(tx, ter{temINVALID_FLAG});
-
524 }
-
525
-
526 {
-
527 auto tx = vault.deposit(
-
528 {.depositor = owner,
-
529 .id = keylet.key,
-
530 .amount = asset(10)});
-
531 tx[sfFlags] = tfClearDeepFreeze;
-
532 env(tx, ter{temINVALID_FLAG});
-
533 }
-
534
-
535 {
-
536 auto tx = vault.withdraw(
-
537 {.depositor = owner,
-
538 .id = keylet.key,
+
516 {
+
517 auto tx = vault.deposit(
+
518 {.depositor = owner,
+
519 .id = keylet.key,
+
520 .amount = asset(10)});
+
521 tx[sfFlags] = tfClearDeepFreeze;
+
522 env(tx, ter{temINVALID_FLAG});
+
523 }
+
524
+
525 {
+
526 auto tx = vault.withdraw(
+
527 {.depositor = owner,
+
528 .id = keylet.key,
+
529 .amount = asset(10)});
+
530 tx[sfFlags] = tfClearDeepFreeze;
+
531 env(tx, ter{temINVALID_FLAG});
+
532 }
+
533
+
534 {
+
535 auto tx = vault.clawback(
+
536 {.issuer = issuer,
+
537 .id = keylet.key,
+
538 .holder = owner,
539 .amount = asset(10)});
540 tx[sfFlags] = tfClearDeepFreeze;
541 env(tx, ter{temINVALID_FLAG});
542 }
543
544 {
-
545 auto tx = vault.clawback(
-
546 {.issuer = issuer,
-
547 .id = keylet.key,
-
548 .holder = owner,
-
549 .amount = asset(10)});
-
550 tx[sfFlags] = tfClearDeepFreeze;
-
551 env(tx, ter{temINVALID_FLAG});
-
552 }
-
553
-
554 {
-
555 auto tx = vault.del({.owner = owner, .id = keylet.key});
-
556 tx[sfFlags] = tfClearDeepFreeze;
-
557 env(tx, ter{temINVALID_FLAG});
-
558 }
-
559 });
-
560
-
561 testCase([&](Env& env,
-
562 Account const& issuer,
-
563 Account const& owner,
-
564 Asset const& asset,
-
565 Vault& vault) {
-
566 testcase("invalid fee");
+
545 auto tx = vault.del({.owner = owner, .id = keylet.key});
+
546 tx[sfFlags] = tfClearDeepFreeze;
+
547 env(tx, ter{temINVALID_FLAG});
+
548 }
+
549 });
+
550
+
551 testCase([&](Env& env,
+
552 Account const& issuer,
+
553 Account const& owner,
+
554 Asset const& asset,
+
555 Vault& vault) {
+
556 testcase("invalid fee");
+
557
+
558 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
559 tx[jss::Fee] = "-1";
+
560 env(tx, ter{temBAD_FEE});
+
561
+
562 {
+
563 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
564 tx[jss::Fee] = "-1";
+
565 env(tx, ter{temBAD_FEE});
+
566 }
567
-
568 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
569 tx[jss::Fee] = "-1";
-
570 env(tx, ter{temBAD_FEE});
-
571
-
572 {
-
573 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
574 tx[jss::Fee] = "-1";
-
575 env(tx, ter{temBAD_FEE});
-
576 }
-
577
-
578 {
-
579 auto tx = vault.deposit(
-
580 {.depositor = owner,
-
581 .id = keylet.key,
-
582 .amount = asset(10)});
-
583 tx[jss::Fee] = "-1";
-
584 env(tx, ter{temBAD_FEE});
-
585 }
-
586
-
587 {
-
588 auto tx = vault.withdraw(
-
589 {.depositor = owner,
-
590 .id = keylet.key,
+
568 {
+
569 auto tx = vault.deposit(
+
570 {.depositor = owner,
+
571 .id = keylet.key,
+
572 .amount = asset(10)});
+
573 tx[jss::Fee] = "-1";
+
574 env(tx, ter{temBAD_FEE});
+
575 }
+
576
+
577 {
+
578 auto tx = vault.withdraw(
+
579 {.depositor = owner,
+
580 .id = keylet.key,
+
581 .amount = asset(10)});
+
582 tx[jss::Fee] = "-1";
+
583 env(tx, ter{temBAD_FEE});
+
584 }
+
585
+
586 {
+
587 auto tx = vault.clawback(
+
588 {.issuer = issuer,
+
589 .id = keylet.key,
+
590 .holder = owner,
591 .amount = asset(10)});
592 tx[jss::Fee] = "-1";
593 env(tx, ter{temBAD_FEE});
594 }
595
596 {
-
597 auto tx = vault.clawback(
-
598 {.issuer = issuer,
-
599 .id = keylet.key,
-
600 .holder = owner,
-
601 .amount = asset(10)});
-
602 tx[jss::Fee] = "-1";
-
603 env(tx, ter{temBAD_FEE});
-
604 }
-
605
-
606 {
-
607 auto tx = vault.del({.owner = owner, .id = keylet.key});
-
608 tx[jss::Fee] = "-1";
-
609 env(tx, ter{temBAD_FEE});
-
610 }
-
611 });
-
612
-
613 testCase(
-
614 [&](Env& env,
-
615 Account const&,
-
616 Account const& owner,
-
617 Asset const&,
-
618 Vault& vault) {
-
619 testcase("disabled permissioned domain");
-
620
-
621 auto [tx, keylet] =
-
622 vault.create({.owner = owner, .asset = xrpIssue()});
-
623 tx[sfDomainID] = to_string(base_uint<256>(42ul));
-
624 env(tx, ter{temDISABLED});
-
625
-
626 {
-
627 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
628 tx[sfDomainID] = to_string(base_uint<256>(42ul));
-
629 env(tx, ter{temDISABLED});
-
630 }
-
631
-
632 {
-
633 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
634 tx[sfDomainID] = "0";
-
635 env(tx, ter{temDISABLED});
-
636 }
-
637 },
-
638 {.features = (supported_amendments() | featureSingleAssetVault) -
-
639 featurePermissionedDomains});
+
597 auto tx = vault.del({.owner = owner, .id = keylet.key});
+
598 tx[jss::Fee] = "-1";
+
599 env(tx, ter{temBAD_FEE});
+
600 }
+
601 });
+
602
+
603 testCase(
+
604 [&](Env& env,
+
605 Account const&,
+
606 Account const& owner,
+
607 Asset const&,
+
608 Vault& vault) {
+
609 testcase("disabled permissioned domain");
+
610
+
611 auto [tx, keylet] =
+
612 vault.create({.owner = owner, .asset = xrpIssue()});
+
613 tx[sfDomainID] = to_string(base_uint<256>(42ul));
+
614 env(tx, ter{temDISABLED});
+
615
+
616 {
+
617 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
618 tx[sfDomainID] = to_string(base_uint<256>(42ul));
+
619 env(tx, ter{temDISABLED});
+
620 }
+
621
+
622 {
+
623 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
624 tx[sfDomainID] = "0";
+
625 env(tx, ter{temDISABLED});
+
626 }
+
627 },
+
628 {.features = (supported_amendments() | featureSingleAssetVault) -
+
629 featurePermissionedDomains});
+
630
+
631 testCase([&](Env& env,
+
632 Account const& issuer,
+
633 Account const& owner,
+
634 Asset const& asset,
+
635 Vault& vault) {
+
636 testcase("use zero vault");
+
637
+
638 auto [tx, keylet] =
+
639 vault.create({.owner = owner, .asset = xrpIssue()});
640
-
641 testCase([&](Env& env,
-
642 Account const& issuer,
-
643 Account const& owner,
-
644 Asset const& asset,
-
645 Vault& vault) {
-
646 testcase("use zero vault");
-
647
-
648 auto [tx, keylet] =
-
649 vault.create({.owner = owner, .asset = xrpIssue()});
-
650
-
651 {
-
652 auto tx = vault.set({
-
653 .owner = owner,
-
654 .id = beast::zero,
-
655 });
-
656 env(tx, ter{temMALFORMED});
-
657 }
-
658
-
659 {
-
660 auto tx = vault.deposit(
-
661 {.depositor = owner,
-
662 .id = beast::zero,
-
663 .amount = asset(10)});
-
664 env(tx, ter(temMALFORMED));
-
665 }
-
666
-
667 {
-
668 auto tx = vault.withdraw(
-
669 {.depositor = owner,
-
670 .id = beast::zero,
-
671 .amount = asset(10)});
-
672 env(tx, ter{temMALFORMED});
-
673 }
-
674
-
675 {
-
676 auto tx = vault.clawback(
-
677 {.issuer = issuer,
-
678 .id = beast::zero,
-
679 .holder = owner,
-
680 .amount = asset(10)});
-
681 env(tx, ter{temMALFORMED});
-
682 }
-
683
-
684 {
-
685 auto tx = vault.del({
-
686 .owner = owner,
-
687 .id = beast::zero,
-
688 });
-
689 env(tx, ter{temMALFORMED});
-
690 }
-
691 });
-
692
-
693 testCase([&](Env& env,
-
694 Account const& issuer,
-
695 Account const& owner,
-
696 Asset const& asset,
-
697 Vault& vault) {
-
698 testcase("clawback from self");
-
699
-
700 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
641 {
+
642 auto tx = vault.set({
+
643 .owner = owner,
+
644 .id = beast::zero,
+
645 });
+
646 env(tx, ter{temMALFORMED});
+
647 }
+
648
+
649 {
+
650 auto tx = vault.deposit(
+
651 {.depositor = owner,
+
652 .id = beast::zero,
+
653 .amount = asset(10)});
+
654 env(tx, ter(temMALFORMED));
+
655 }
+
656
+
657 {
+
658 auto tx = vault.withdraw(
+
659 {.depositor = owner,
+
660 .id = beast::zero,
+
661 .amount = asset(10)});
+
662 env(tx, ter{temMALFORMED});
+
663 }
+
664
+
665 {
+
666 auto tx = vault.clawback(
+
667 {.issuer = issuer,
+
668 .id = beast::zero,
+
669 .holder = owner,
+
670 .amount = asset(10)});
+
671 env(tx, ter{temMALFORMED});
+
672 }
+
673
+
674 {
+
675 auto tx = vault.del({
+
676 .owner = owner,
+
677 .id = beast::zero,
+
678 });
+
679 env(tx, ter{temMALFORMED});
+
680 }
+
681 });
+
682
+
683 testCase([&](Env& env,
+
684 Account const& issuer,
+
685 Account const& owner,
+
686 Asset const& asset,
+
687 Vault& vault) {
+
688 testcase("clawback from self");
+
689
+
690 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
691
+
692 {
+
693 auto tx = vault.clawback(
+
694 {.issuer = issuer,
+
695 .id = keylet.key,
+
696 .holder = issuer,
+
697 .amount = asset(10)});
+
698 env(tx, ter{temMALFORMED});
+
699 }
+
700 });
701
-
702 {
-
703 auto tx = vault.clawback(
-
704 {.issuer = issuer,
-
705 .id = keylet.key,
-
706 .holder = issuer,
-
707 .amount = asset(10)});
-
708 env(tx, ter{temMALFORMED});
-
709 }
-
710 });
-
711
-
712 testCase([&](Env& env,
-
713 Account const&,
-
714 Account const& owner,
-
715 Asset const& asset,
-
716 Vault& vault) {
-
717 testcase("withdraw to bad destination");
-
718
-
719 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
702 testCase([&](Env& env,
+
703 Account const&,
+
704 Account const& owner,
+
705 Asset const& asset,
+
706 Vault& vault) {
+
707 testcase("withdraw to bad destination");
+
708
+
709 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
710
+
711 {
+
712 auto tx = vault.withdraw(
+
713 {.depositor = owner,
+
714 .id = keylet.key,
+
715 .amount = asset(10)});
+
716 tx[jss::Destination] = "0";
+
717 env(tx, ter{temMALFORMED});
+
718 }
+
719 });
720
-
721 {
-
722 auto tx = vault.withdraw(
-
723 {.depositor = owner,
-
724 .id = keylet.key,
-
725 .amount = asset(10)});
-
726 tx[jss::Destination] = "0";
-
727 env(tx, ter{temMALFORMED});
-
728 }
-
729 });
-
730
-
731 testCase([&](Env& env,
-
732 Account const&,
-
733 Account const& owner,
-
734 Asset const& asset,
-
735 Vault& vault) {
-
736 testcase("create or set invalid data");
-
737
-
738 auto [tx1, keylet] = vault.create({.owner = owner, .asset = asset});
-
739
-
740 {
-
741 auto tx = tx1;
-
742 tx[sfData] = "";
-
743 env(tx, ter(temMALFORMED));
-
744 }
-
745
-
746 {
-
747 auto tx = tx1;
-
748 // A hexadecimal string of 257 bytes.
-
749 tx[sfData] = std::string(514, 'A');
-
750 env(tx, ter(temMALFORMED));
-
751 }
-
752
-
753 {
-
754 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
755 tx[sfData] = "";
-
756 env(tx, ter{temMALFORMED});
-
757 }
-
758
-
759 {
-
760 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
761 // A hexadecimal string of 257 bytes.
-
762 tx[sfData] = std::string(514, 'A');
-
763 env(tx, ter{temMALFORMED});
-
764 }
-
765 });
-
766
-
767 testCase([&](Env& env,
-
768 Account const&,
-
769 Account const& owner,
-
770 Asset const& asset,
-
771 Vault& vault) {
-
772 testcase("set nothing updated");
-
773
-
774 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
775
-
776 {
-
777 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
778 env(tx, ter{temMALFORMED});
-
779 }
-
780 });
-
781
-
782 testCase([&](Env& env,
-
783 Account const&,
-
784 Account const& owner,
-
785 Asset const& asset,
-
786 Vault& vault) {
-
787 testcase("create with invalid metadata");
-
788
-
789 auto [tx1, keylet] = vault.create({.owner = owner, .asset = asset});
-
790
-
791 {
-
792 auto tx = tx1;
-
793 tx[sfMPTokenMetadata] = "";
-
794 env(tx, ter(temMALFORMED));
-
795 }
-
796
-
797 {
-
798 auto tx = tx1;
-
799 // This metadata is for the share token.
-
800 // A hexadecimal string of 1025 bytes.
-
801 tx[sfMPTokenMetadata] = std::string(2050, 'B');
-
802 env(tx, ter(temMALFORMED));
-
803 }
-
804 });
-
805
-
806 testCase([&](Env& env,
-
807 Account const&,
-
808 Account const& owner,
-
809 Asset const& asset,
-
810 Vault& vault) {
-
811 testcase("set negative maximum");
-
812
-
813 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
814
-
815 {
-
816 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
817 tx[sfAssetsMaximum] = negativeAmount(asset).number();
-
818 env(tx, ter{temMALFORMED});
-
819 }
-
820 });
-
821
-
822 testCase([&](Env& env,
-
823 Account const&,
-
824 Account const& owner,
-
825 Asset const& asset,
-
826 Vault& vault) {
-
827 testcase("invalid deposit amount");
+
721 testCase([&](Env& env,
+
722 Account const&,
+
723 Account const& owner,
+
724 Asset const& asset,
+
725 Vault& vault) {
+
726 testcase("create or set invalid data");
+
727
+
728 auto [tx1, keylet] = vault.create({.owner = owner, .asset = asset});
+
729
+
730 {
+
731 auto tx = tx1;
+
732 tx[sfData] = "";
+
733 env(tx, ter(temMALFORMED));
+
734 }
+
735
+
736 {
+
737 auto tx = tx1;
+
738 // A hexadecimal string of 257 bytes.
+
739 tx[sfData] = std::string(514, 'A');
+
740 env(tx, ter(temMALFORMED));
+
741 }
+
742
+
743 {
+
744 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
745 tx[sfData] = "";
+
746 env(tx, ter{temMALFORMED});
+
747 }
+
748
+
749 {
+
750 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
751 // A hexadecimal string of 257 bytes.
+
752 tx[sfData] = std::string(514, 'A');
+
753 env(tx, ter{temMALFORMED});
+
754 }
+
755 });
+
756
+
757 testCase([&](Env& env,
+
758 Account const&,
+
759 Account const& owner,
+
760 Asset const& asset,
+
761 Vault& vault) {
+
762 testcase("set nothing updated");
+
763
+
764 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
765
+
766 {
+
767 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
768 env(tx, ter{temMALFORMED});
+
769 }
+
770 });
+
771
+
772 testCase([&](Env& env,
+
773 Account const&,
+
774 Account const& owner,
+
775 Asset const& asset,
+
776 Vault& vault) {
+
777 testcase("create with invalid metadata");
+
778
+
779 auto [tx1, keylet] = vault.create({.owner = owner, .asset = asset});
+
780
+
781 {
+
782 auto tx = tx1;
+
783 tx[sfMPTokenMetadata] = "";
+
784 env(tx, ter(temMALFORMED));
+
785 }
+
786
+
787 {
+
788 auto tx = tx1;
+
789 // This metadata is for the share token.
+
790 // A hexadecimal string of 1025 bytes.
+
791 tx[sfMPTokenMetadata] = std::string(2050, 'B');
+
792 env(tx, ter(temMALFORMED));
+
793 }
+
794 });
+
795
+
796 testCase([&](Env& env,
+
797 Account const&,
+
798 Account const& owner,
+
799 Asset const& asset,
+
800 Vault& vault) {
+
801 testcase("set negative maximum");
+
802
+
803 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
804
+
805 {
+
806 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
807 tx[sfAssetsMaximum] = negativeAmount(asset).number();
+
808 env(tx, ter{temMALFORMED});
+
809 }
+
810 });
+
811
+
812 testCase([&](Env& env,
+
813 Account const&,
+
814 Account const& owner,
+
815 Asset const& asset,
+
816 Vault& vault) {
+
817 testcase("invalid deposit amount");
+
818
+
819 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
820
+
821 {
+
822 auto tx = vault.deposit(
+
823 {.depositor = owner,
+
824 .id = keylet.key,
+
825 .amount = negativeAmount(asset)});
+
826 env(tx, ter(temBAD_AMOUNT));
+
827 }
828
-
829 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
830
-
831 {
-
832 auto tx = vault.deposit(
-
833 {.depositor = owner,
-
834 .id = keylet.key,
-
835 .amount = negativeAmount(asset)});
-
836 env(tx, ter(temBAD_AMOUNT));
-
837 }
-
838
-
839 {
-
840 auto tx = vault.deposit(
-
841 {.depositor = owner, .id = keylet.key, .amount = asset(0)});
-
842 env(tx, ter(temBAD_AMOUNT));
-
843 }
-
844 });
-
845
-
846 testCase([&](Env& env,
-
847 Account const&,
-
848 Account const& owner,
-
849 Asset const& asset,
-
850 Vault& vault) {
-
851 testcase("invalid set immutable flag");
-
852
-
853 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
854
-
855 {
-
856 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
857 tx[sfFlags] = tfVaultPrivate;
-
858 env(tx, ter(temINVALID_FLAG));
-
859 }
-
860 });
-
861
-
862 testCase([&](Env& env,
-
863 Account const&,
-
864 Account const& owner,
-
865 Asset const& asset,
-
866 Vault& vault) {
-
867 testcase("invalid withdraw amount");
+
829 {
+
830 auto tx = vault.deposit(
+
831 {.depositor = owner, .id = keylet.key, .amount = asset(0)});
+
832 env(tx, ter(temBAD_AMOUNT));
+
833 }
+
834 });
+
835
+
836 testCase([&](Env& env,
+
837 Account const&,
+
838 Account const& owner,
+
839 Asset const& asset,
+
840 Vault& vault) {
+
841 testcase("invalid set immutable flag");
+
842
+
843 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
844
+
845 {
+
846 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
847 tx[sfFlags] = tfVaultPrivate;
+
848 env(tx, ter(temINVALID_FLAG));
+
849 }
+
850 });
+
851
+
852 testCase([&](Env& env,
+
853 Account const&,
+
854 Account const& owner,
+
855 Asset const& asset,
+
856 Vault& vault) {
+
857 testcase("invalid withdraw amount");
+
858
+
859 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
860
+
861 {
+
862 auto tx = vault.withdraw(
+
863 {.depositor = owner,
+
864 .id = keylet.key,
+
865 .amount = negativeAmount(asset)});
+
866 env(tx, ter(temBAD_AMOUNT));
+
867 }
868
-
869 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
870
-
871 {
-
872 auto tx = vault.withdraw(
-
873 {.depositor = owner,
-
874 .id = keylet.key,
-
875 .amount = negativeAmount(asset)});
-
876 env(tx, ter(temBAD_AMOUNT));
-
877 }
-
878
-
879 {
-
880 auto tx = vault.withdraw(
-
881 {.depositor = owner, .id = keylet.key, .amount = asset(0)});
-
882 env(tx, ter(temBAD_AMOUNT));
-
883 }
-
884 });
-
885
-
886 testCase([&](Env& env,
-
887 Account const& issuer,
-
888 Account const& owner,
-
889 Asset const& asset,
-
890 Vault& vault) {
-
891 testcase("invalid clawback");
-
892
-
893 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
894
-
895 {
-
896 auto tx = vault.clawback(
-
897 {.issuer = owner,
-
898 .id = keylet.key,
-
899 .holder = issuer,
-
900 .amount = asset(50)});
-
901 env(tx, ter(temMALFORMED));
-
902 }
+
869 {
+
870 auto tx = vault.withdraw(
+
871 {.depositor = owner, .id = keylet.key, .amount = asset(0)});
+
872 env(tx, ter(temBAD_AMOUNT));
+
873 }
+
874 });
+
875
+
876 testCase([&](Env& env,
+
877 Account const& issuer,
+
878 Account const& owner,
+
879 Asset const& asset,
+
880 Vault& vault) {
+
881 testcase("invalid clawback");
+
882
+
883 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
884
+
885 {
+
886 auto tx = vault.clawback(
+
887 {.issuer = owner,
+
888 .id = keylet.key,
+
889 .holder = issuer,
+
890 .amount = asset(50)});
+
891 env(tx, ter(temMALFORMED));
+
892 }
+
893
+
894 {
+
895 auto tx = vault.clawback(
+
896 {.issuer = issuer,
+
897 .id = keylet.key,
+
898 .holder = owner,
+
899 .amount = negativeAmount(asset)});
+
900 env(tx, ter(temBAD_AMOUNT));
+
901 }
+
902 });
903
-
904 {
-
905 auto tx = vault.clawback(
-
906 {.issuer = issuer,
-
907 .id = keylet.key,
-
908 .holder = owner,
-
909 .amount = negativeAmount(asset)});
-
910 env(tx, ter(temBAD_AMOUNT));
-
911 }
-
912 });
-
913
-
914 testCase([&](Env& env,
-
915 Account const&,
-
916 Account const& owner,
-
917 Asset const& asset,
-
918 Vault& vault) {
-
919 testcase("invalid create");
-
920
-
921 auto [tx1, keylet] = vault.create({.owner = owner, .asset = asset});
-
922
-
923 {
-
924 auto tx = tx1;
-
925 tx[sfWithdrawalPolicy] = 0;
-
926 env(tx, ter(temMALFORMED));
-
927 }
-
928
-
929 {
-
930 auto tx = tx1;
-
931 tx[sfDomainID] = to_string(base_uint<256>(42ul));
-
932 env(tx, ter{temMALFORMED});
-
933 }
-
934
-
935 {
-
936 auto tx = tx1;
-
937 tx[sfAssetsMaximum] = negativeAmount(asset).number();
-
938 env(tx, ter{temMALFORMED});
-
939 }
-
940
-
941 {
-
942 auto tx = tx1;
-
943 tx[sfFlags] = tfVaultPrivate;
-
944 tx[sfDomainID] = "0";
-
945 env(tx, ter{temMALFORMED});
-
946 }
-
947 });
-
948 }
-
949
-
950 // Test for non-asset specific behaviors.
-
951 void
-
952 testCreateFailXRP()
-
953 {
-
954 using namespace test::jtx;
-
955
-
956 auto testCase = [this](std::function<void(
-
957 Env & env,
-
958 Account const& issuer,
-
959 Account const& owner,
-
960 Account const& depositor,
-
961 Asset const& asset,
-
962 Vault& vault)> test) {
-
963 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
964 Account issuer{"issuer"};
-
965 Account owner{"owner"};
-
966 Account depositor{"depositor"};
-
967 env.fund(XRP(1000), issuer, owner, depositor);
-
968 env.close();
-
969 Vault vault{env};
-
970 Asset asset = xrpIssue();
-
971
-
972 test(env, issuer, owner, depositor, asset, vault);
-
973 };
-
974
-
975 testCase([this](
-
976 Env& env,
-
977 Account const& issuer,
-
978 Account const& owner,
-
979 Account const& depositor,
-
980 PrettyAsset const& asset,
-
981 Vault& vault) {
-
982 testcase("nothing to set");
-
983 auto tx = vault.set({.owner = owner, .id = keylet::skip().key});
-
984 tx[sfAssetsMaximum] = asset(0).number();
-
985 env(tx, ter(tecNO_ENTRY));
-
986 });
-
987
-
988 testCase([this](
-
989 Env& env,
-
990 Account const& issuer,
-
991 Account const& owner,
-
992 Account const& depositor,
-
993 PrettyAsset const& asset,
-
994 Vault& vault) {
-
995 testcase("nothing to deposit to");
-
996 auto tx = vault.deposit(
-
997 {.depositor = depositor,
-
998 .id = keylet::skip().key,
-
999 .amount = asset(10)});
-
1000 env(tx, ter(tecNO_ENTRY));
-
1001 });
-
1002
-
1003 testCase([this](
-
1004 Env& env,
-
1005 Account const& issuer,
-
1006 Account const& owner,
-
1007 Account const& depositor,
-
1008 PrettyAsset const& asset,
-
1009 Vault& vault) {
-
1010 testcase("nothing to withdraw from");
-
1011 auto tx = vault.withdraw(
-
1012 {.depositor = depositor,
-
1013 .id = keylet::skip().key,
-
1014 .amount = asset(10)});
-
1015 env(tx, ter(tecNO_ENTRY));
-
1016 });
-
1017
-
1018 testCase([this](
-
1019 Env& env,
-
1020 Account const& issuer,
-
1021 Account const& owner,
-
1022 Account const& depositor,
-
1023 Asset const& asset,
-
1024 Vault& vault) {
-
1025 testcase("nothing to delete");
-
1026 auto tx = vault.del({.owner = owner, .id = keylet::skip().key});
-
1027 env(tx, ter(tecNO_ENTRY));
-
1028 });
-
1029
-
1030 testCase([this](
-
1031 Env& env,
-
1032 Account const& issuer,
-
1033 Account const& owner,
-
1034 Account const& depositor,
-
1035 Asset const& asset,
-
1036 Vault& vault) {
-
1037 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1038 testcase("transaction is good");
-
1039 env(tx);
-
1040 });
-
1041
-
1042 testCase([this](
-
1043 Env& env,
-
1044 Account const& issuer,
-
1045 Account const& owner,
-
1046 Account const& depositor,
-
1047 Asset const& asset,
-
1048 Vault& vault) {
-
1049 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1050 tx[sfWithdrawalPolicy] = 1;
-
1051 testcase("explicitly select withdrawal policy");
-
1052 env(tx);
-
1053 });
-
1054
-
1055 testCase([this](
-
1056 Env& env,
-
1057 Account const& issuer,
-
1058 Account const& owner,
-
1059 Account const& depositor,
-
1060 Asset const& asset,
-
1061 Vault& vault) {
-
1062 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1063 testcase("insufficient fee");
-
1064 env(tx, fee(env.current()->fees().base), ter(telINSUF_FEE_P));
-
1065 });
-
1066
-
1067 testCase([this](
-
1068 Env& env,
-
1069 Account const& issuer,
-
1070 Account const& owner,
-
1071 Account const& depositor,
-
1072 Asset const& asset,
-
1073 Vault& vault) {
-
1074 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1075 testcase("insufficient reserve");
-
1076 // It is possible to construct a complicated mathematical
-
1077 // expression for this amount, but it is sadly not easy.
-
1078 env(pay(owner, issuer, XRP(775)));
-
1079 env.close();
-
1080 env(tx, ter(tecINSUFFICIENT_RESERVE));
-
1081 });
-
1082
-
1083 testCase([this](
-
1084 Env& env,
-
1085 Account const& issuer,
-
1086 Account const& owner,
-
1087 Account const& depositor,
-
1088 Asset const& asset,
-
1089 Vault& vault) {
-
1090 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1091 tx[sfFlags] = tfVaultPrivate;
-
1092 tx[sfDomainID] = to_string(base_uint<256>(42ul));
-
1093 testcase("non-existing domain");
-
1094 env(tx, ter{tecOBJECT_NOT_FOUND});
-
1095 });
-
1096 }
-
1097
-
1098 void
-
1099 testCreateFailIOU()
-
1100 {
-
1101 using namespace test::jtx;
-
1102 {
-
1103 {
-
1104 testcase("IOU fail create frozen");
-
1105 Env env{
-
1106 *this, supported_amendments() | featureSingleAssetVault};
-
1107 Account issuer{"issuer"};
-
1108 Account owner{"owner"};
-
1109 env.fund(XRP(1000), issuer, owner);
+
904 testCase([&](Env& env,
+
905 Account const&,
+
906 Account const& owner,
+
907 Asset const& asset,
+
908 Vault& vault) {
+
909 testcase("invalid create");
+
910
+
911 auto [tx1, keylet] = vault.create({.owner = owner, .asset = asset});
+
912
+
913 {
+
914 auto tx = tx1;
+
915 tx[sfWithdrawalPolicy] = 0;
+
916 env(tx, ter(temMALFORMED));
+
917 }
+
918
+
919 {
+
920 auto tx = tx1;
+
921 tx[sfDomainID] = to_string(base_uint<256>(42ul));
+
922 env(tx, ter{temMALFORMED});
+
923 }
+
924
+
925 {
+
926 auto tx = tx1;
+
927 tx[sfAssetsMaximum] = negativeAmount(asset).number();
+
928 env(tx, ter{temMALFORMED});
+
929 }
+
930
+
931 {
+
932 auto tx = tx1;
+
933 tx[sfFlags] = tfVaultPrivate;
+
934 tx[sfDomainID] = "0";
+
935 env(tx, ter{temMALFORMED});
+
936 }
+
937 });
+
938 }
+
939
+
940 // Test for non-asset specific behaviors.
+
941 void
+
942 testCreateFailXRP()
+
943 {
+
944 using namespace test::jtx;
+
945
+
946 auto testCase = [this](std::function<void(
+
947 Env & env,
+
948 Account const& issuer,
+
949 Account const& owner,
+
950 Account const& depositor,
+
951 Asset const& asset,
+
952 Vault& vault)> test) {
+
953 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
954 Account issuer{"issuer"};
+
955 Account owner{"owner"};
+
956 Account depositor{"depositor"};
+
957 env.fund(XRP(1000), issuer, owner, depositor);
+
958 env.close();
+
959 Vault vault{env};
+
960 Asset asset = xrpIssue();
+
961
+
962 test(env, issuer, owner, depositor, asset, vault);
+
963 };
+
964
+
965 testCase([this](
+
966 Env& env,
+
967 Account const& issuer,
+
968 Account const& owner,
+
969 Account const& depositor,
+
970 PrettyAsset const& asset,
+
971 Vault& vault) {
+
972 testcase("nothing to set");
+
973 auto tx = vault.set({.owner = owner, .id = keylet::skip().key});
+
974 tx[sfAssetsMaximum] = asset(0).number();
+
975 env(tx, ter(tecNO_ENTRY));
+
976 });
+
977
+
978 testCase([this](
+
979 Env& env,
+
980 Account const& issuer,
+
981 Account const& owner,
+
982 Account const& depositor,
+
983 PrettyAsset const& asset,
+
984 Vault& vault) {
+
985 testcase("nothing to deposit to");
+
986 auto tx = vault.deposit(
+
987 {.depositor = depositor,
+
988 .id = keylet::skip().key,
+
989 .amount = asset(10)});
+
990 env(tx, ter(tecNO_ENTRY));
+
991 });
+
992
+
993 testCase([this](
+
994 Env& env,
+
995 Account const& issuer,
+
996 Account const& owner,
+
997 Account const& depositor,
+
998 PrettyAsset const& asset,
+
999 Vault& vault) {
+
1000 testcase("nothing to withdraw from");
+
1001 auto tx = vault.withdraw(
+
1002 {.depositor = depositor,
+
1003 .id = keylet::skip().key,
+
1004 .amount = asset(10)});
+
1005 env(tx, ter(tecNO_ENTRY));
+
1006 });
+
1007
+
1008 testCase([this](
+
1009 Env& env,
+
1010 Account const& issuer,
+
1011 Account const& owner,
+
1012 Account const& depositor,
+
1013 Asset const& asset,
+
1014 Vault& vault) {
+
1015 testcase("nothing to delete");
+
1016 auto tx = vault.del({.owner = owner, .id = keylet::skip().key});
+
1017 env(tx, ter(tecNO_ENTRY));
+
1018 });
+
1019
+
1020 testCase([this](
+
1021 Env& env,
+
1022 Account const& issuer,
+
1023 Account const& owner,
+
1024 Account const& depositor,
+
1025 Asset const& asset,
+
1026 Vault& vault) {
+
1027 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1028 testcase("transaction is good");
+
1029 env(tx);
+
1030 });
+
1031
+
1032 testCase([this](
+
1033 Env& env,
+
1034 Account const& issuer,
+
1035 Account const& owner,
+
1036 Account const& depositor,
+
1037 Asset const& asset,
+
1038 Vault& vault) {
+
1039 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1040 tx[sfWithdrawalPolicy] = 1;
+
1041 testcase("explicitly select withdrawal policy");
+
1042 env(tx);
+
1043 });
+
1044
+
1045 testCase([this](
+
1046 Env& env,
+
1047 Account const& issuer,
+
1048 Account const& owner,
+
1049 Account const& depositor,
+
1050 Asset const& asset,
+
1051 Vault& vault) {
+
1052 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1053 testcase("insufficient fee");
+
1054 env(tx, fee(env.current()->fees().base), ter(telINSUF_FEE_P));
+
1055 });
+
1056
+
1057 testCase([this](
+
1058 Env& env,
+
1059 Account const& issuer,
+
1060 Account const& owner,
+
1061 Account const& depositor,
+
1062 Asset const& asset,
+
1063 Vault& vault) {
+
1064 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1065 testcase("insufficient reserve");
+
1066 // It is possible to construct a complicated mathematical
+
1067 // expression for this amount, but it is sadly not easy.
+
1068 env(pay(owner, issuer, XRP(775)));
+
1069 env.close();
+
1070 env(tx, ter(tecINSUFFICIENT_RESERVE));
+
1071 });
+
1072
+
1073 testCase([this](
+
1074 Env& env,
+
1075 Account const& issuer,
+
1076 Account const& owner,
+
1077 Account const& depositor,
+
1078 Asset const& asset,
+
1079 Vault& vault) {
+
1080 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1081 tx[sfFlags] = tfVaultPrivate;
+
1082 tx[sfDomainID] = to_string(base_uint<256>(42ul));
+
1083 testcase("non-existing domain");
+
1084 env(tx, ter{tecOBJECT_NOT_FOUND});
+
1085 });
+
1086 }
+
1087
+
1088 void
+
1089 testCreateFailIOU()
+
1090 {
+
1091 using namespace test::jtx;
+
1092 {
+
1093 {
+
1094 testcase("IOU fail create frozen");
+
1095 Env env{
+
1096 *this, supported_amendments() | featureSingleAssetVault};
+
1097 Account issuer{"issuer"};
+
1098 Account owner{"owner"};
+
1099 env.fund(XRP(1000), issuer, owner);
+
1100 env.close();
+
1101 env(fset(issuer, asfGlobalFreeze));
+
1102 env.close();
+
1103
+
1104 Vault vault{env};
+
1105 Asset asset = issuer["IOU"];
+
1106 auto [tx, keylet] =
+
1107 vault.create({.owner = owner, .asset = asset});
+
1108
+
1109 env(tx, ter(tecFROZEN));
1110 env.close();
-
1111 env(fset(issuer, asfGlobalFreeze));
-
1112 env.close();
-
1113
-
1114 Vault vault{env};
-
1115 Asset asset = issuer["IOU"];
-
1116 auto [tx, keylet] =
-
1117 vault.create({.owner = owner, .asset = asset});
-
1118
-
1119 env(tx, ter(tecFROZEN));
+
1111 }
+
1112
+
1113 {
+
1114 testcase("IOU fail create no ripling");
+
1115 Env env{
+
1116 *this, supported_amendments() | featureSingleAssetVault};
+
1117 Account issuer{"issuer"};
+
1118 Account owner{"owner"};
+
1119 env.fund(XRP(1000), issuer, owner);
1120 env.close();
-
1121 }
-
1122
-
1123 {
-
1124 testcase("IOU fail create no ripling");
-
1125 Env env{
-
1126 *this, supported_amendments() | featureSingleAssetVault};
-
1127 Account issuer{"issuer"};
-
1128 Account owner{"owner"};
-
1129 env.fund(XRP(1000), issuer, owner);
-
1130 env.close();
-
1131 env(fclear(issuer, asfDefaultRipple));
-
1132 env.close();
-
1133
-
1134 Vault vault{env};
-
1135 Asset asset = issuer["IOU"];
-
1136 auto [tx, keylet] =
-
1137 vault.create({.owner = owner, .asset = asset});
-
1138 env(tx, ter(terNO_RIPPLE));
+
1121 env(fclear(issuer, asfDefaultRipple));
+
1122 env.close();
+
1123
+
1124 Vault vault{env};
+
1125 Asset asset = issuer["IOU"];
+
1126 auto [tx, keylet] =
+
1127 vault.create({.owner = owner, .asset = asset});
+
1128 env(tx, ter(terNO_RIPPLE));
+
1129 env.close();
+
1130 }
+
1131
+
1132 {
+
1133 testcase("IOU no issuer");
+
1134 Env env{
+
1135 *this, supported_amendments() | featureSingleAssetVault};
+
1136 Account issuer{"issuer"};
+
1137 Account owner{"owner"};
+
1138 env.fund(XRP(1000), owner);
1139 env.close();
-
1140 }
-
1141
-
1142 {
-
1143 testcase("IOU no issuer");
-
1144 Env env{
-
1145 *this, supported_amendments() | featureSingleAssetVault};
-
1146 Account issuer{"issuer"};
-
1147 Account owner{"owner"};
-
1148 env.fund(XRP(1000), owner);
-
1149 env.close();
-
1150
-
1151 Vault vault{env};
-
1152 Asset asset = issuer["IOU"];
-
1153 {
-
1154 auto [tx, keylet] =
-
1155 vault.create({.owner = owner, .asset = asset});
-
1156 env(tx, ter(terNO_ACCOUNT));
-
1157 env.close();
-
1158 }
-
1159 }
-
1160 }
-
1161
-
1162 {
-
1163 testcase("IOU fail create vault for AMM LPToken");
-
1164 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
1165 Account const gw("gateway");
-
1166 Account const alice("alice");
-
1167 Account const carol("carol");
-
1168 IOU const USD = gw["USD"];
-
1169
-
1170 auto const [asset1, asset2] =
-
1171 std::pair<STAmount, STAmount>(XRP(10000), USD(10000));
-
1172 auto tofund = [&](STAmount const& a) -> STAmount {
-
1173 if (a.native())
-
1174 {
-
1175 auto const defXRP = XRP(30000);
-
1176 if (a <= defXRP)
-
1177 return defXRP;
-
1178 return a + XRP(1000);
-
1179 }
-
1180 auto const defIOU = STAmount{a.issue(), 30000};
-
1181 if (a <= defIOU)
-
1182 return defIOU;
-
1183 return a + STAmount{a.issue(), 1000};
-
1184 };
-
1185 auto const toFund1 = tofund(asset1);
-
1186 auto const toFund2 = tofund(asset2);
-
1187 BEAST_EXPECT(asset1 <= toFund1 && asset2 <= toFund2);
+
1140
+
1141 Vault vault{env};
+
1142 Asset asset = issuer["IOU"];
+
1143 {
+
1144 auto [tx, keylet] =
+
1145 vault.create({.owner = owner, .asset = asset});
+
1146 env(tx, ter(terNO_ACCOUNT));
+
1147 env.close();
+
1148 }
+
1149 }
+
1150 }
+
1151
+
1152 {
+
1153 testcase("IOU fail create vault for AMM LPToken");
+
1154 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
1155 Account const gw("gateway");
+
1156 Account const alice("alice");
+
1157 Account const carol("carol");
+
1158 IOU const USD = gw["USD"];
+
1159
+
1160 auto const [asset1, asset2] =
+
1161 std::pair<STAmount, STAmount>(XRP(10000), USD(10000));
+
1162 auto tofund = [&](STAmount const& a) -> STAmount {
+
1163 if (a.native())
+
1164 {
+
1165 auto const defXRP = XRP(30000);
+
1166 if (a <= defXRP)
+
1167 return defXRP;
+
1168 return a + XRP(1000);
+
1169 }
+
1170 auto const defIOU = STAmount{a.issue(), 30000};
+
1171 if (a <= defIOU)
+
1172 return defIOU;
+
1173 return a + STAmount{a.issue(), 1000};
+
1174 };
+
1175 auto const toFund1 = tofund(asset1);
+
1176 auto const toFund2 = tofund(asset2);
+
1177 BEAST_EXPECT(asset1 <= toFund1 && asset2 <= toFund2);
+
1178
+
1179 if (!asset1.native() && !asset2.native())
+
1180 fund(env, gw, {alice, carol}, {toFund1, toFund2}, Fund::All);
+
1181 else if (asset1.native())
+
1182 fund(env, gw, {alice, carol}, toFund1, {toFund2}, Fund::All);
+
1183 else if (asset2.native())
+
1184 fund(env, gw, {alice, carol}, toFund2, {toFund1}, Fund::All);
+
1185
+
1186 AMM ammAlice(
+
1187 env, alice, asset1, asset2, CreateArg{.log = false, .tfee = 0});
1188
-
1189 if (!asset1.native() && !asset2.native())
-
1190 fund(env, gw, {alice, carol}, {toFund1, toFund2}, Fund::All);
-
1191 else if (asset1.native())
-
1192 fund(env, gw, {alice, carol}, toFund1, {toFund2}, Fund::All);
-
1193 else if (asset2.native())
-
1194 fund(env, gw, {alice, carol}, toFund2, {toFund1}, Fund::All);
-
1195
-
1196 AMM ammAlice(
-
1197 env, alice, asset1, asset2, CreateArg{.log = false, .tfee = 0});
-
1198
-
1199 Account const owner{"owner"};
-
1200 env.fund(XRP(1000000), owner);
-
1201
-
1202 Vault vault{env};
-
1203 auto [tx, k] =
-
1204 vault.create({.owner = owner, .asset = ammAlice.lptIssue()});
-
1205 env(tx, ter{tecWRONG_ASSET});
-
1206 env.close();
-
1207 }
-
1208 }
-
1209
-
1210 void
-
1211 testCreateFailMPT()
-
1212 {
-
1213 using namespace test::jtx;
+
1189 Account const owner{"owner"};
+
1190 env.fund(XRP(1000000), owner);
+
1191
+
1192 Vault vault{env};
+
1193 auto [tx, k] =
+
1194 vault.create({.owner = owner, .asset = ammAlice.lptIssue()});
+
1195 env(tx, ter{tecWRONG_ASSET});
+
1196 env.close();
+
1197 }
+
1198 }
+
1199
+
1200 void
+
1201 testCreateFailMPT()
+
1202 {
+
1203 using namespace test::jtx;
+
1204
+
1205 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
1206 Account issuer{"issuer"};
+
1207 Account owner{"owner"};
+
1208 Account depositor{"depositor"};
+
1209 env.fund(XRP(1000), issuer, owner, depositor);
+
1210 env.close();
+
1211 Vault vault{env};
+
1212
+
1213 MPTTester mptt{env, issuer, mptInitNoFund};
1214
-
1215 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
1216 Account issuer{"issuer"};
-
1217 Account owner{"owner"};
-
1218 Account depositor{"depositor"};
-
1219 env.fund(XRP(1000), issuer, owner, depositor);
-
1220 env.close();
-
1221 Vault vault{env};
-
1222
-
1223 MPTTester mptt{env, issuer, mptInitNoFund};
-
1224
-
1225 // Locked because that is the default flag.
-
1226 mptt.create();
-
1227 Asset asset = mptt.issuanceID();
-
1228 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1229 env(tx, ter(tecNO_AUTH));
-
1230 }
-
1231
-
1232 void
-
1233 testNonTransferableShares()
-
1234 {
-
1235 using namespace test::jtx;
-
1236
-
1237 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
1238 Account issuer{"issuer"};
-
1239 Account owner{"owner"};
-
1240 Account depositor{"depositor"};
-
1241 env.fund(XRP(1000), issuer, owner, depositor);
-
1242 env.close();
-
1243
-
1244 Vault vault{env};
-
1245 PrettyAsset asset = issuer["IOU"];
-
1246 env.trust(asset(1000), owner);
-
1247 env(pay(issuer, owner, asset(100)));
-
1248 env.trust(asset(1000), depositor);
-
1249 env(pay(issuer, depositor, asset(100)));
-
1250 env.close();
-
1251
-
1252 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1253 tx[sfFlags] = tfVaultShareNonTransferable;
-
1254 env(tx);
-
1255 env.close();
-
1256
-
1257 {
-
1258 testcase("nontransferable deposits");
-
1259 auto tx1 = vault.deposit(
-
1260 {.depositor = depositor,
-
1261 .id = keylet.key,
-
1262 .amount = asset(40)});
-
1263 env(tx1);
+
1215 // Locked because that is the default flag.
+
1216 mptt.create();
+
1217 Asset asset = mptt.issuanceID();
+
1218 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1219 env(tx, ter(tecNO_AUTH));
+
1220 }
+
1221
+
1222 void
+
1223 testNonTransferableShares()
+
1224 {
+
1225 using namespace test::jtx;
+
1226
+
1227 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
1228 Account issuer{"issuer"};
+
1229 Account owner{"owner"};
+
1230 Account depositor{"depositor"};
+
1231 env.fund(XRP(1000), issuer, owner, depositor);
+
1232 env.close();
+
1233
+
1234 Vault vault{env};
+
1235 PrettyAsset asset = issuer["IOU"];
+
1236 env.trust(asset(1000), owner);
+
1237 env(pay(issuer, owner, asset(100)));
+
1238 env.trust(asset(1000), depositor);
+
1239 env(pay(issuer, depositor, asset(100)));
+
1240 env.close();
+
1241
+
1242 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1243 tx[sfFlags] = tfVaultShareNonTransferable;
+
1244 env(tx);
+
1245 env.close();
+
1246
+
1247 {
+
1248 testcase("nontransferable deposits");
+
1249 auto tx1 = vault.deposit(
+
1250 {.depositor = depositor,
+
1251 .id = keylet.key,
+
1252 .amount = asset(40)});
+
1253 env(tx1);
+
1254
+
1255 auto tx2 = vault.deposit(
+
1256 {.depositor = owner, .id = keylet.key, .amount = asset(60)});
+
1257 env(tx2);
+
1258 env.close();
+
1259 }
+
1260
+
1261 auto const vaultAccount = //
+
1262 [&env, key = keylet.key, this]() -> AccountID {
+
1263 auto jvVault = env.rpc("vault_info", strHex(key));
1264
-
1265 auto tx2 = vault.deposit(
-
1266 {.depositor = owner, .id = keylet.key, .amount = asset(60)});
-
1267 env(tx2);
-
1268 env.close();
-
1269 }
+
1265 BEAST_EXPECT(
+
1266 jvVault[jss::result][jss::vault][sfAssetsTotal] == "100");
+
1267 BEAST_EXPECT(
+
1268 jvVault[jss::result][jss::vault][jss::shares]
+
1269 [sfOutstandingAmount] == "100");
1270
-
1271 auto const vaultAccount = //
-
1272 [&env, key = keylet.key, this]() -> AccountID {
-
1273 auto jvVault = env.rpc("vault_info", strHex(key));
-
1274
-
1275 BEAST_EXPECT(
-
1276 jvVault[jss::result][jss::vault][sfAssetsTotal] == "100");
-
1277 BEAST_EXPECT(
-
1278 jvVault[jss::result][jss::vault][jss::shares]
-
1279 [sfOutstandingAmount] == "100");
+
1271 // Vault pseudo-account
+
1272 return parseBase58<AccountID>(
+
1273 jvVault[jss::result][jss::vault][jss::Account]
+
1274 .asString())
+
1275 .value();
+
1276 }();
+
1277
+
1278 auto const MptID = makeMptID(1, vaultAccount);
+
1279 Asset shares = MptID;
1280
-
1281 // Vault pseudo-account
-
1282 return parseBase58<AccountID>(
-
1283 jvVault[jss::result][jss::vault][jss::Account]
-
1284 .asString())
-
1285 .value();
-
1286 }();
-
1287
-
1288 auto const MptID = makeMptID(1, vaultAccount);
-
1289 Asset shares = MptID;
-
1290
-
1291 {
-
1292 testcase("nontransferable shares cannot be moved");
-
1293 env(pay(owner, depositor, shares(10)), ter{tecNO_AUTH});
-
1294 env(pay(depositor, owner, shares(10)), ter{tecNO_AUTH});
-
1295 }
-
1296
-
1297 {
-
1298 testcase("nontransferable shares can be used to withdraw");
-
1299 auto tx1 = vault.withdraw(
-
1300 {.depositor = depositor,
-
1301 .id = keylet.key,
-
1302 .amount = asset(20)});
-
1303 env(tx1);
-
1304
-
1305 auto tx2 = vault.withdraw(
-
1306 {.depositor = owner, .id = keylet.key, .amount = asset(30)});
-
1307 env(tx2);
-
1308 env.close();
+
1281 {
+
1282 testcase("nontransferable shares cannot be moved");
+
1283 env(pay(owner, depositor, shares(10)), ter{tecNO_AUTH});
+
1284 env(pay(depositor, owner, shares(10)), ter{tecNO_AUTH});
+
1285 }
+
1286
+
1287 {
+
1288 testcase("nontransferable shares can be used to withdraw");
+
1289 auto tx1 = vault.withdraw(
+
1290 {.depositor = depositor,
+
1291 .id = keylet.key,
+
1292 .amount = asset(20)});
+
1293 env(tx1);
+
1294
+
1295 auto tx2 = vault.withdraw(
+
1296 {.depositor = owner, .id = keylet.key, .amount = asset(30)});
+
1297 env(tx2);
+
1298 env.close();
+
1299 }
+
1300
+
1301 {
+
1302 testcase("nontransferable shares balance check");
+
1303 auto jvVault = env.rpc("vault_info", strHex(keylet.key));
+
1304 BEAST_EXPECT(
+
1305 jvVault[jss::result][jss::vault][sfAssetsTotal] == "50");
+
1306 BEAST_EXPECT(
+
1307 jvVault[jss::result][jss::vault][jss::shares]
+
1308 [sfOutstandingAmount] == "50");
1309 }
1310
1311 {
-
1312 testcase("nontransferable shares balance check");
-
1313 auto jvVault = env.rpc("vault_info", strHex(keylet.key));
-
1314 BEAST_EXPECT(
-
1315 jvVault[jss::result][jss::vault][sfAssetsTotal] == "50");
-
1316 BEAST_EXPECT(
-
1317 jvVault[jss::result][jss::vault][jss::shares]
-
1318 [sfOutstandingAmount] == "50");
-
1319 }
-
1320
-
1321 {
-
1322 testcase("nontransferable shares withdraw rest");
-
1323 auto tx1 = vault.withdraw(
-
1324 {.depositor = depositor,
-
1325 .id = keylet.key,
-
1326 .amount = asset(20)});
-
1327 env(tx1);
-
1328
-
1329 auto tx2 = vault.withdraw(
-
1330 {.depositor = owner, .id = keylet.key, .amount = asset(30)});
-
1331 env(tx2);
-
1332 env.close();
-
1333 }
-
1334
-
1335 {
-
1336 testcase("nontransferable shares delete empty vault");
-
1337 auto tx = vault.del({.owner = owner, .id = keylet.key});
-
1338 env(tx);
-
1339 BEAST_EXPECT(!env.le(keylet));
-
1340 }
-
1341 }
+
1312 testcase("nontransferable shares withdraw rest");
+
1313 auto tx1 = vault.withdraw(
+
1314 {.depositor = depositor,
+
1315 .id = keylet.key,
+
1316 .amount = asset(20)});
+
1317 env(tx1);
+
1318
+
1319 auto tx2 = vault.withdraw(
+
1320 {.depositor = owner, .id = keylet.key, .amount = asset(30)});
+
1321 env(tx2);
+
1322 env.close();
+
1323 }
+
1324
+
1325 {
+
1326 testcase("nontransferable shares delete empty vault");
+
1327 auto tx = vault.del({.owner = owner, .id = keylet.key});
+
1328 env(tx);
+
1329 BEAST_EXPECT(!env.le(keylet));
+
1330 }
+
1331 }
+
1332
+
1333 void
+
1334 testWithMPT()
+
1335 {
+
1336 using namespace test::jtx;
+
1337
+
1338 struct CaseArgs
+
1339 {
+
1340 bool enableClawback = true;
+
1341 };
1342
-
1343 void
-
1344 testWithMPT()
-
1345 {
-
1346 using namespace test::jtx;
-
1347
-
1348 struct CaseArgs
-
1349 {
-
1350 bool enableClawback = true;
-
1351 };
-
1352
-
1353 auto testCase = [this](
-
1354 std::function<void(
-
1355 Env & env,
-
1356 Account const& issuer,
-
1357 Account const& owner,
-
1358 Account const& depositor,
-
1359 Asset const& asset,
-
1360 Vault& vault,
-
1361 MPTTester& mptt)> test,
-
1362 CaseArgs args = {}) {
-
1363 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
1364 Account issuer{"issuer"};
-
1365 Account owner{"owner"};
-
1366 Account depositor{"depositor"};
-
1367 env.fund(XRP(1000), issuer, owner, depositor);
-
1368 env.close();
-
1369 Vault vault{env};
-
1370
-
1371 MPTTester mptt{env, issuer, mptInitNoFund};
-
1372 mptt.create(
-
1373 {.flags = tfMPTCanTransfer | tfMPTCanLock |
-
1374 (args.enableClawback ? lsfMPTCanClawback
-
1375 : LedgerSpecificFlags(0)) |
-
1376 tfMPTRequireAuth});
-
1377 PrettyAsset asset = mptt.issuanceID();
-
1378 mptt.authorize({.account = owner});
-
1379 mptt.authorize({.account = issuer, .holder = owner});
-
1380 mptt.authorize({.account = depositor});
-
1381 mptt.authorize({.account = issuer, .holder = depositor});
-
1382 env(pay(issuer, depositor, asset(1000)));
-
1383 env.close();
-
1384
-
1385 test(env, issuer, owner, depositor, asset, vault, mptt);
-
1386 };
-
1387
-
1388 testCase([this](
-
1389 Env& env,
-
1390 Account const& issuer,
-
1391 Account const& owner,
-
1392 Account const& depositor,
-
1393 PrettyAsset const& asset,
-
1394 Vault& vault,
-
1395 MPTTester& mptt) {
-
1396 testcase("MPT nothing to clawback from");
-
1397 auto tx = vault.clawback(
-
1398 {.issuer = issuer,
-
1399 .id = keylet::skip().key,
-
1400 .holder = depositor,
-
1401 .amount = asset(10)});
-
1402 env(tx, ter(tecNO_ENTRY));
-
1403 });
-
1404
-
1405 testCase([this](
-
1406 Env& env,
-
1407 Account const& issuer,
-
1408 Account const& owner,
-
1409 Account const& depositor,
-
1410 Asset const& asset,
-
1411 Vault& vault,
-
1412 MPTTester& mptt) {
-
1413 testcase("MPT global lock blocks create");
-
1414 mptt.set({.account = issuer, .flags = tfMPTLock});
-
1415 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1416 env(tx, ter(tecLOCKED));
-
1417 });
-
1418
-
1419 testCase([this](
-
1420 Env& env,
-
1421 Account const& issuer,
-
1422 Account const& owner,
-
1423 Account const& depositor,
-
1424 Asset const& asset,
-
1425 Vault& vault,
-
1426 MPTTester& mptt) {
-
1427 testcase("MPT global lock blocks deposit");
-
1428 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1429 env(tx);
+
1343 auto testCase = [this](
+
1344 std::function<void(
+
1345 Env & env,
+
1346 Account const& issuer,
+
1347 Account const& owner,
+
1348 Account const& depositor,
+
1349 Asset const& asset,
+
1350 Vault& vault,
+
1351 MPTTester& mptt)> test,
+
1352 CaseArgs args = {}) {
+
1353 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
1354 Account issuer{"issuer"};
+
1355 Account owner{"owner"};
+
1356 Account depositor{"depositor"};
+
1357 env.fund(XRP(1000), issuer, owner, depositor);
+
1358 env.close();
+
1359 Vault vault{env};
+
1360
+
1361 MPTTester mptt{env, issuer, mptInitNoFund};
+
1362 mptt.create(
+
1363 {.flags = tfMPTCanTransfer | tfMPTCanLock |
+
1364 (args.enableClawback ? lsfMPTCanClawback
+
1365 : LedgerSpecificFlags(0)) |
+
1366 tfMPTRequireAuth});
+
1367 PrettyAsset asset = mptt.issuanceID();
+
1368 mptt.authorize({.account = owner});
+
1369 mptt.authorize({.account = issuer, .holder = owner});
+
1370 mptt.authorize({.account = depositor});
+
1371 mptt.authorize({.account = issuer, .holder = depositor});
+
1372 env(pay(issuer, depositor, asset(1000)));
+
1373 env.close();
+
1374
+
1375 test(env, issuer, owner, depositor, asset, vault, mptt);
+
1376 };
+
1377
+
1378 testCase([this](
+
1379 Env& env,
+
1380 Account const& issuer,
+
1381 Account const& owner,
+
1382 Account const& depositor,
+
1383 PrettyAsset const& asset,
+
1384 Vault& vault,
+
1385 MPTTester& mptt) {
+
1386 testcase("MPT nothing to clawback from");
+
1387 auto tx = vault.clawback(
+
1388 {.issuer = issuer,
+
1389 .id = keylet::skip().key,
+
1390 .holder = depositor,
+
1391 .amount = asset(10)});
+
1392 env(tx, ter(tecNO_ENTRY));
+
1393 });
+
1394
+
1395 testCase([this](
+
1396 Env& env,
+
1397 Account const& issuer,
+
1398 Account const& owner,
+
1399 Account const& depositor,
+
1400 Asset const& asset,
+
1401 Vault& vault,
+
1402 MPTTester& mptt) {
+
1403 testcase("MPT global lock blocks create");
+
1404 mptt.set({.account = issuer, .flags = tfMPTLock});
+
1405 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1406 env(tx, ter(tecLOCKED));
+
1407 });
+
1408
+
1409 testCase([this](
+
1410 Env& env,
+
1411 Account const& issuer,
+
1412 Account const& owner,
+
1413 Account const& depositor,
+
1414 Asset const& asset,
+
1415 Vault& vault,
+
1416 MPTTester& mptt) {
+
1417 testcase("MPT global lock blocks deposit");
+
1418 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1419 env(tx);
+
1420 env.close();
+
1421
+
1422 mptt.set({.account = issuer, .flags = tfMPTLock});
+
1423 env.close();
+
1424
+
1425 tx = vault.deposit(
+
1426 {.depositor = depositor,
+
1427 .id = keylet.key,
+
1428 .amount = asset(100)});
+
1429 env(tx, ter{tecLOCKED});
1430 env.close();
1431
-
1432 mptt.set({.account = issuer, .flags = tfMPTLock});
-
1433 env.close();
-
1434
-
1435 tx = vault.deposit(
-
1436 {.depositor = depositor,
-
1437 .id = keylet.key,
-
1438 .amount = asset(100)});
-
1439 env(tx, ter{tecLOCKED});
-
1440 env.close();
-
1441
-
1442 // Can delete empty vault, even if global lock
-
1443 tx = vault.del({.owner = owner, .id = keylet.key});
-
1444 env(tx);
-
1445 });
-
1446
-
1447 testCase([this](
-
1448 Env& env,
-
1449 Account const& issuer,
-
1450 Account const& owner,
-
1451 Account const& depositor,
-
1452 Asset const& asset,
-
1453 Vault& vault,
-
1454 MPTTester& mptt) {
-
1455 testcase("MPT global lock blocks withdrawal");
-
1456 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1457 env(tx);
-
1458 env.close();
-
1459 tx = vault.deposit(
-
1460 {.depositor = depositor,
-
1461 .id = keylet.key,
-
1462 .amount = asset(100)});
-
1463 env(tx);
-
1464 env.close();
+
1432 // Can delete empty vault, even if global lock
+
1433 tx = vault.del({.owner = owner, .id = keylet.key});
+
1434 env(tx);
+
1435 });
+
1436
+
1437 testCase([this](
+
1438 Env& env,
+
1439 Account const& issuer,
+
1440 Account const& owner,
+
1441 Account const& depositor,
+
1442 Asset const& asset,
+
1443 Vault& vault,
+
1444 MPTTester& mptt) {
+
1445 testcase("MPT global lock blocks withdrawal");
+
1446 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1447 env(tx);
+
1448 env.close();
+
1449 tx = vault.deposit(
+
1450 {.depositor = depositor,
+
1451 .id = keylet.key,
+
1452 .amount = asset(100)});
+
1453 env(tx);
+
1454 env.close();
+
1455
+
1456 // Check that the OutstandingAmount field of MPTIssuance
+
1457 // accounts for the issued shares.
+
1458 auto v = env.le(keylet);
+
1459 BEAST_EXPECT(v);
+
1460 MPTID share = (*v)[sfShareMPTID];
+
1461 auto issuance = env.le(keylet::mptIssuance(share));
+
1462 BEAST_EXPECT(issuance);
+
1463 Number outstandingShares = issuance->at(sfOutstandingAmount);
+
1464 BEAST_EXPECT(outstandingShares == 100);
1465
-
1466 // Check that the OutstandingAmount field of MPTIssuance
-
1467 // accounts for the issued shares.
-
1468 auto v = env.le(keylet);
-
1469 BEAST_EXPECT(v);
-
1470 MPTID share = (*v)[sfShareMPTID];
-
1471 auto issuance = env.le(keylet::mptIssuance(share));
-
1472 BEAST_EXPECT(issuance);
-
1473 Number outstandingShares = issuance->at(sfOutstandingAmount);
-
1474 BEAST_EXPECT(outstandingShares == 100);
-
1475
-
1476 mptt.set({.account = issuer, .flags = tfMPTLock});
-
1477 env.close();
-
1478
-
1479 tx = vault.withdraw(
-
1480 {.depositor = depositor,
+
1466 mptt.set({.account = issuer, .flags = tfMPTLock});
+
1467 env.close();
+
1468
+
1469 tx = vault.withdraw(
+
1470 {.depositor = depositor,
+
1471 .id = keylet.key,
+
1472 .amount = asset(100)});
+
1473 env(tx, ter(tecLOCKED));
+
1474
+
1475 tx[sfDestination] = issuer.human();
+
1476 env(tx, ter(tecLOCKED));
+
1477
+
1478 // Clawback is still permitted, even with global lock
+
1479 tx = vault.clawback(
+
1480 {.issuer = issuer,
1481 .id = keylet.key,
-
1482 .amount = asset(100)});
-
1483 env(tx, ter(tecLOCKED));
-
1484
-
1485 tx[sfDestination] = issuer.human();
-
1486 env(tx, ter(tecLOCKED));
-
1487
-
1488 // Clawback is still permitted, even with global lock
-
1489 tx = vault.clawback(
-
1490 {.issuer = issuer,
-
1491 .id = keylet.key,
-
1492 .holder = depositor,
-
1493 .amount = asset(0)});
-
1494 env(tx);
-
1495 env.close();
-
1496
-
1497 // Can delete empty vault, even if global lock
-
1498 tx = vault.del({.owner = owner, .id = keylet.key});
-
1499 env(tx);
-
1500 });
+
1482 .holder = depositor,
+
1483 .amount = asset(0)});
+
1484 env(tx);
+
1485 env.close();
+
1486
+
1487 // Can delete empty vault, even if global lock
+
1488 tx = vault.del({.owner = owner, .id = keylet.key});
+
1489 env(tx);
+
1490 });
+
1491
+
1492 testCase([this](
+
1493 Env& env,
+
1494 Account const& issuer,
+
1495 Account const& owner,
+
1496 Account const& depositor,
+
1497 PrettyAsset const& asset,
+
1498 Vault& vault,
+
1499 MPTTester& mptt) {
+
1500 testcase("MPT only issuer can clawback");
1501
-
1502 testCase([this](
-
1503 Env& env,
-
1504 Account const& issuer,
-
1505 Account const& owner,
-
1506 Account const& depositor,
-
1507 PrettyAsset const& asset,
-
1508 Vault& vault,
-
1509 MPTTester& mptt) {
-
1510 testcase("MPT only issuer can clawback");
-
1511
-
1512 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1513 env(tx);
-
1514 env.close();
-
1515
-
1516 tx = vault.deposit(
-
1517 {.depositor = depositor,
-
1518 .id = keylet.key,
-
1519 .amount = asset(100)});
-
1520 env(tx);
-
1521 env.close();
-
1522
-
1523 {
-
1524 auto tx = vault.clawback(
-
1525 {.issuer = owner, .id = keylet.key, .holder = depositor});
-
1526 env(tx, ter(tecNO_PERMISSION));
-
1527 }
-
1528 });
+
1502 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1503 env(tx);
+
1504 env.close();
+
1505
+
1506 tx = vault.deposit(
+
1507 {.depositor = depositor,
+
1508 .id = keylet.key,
+
1509 .amount = asset(100)});
+
1510 env(tx);
+
1511 env.close();
+
1512
+
1513 {
+
1514 auto tx = vault.clawback(
+
1515 {.issuer = owner, .id = keylet.key, .holder = depositor});
+
1516 env(tx, ter(tecNO_PERMISSION));
+
1517 }
+
1518 });
+
1519
+
1520 testCase([this](
+
1521 Env& env,
+
1522 Account const& issuer,
+
1523 Account const& owner,
+
1524 Account const& depositor,
+
1525 PrettyAsset const& asset,
+
1526 Vault& vault,
+
1527 MPTTester& mptt) {
+
1528 testcase("MPT issuance deleted");
1529
-
1530 testCase([this](
-
1531 Env& env,
-
1532 Account const& issuer,
-
1533 Account const& owner,
-
1534 Account const& depositor,
-
1535 PrettyAsset const& asset,
-
1536 Vault& vault,
-
1537 MPTTester& mptt) {
-
1538 testcase("MPT issuance deleted");
-
1539
-
1540 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1541 env(tx);
-
1542 env.close();
-
1543
-
1544 tx = vault.deposit(
-
1545 {.depositor = depositor,
-
1546 .id = keylet.key,
-
1547 .amount = asset(1000)});
-
1548 env(tx);
-
1549 env.close();
-
1550
-
1551 {
-
1552 auto tx = vault.clawback(
-
1553 {.issuer = issuer,
-
1554 .id = keylet.key,
-
1555 .holder = depositor,
-
1556 .amount = asset(0)});
-
1557 env(tx);
-
1558 }
-
1559
-
1560 mptt.destroy({.issuer = issuer, .id = mptt.issuanceID()});
-
1561 env.close();
-
1562
-
1563 {
-
1564 auto [tx, keylet] =
-
1565 vault.create({.owner = depositor, .asset = asset});
-
1566 env(tx, ter{tecOBJECT_NOT_FOUND});
-
1567 }
-
1568
-
1569 {
-
1570 auto tx = vault.deposit(
-
1571 {.depositor = depositor,
-
1572 .id = keylet.key,
-
1573 .amount = asset(10)});
-
1574 env(tx, ter{tecOBJECT_NOT_FOUND});
-
1575 }
-
1576
-
1577 {
-
1578 auto tx = vault.withdraw(
-
1579 {.depositor = depositor,
-
1580 .id = keylet.key,
-
1581 .amount = asset(10)});
-
1582 env(tx, ter{tecOBJECT_NOT_FOUND});
-
1583 }
-
1584
-
1585 {
-
1586 auto tx = vault.clawback(
-
1587 {.issuer = issuer,
-
1588 .id = keylet.key,
-
1589 .holder = depositor,
-
1590 .amount = asset(0)});
-
1591 env(tx, ter{tecOBJECT_NOT_FOUND});
-
1592 }
-
1593
-
1594 env(vault.del({.owner = owner, .id = keylet.key}));
-
1595 });
-
1596
-
1597 testCase(
-
1598 [this](
-
1599 Env& env,
-
1600 Account const& issuer,
-
1601 Account const& owner,
-
1602 Account const& depositor,
-
1603 PrettyAsset const& asset,
-
1604 Vault& vault,
-
1605 MPTTester& mptt) {
-
1606 testcase("MPT clawback disabled");
-
1607
-
1608 auto [tx, keylet] =
-
1609 vault.create({.owner = owner, .asset = asset});
-
1610 env(tx);
-
1611 env.close();
-
1612
-
1613 tx = vault.deposit(
-
1614 {.depositor = depositor,
-
1615 .id = keylet.key,
-
1616 .amount = asset(1000)});
-
1617 env(tx);
-
1618 env.close();
-
1619
-
1620 {
-
1621 auto tx = vault.clawback(
-
1622 {.issuer = issuer,
-
1623 .id = keylet.key,
-
1624 .holder = depositor,
-
1625 .amount = asset(0)});
-
1626 env(tx, ter{tecNO_PERMISSION});
-
1627 }
-
1628 },
-
1629 {.enableClawback = false});
-
1630
-
1631 testCase([this](
-
1632 Env& env,
-
1633 Account const& issuer,
-
1634 Account const& owner,
-
1635 Account const& depositor,
-
1636 Asset const& asset,
-
1637 Vault& vault,
-
1638 MPTTester& mptt) {
-
1639 testcase("MPT un-authorization");
-
1640 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1641 env(tx);
-
1642 env.close();
-
1643 tx = vault.deposit(
-
1644 {.depositor = depositor,
-
1645 .id = keylet.key,
-
1646 .amount = asset(1000)});
-
1647 env(tx);
-
1648 env.close();
-
1649
-
1650 mptt.authorize(
-
1651 {.account = issuer,
-
1652 .holder = depositor,
-
1653 .flags = tfMPTUnauthorize});
-
1654 env.close();
-
1655
-
1656 {
-
1657 auto tx = vault.withdraw(
-
1658 {.depositor = depositor,
-
1659 .id = keylet.key,
-
1660 .amount = asset(100)});
-
1661 env(tx, ter(tecNO_AUTH));
-
1662
-
1663 // Withdrawal to other (authorized) accounts works
-
1664 tx[sfDestination] = issuer.human();
-
1665 env(tx);
-
1666 tx[sfDestination] = owner.human();
-
1667 env(tx);
-
1668 env.close();
-
1669 }
-
1670
-
1671 {
-
1672 // Cannot deposit some more
-
1673 auto tx = vault.deposit(
-
1674 {.depositor = depositor,
-
1675 .id = keylet.key,
-
1676 .amount = asset(100)});
-
1677 env(tx, ter(tecNO_AUTH));
-
1678 }
-
1679
-
1680 // Clawback works
-
1681 tx = vault.clawback(
-
1682 {.issuer = issuer,
-
1683 .id = keylet.key,
-
1684 .holder = depositor,
-
1685 .amount = asset(800)});
-
1686 env(tx);
-
1687
-
1688 env(vault.del({.owner = owner, .id = keylet.key}));
-
1689 });
-
1690
-
1691 testCase([this](
-
1692 Env& env,
-
1693 Account const& issuer,
-
1694 Account const& owner,
-
1695 Account const& depositor,
-
1696 Asset const& asset,
-
1697 Vault& vault,
-
1698 MPTTester& mptt) {
-
1699 testcase("MPT lock of vault pseudo-account");
-
1700 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1701 env(tx);
-
1702 env.close();
-
1703
-
1704 auto const vaultAccount =
-
1705 [&env, keylet = keylet, this]() -> AccountID {
-
1706 auto const vault = env.le(keylet);
-
1707 BEAST_EXPECT(vault != nullptr);
-
1708 return vault->at(sfAccount);
-
1709 }();
-
1710
-
1711 tx = vault.deposit(
-
1712 {.depositor = depositor,
-
1713 .id = keylet.key,
-
1714 .amount = asset(100)});
-
1715 env(tx);
-
1716 env.close();
-
1717
-
1718 tx = [&]() {
-
1719 Json::Value jv;
-
1720 jv[jss::Account] = issuer.human();
-
1721 jv[sfMPTokenIssuanceID] =
-
1722 to_string(asset.get<MPTIssue>().getMptID());
-
1723 jv[jss::Holder] = toBase58(vaultAccount);
-
1724 jv[jss::TransactionType] = jss::MPTokenIssuanceSet;
-
1725 jv[jss::Flags] = tfMPTLock;
-
1726 return jv;
-
1727 }();
-
1728 env(tx);
-
1729 env.close();
-
1730
-
1731 tx = vault.deposit(
-
1732 {.depositor = depositor,
-
1733 .id = keylet.key,
-
1734 .amount = asset(100)});
-
1735 env(tx, ter(tecLOCKED));
-
1736
-
1737 tx = vault.withdraw(
-
1738 {.depositor = depositor,
-
1739 .id = keylet.key,
-
1740 .amount = asset(100)});
-
1741 env(tx, ter(tecLOCKED));
-
1742
-
1743 // Clawback works, even when locked
-
1744 tx = vault.clawback(
-
1745 {.issuer = issuer,
-
1746 .id = keylet.key,
-
1747 .holder = depositor,
-
1748 .amount = asset(100)});
-
1749 env(tx);
-
1750
-
1751 // Can delete an empty vault even when asset is locked.
-
1752 tx = vault.del({.owner = owner, .id = keylet.key});
-
1753 env(tx);
-
1754 });
+
1530 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1531 env(tx);
+
1532 env.close();
+
1533
+
1534 tx = vault.deposit(
+
1535 {.depositor = depositor,
+
1536 .id = keylet.key,
+
1537 .amount = asset(1000)});
+
1538 env(tx);
+
1539 env.close();
+
1540
+
1541 {
+
1542 auto tx = vault.clawback(
+
1543 {.issuer = issuer,
+
1544 .id = keylet.key,
+
1545 .holder = depositor,
+
1546 .amount = asset(0)});
+
1547 env(tx);
+
1548 }
+
1549
+
1550 mptt.destroy({.issuer = issuer, .id = mptt.issuanceID()});
+
1551 env.close();
+
1552
+
1553 {
+
1554 auto [tx, keylet] =
+
1555 vault.create({.owner = depositor, .asset = asset});
+
1556 env(tx, ter{tecOBJECT_NOT_FOUND});
+
1557 }
+
1558
+
1559 {
+
1560 auto tx = vault.deposit(
+
1561 {.depositor = depositor,
+
1562 .id = keylet.key,
+
1563 .amount = asset(10)});
+
1564 env(tx, ter{tecOBJECT_NOT_FOUND});
+
1565 }
+
1566
+
1567 {
+
1568 auto tx = vault.withdraw(
+
1569 {.depositor = depositor,
+
1570 .id = keylet.key,
+
1571 .amount = asset(10)});
+
1572 env(tx, ter{tecOBJECT_NOT_FOUND});
+
1573 }
+
1574
+
1575 {
+
1576 auto tx = vault.clawback(
+
1577 {.issuer = issuer,
+
1578 .id = keylet.key,
+
1579 .holder = depositor,
+
1580 .amount = asset(0)});
+
1581 env(tx, ter{tecOBJECT_NOT_FOUND});
+
1582 }
+
1583
+
1584 env(vault.del({.owner = owner, .id = keylet.key}));
+
1585 });
+
1586
+
1587 testCase(
+
1588 [this](
+
1589 Env& env,
+
1590 Account const& issuer,
+
1591 Account const& owner,
+
1592 Account const& depositor,
+
1593 PrettyAsset const& asset,
+
1594 Vault& vault,
+
1595 MPTTester& mptt) {
+
1596 testcase("MPT clawback disabled");
+
1597
+
1598 auto [tx, keylet] =
+
1599 vault.create({.owner = owner, .asset = asset});
+
1600 env(tx);
+
1601 env.close();
+
1602
+
1603 tx = vault.deposit(
+
1604 {.depositor = depositor,
+
1605 .id = keylet.key,
+
1606 .amount = asset(1000)});
+
1607 env(tx);
+
1608 env.close();
+
1609
+
1610 {
+
1611 auto tx = vault.clawback(
+
1612 {.issuer = issuer,
+
1613 .id = keylet.key,
+
1614 .holder = depositor,
+
1615 .amount = asset(0)});
+
1616 env(tx, ter{tecNO_PERMISSION});
+
1617 }
+
1618 },
+
1619 {.enableClawback = false});
+
1620
+
1621 testCase([this](
+
1622 Env& env,
+
1623 Account const& issuer,
+
1624 Account const& owner,
+
1625 Account const& depositor,
+
1626 Asset const& asset,
+
1627 Vault& vault,
+
1628 MPTTester& mptt) {
+
1629 testcase("MPT un-authorization");
+
1630 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1631 env(tx);
+
1632 env.close();
+
1633 tx = vault.deposit(
+
1634 {.depositor = depositor,
+
1635 .id = keylet.key,
+
1636 .amount = asset(1000)});
+
1637 env(tx);
+
1638 env.close();
+
1639
+
1640 mptt.authorize(
+
1641 {.account = issuer,
+
1642 .holder = depositor,
+
1643 .flags = tfMPTUnauthorize});
+
1644 env.close();
+
1645
+
1646 {
+
1647 auto tx = vault.withdraw(
+
1648 {.depositor = depositor,
+
1649 .id = keylet.key,
+
1650 .amount = asset(100)});
+
1651 env(tx, ter(tecNO_AUTH));
+
1652
+
1653 // Withdrawal to other (authorized) accounts works
+
1654 tx[sfDestination] = issuer.human();
+
1655 env(tx);
+
1656 tx[sfDestination] = owner.human();
+
1657 env(tx);
+
1658 env.close();
+
1659 }
+
1660
+
1661 {
+
1662 // Cannot deposit some more
+
1663 auto tx = vault.deposit(
+
1664 {.depositor = depositor,
+
1665 .id = keylet.key,
+
1666 .amount = asset(100)});
+
1667 env(tx, ter(tecNO_AUTH));
+
1668 }
+
1669
+
1670 // Clawback works
+
1671 tx = vault.clawback(
+
1672 {.issuer = issuer,
+
1673 .id = keylet.key,
+
1674 .holder = depositor,
+
1675 .amount = asset(800)});
+
1676 env(tx);
+
1677
+
1678 env(vault.del({.owner = owner, .id = keylet.key}));
+
1679 });
+
1680
+
1681 testCase([this](
+
1682 Env& env,
+
1683 Account const& issuer,
+
1684 Account const& owner,
+
1685 Account const& depositor,
+
1686 Asset const& asset,
+
1687 Vault& vault,
+
1688 MPTTester& mptt) {
+
1689 testcase("MPT lock of vault pseudo-account");
+
1690 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1691 env(tx);
+
1692 env.close();
+
1693
+
1694 auto const vaultAccount =
+
1695 [&env, keylet = keylet, this]() -> AccountID {
+
1696 auto const vault = env.le(keylet);
+
1697 BEAST_EXPECT(vault != nullptr);
+
1698 return vault->at(sfAccount);
+
1699 }();
+
1700
+
1701 tx = vault.deposit(
+
1702 {.depositor = depositor,
+
1703 .id = keylet.key,
+
1704 .amount = asset(100)});
+
1705 env(tx);
+
1706 env.close();
+
1707
+
1708 tx = [&]() {
+
1709 Json::Value jv;
+
1710 jv[jss::Account] = issuer.human();
+
1711 jv[sfMPTokenIssuanceID] =
+
1712 to_string(asset.get<MPTIssue>().getMptID());
+
1713 jv[jss::Holder] = toBase58(vaultAccount);
+
1714 jv[jss::TransactionType] = jss::MPTokenIssuanceSet;
+
1715 jv[jss::Flags] = tfMPTLock;
+
1716 return jv;
+
1717 }();
+
1718 env(tx);
+
1719 env.close();
+
1720
+
1721 tx = vault.deposit(
+
1722 {.depositor = depositor,
+
1723 .id = keylet.key,
+
1724 .amount = asset(100)});
+
1725 env(tx, ter(tecLOCKED));
+
1726
+
1727 tx = vault.withdraw(
+
1728 {.depositor = depositor,
+
1729 .id = keylet.key,
+
1730 .amount = asset(100)});
+
1731 env(tx, ter(tecLOCKED));
+
1732
+
1733 // Clawback works, even when locked
+
1734 tx = vault.clawback(
+
1735 {.issuer = issuer,
+
1736 .id = keylet.key,
+
1737 .holder = depositor,
+
1738 .amount = asset(100)});
+
1739 env(tx);
+
1740
+
1741 // Can delete an empty vault even when asset is locked.
+
1742 tx = vault.del({.owner = owner, .id = keylet.key});
+
1743 env(tx);
+
1744 });
+
1745
+
1746 {
+
1747 testcase("MPT shares to a vault");
+
1748
+
1749 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
1750 Account owner{"owner"};
+
1751 Account issuer{"issuer"};
+
1752 env.fund(XRP(1000000), owner, issuer);
+
1753 env.close();
+
1754 Vault vault{env};
1755
-
1756 {
-
1757 testcase("MPT shares to a vault");
-
1758
-
1759 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
1760 Account owner{"owner"};
-
1761 Account issuer{"issuer"};
-
1762 env.fund(XRP(1000000), owner, issuer);
-
1763 env.close();
-
1764 Vault vault{env};
-
1765
-
1766 MPTTester mptt{env, issuer, mptInitNoFund};
-
1767 mptt.create(
-
1768 {.flags = tfMPTCanTransfer | tfMPTCanLock | lsfMPTCanClawback |
-
1769 tfMPTRequireAuth});
-
1770 mptt.authorize({.account = owner});
-
1771 mptt.authorize({.account = issuer, .holder = owner});
-
1772 PrettyAsset asset = mptt.issuanceID();
-
1773 env(pay(issuer, owner, asset(100)));
-
1774 auto [tx1, k1] = vault.create({.owner = owner, .asset = asset});
-
1775 env(tx1);
+
1756 MPTTester mptt{env, issuer, mptInitNoFund};
+
1757 mptt.create(
+
1758 {.flags = tfMPTCanTransfer | tfMPTCanLock | lsfMPTCanClawback |
+
1759 tfMPTRequireAuth});
+
1760 mptt.authorize({.account = owner});
+
1761 mptt.authorize({.account = issuer, .holder = owner});
+
1762 PrettyAsset asset = mptt.issuanceID();
+
1763 env(pay(issuer, owner, asset(100)));
+
1764 auto [tx1, k1] = vault.create({.owner = owner, .asset = asset});
+
1765 env(tx1);
+
1766 env.close();
+
1767
+
1768 auto const shares = [&env, keylet = k1, this]() -> Asset {
+
1769 auto const vault = env.le(keylet);
+
1770 BEAST_EXPECT(vault != nullptr);
+
1771 return MPTIssue(vault->at(sfShareMPTID));
+
1772 }();
+
1773
+
1774 auto [tx2, k2] = vault.create({.owner = owner, .asset = shares});
+
1775 env(tx2, ter{tecWRONG_ASSET});
1776 env.close();
-
1777
-
1778 auto const shares = [&env, keylet = k1, this]() -> Asset {
-
1779 auto const vault = env.le(keylet);
-
1780 BEAST_EXPECT(vault != nullptr);
-
1781 return MPTIssue(vault->at(sfShareMPTID));
-
1782 }();
-
1783
-
1784 auto [tx2, k2] = vault.create({.owner = owner, .asset = shares});
-
1785 env(tx2, ter{tecWRONG_ASSET});
-
1786 env.close();
-
1787 }
-
1788 }
-
1789
-
1790 void
-
1791 testWithIOU()
-
1792 {
-
1793 using namespace test::jtx;
-
1794
-
1795 auto testCase =
-
1796 [&, this](
-
1797 std::function<void(
-
1798 Env & env,
-
1799 Account const& owner,
-
1800 Account const& issuer,
-
1801 Account const& charlie,
-
1802 std::function<AccountID(ripple::Keylet)> vaultAccount,
-
1803 Vault& vault,
-
1804 PrettyAsset const& asset,
-
1805 std::function<MPTID(ripple::Keylet)> issuanceId,
-
1806 std::function<PrettyAmount(ripple::Keylet)> vaultBalance)>
-
1807 test) {
-
1808 Env env{
-
1809 *this, supported_amendments() | featureSingleAssetVault};
-
1810 Account const owner{"owner"};
-
1811 Account const issuer{"issuer"};
-
1812 Account const charlie{"charlie"};
-
1813 Vault vault{env};
-
1814 env.fund(XRP(1000), issuer, owner, charlie);
-
1815 env(fset(issuer, asfAllowTrustLineClawback));
-
1816 env.close();
-
1817
-
1818 PrettyAsset const asset = issuer["IOU"];
-
1819 env.trust(asset(1000), owner);
-
1820 env(pay(issuer, owner, asset(200)));
-
1821 env(rate(issuer, 1.25));
-
1822 env.close();
-
1823
-
1824 auto const [tx, keylet] =
-
1825 vault.create({.owner = owner, .asset = asset});
-
1826 env(tx);
-
1827 env.close();
-
1828
-
1829 auto const vaultAccount =
-
1830 [&env](ripple::Keylet keylet) -> AccountID {
-
1831 return env.le(keylet)->at(sfAccount);
-
1832 };
-
1833 auto const issuanceId = [&env](ripple::Keylet keylet) -> MPTID {
-
1834 return env.le(keylet)->at(sfShareMPTID);
-
1835 };
-
1836 auto const vaultBalance = //
-
1837 [&env, &vaultAccount, issue = asset.raw().get<Issue>()](
-
1838 ripple::Keylet keylet) -> PrettyAmount {
-
1839 auto const account = vaultAccount(keylet);
-
1840 auto const sle = env.le(keylet::line(account, issue));
-
1841 if (sle == nullptr)
-
1842 return {
-
1843 STAmount(issue, 0),
-
1844 env.lookup(issue.account).name()};
-
1845 auto amount = sle->getFieldAmount(sfBalance);
-
1846 amount.setIssuer(issue.account);
-
1847 if (account > issue.account)
-
1848 amount.negate();
-
1849 return {amount, env.lookup(issue.account).name()};
-
1850 };
-
1851
-
1852 test(
-
1853 env,
-
1854 owner,
-
1855 issuer,
-
1856 charlie,
-
1857 vaultAccount,
-
1858 vault,
-
1859 asset,
-
1860 issuanceId,
-
1861 vaultBalance);
-
1862 };
-
1863
-
1864 testCase([&, this](
-
1865 Env& env,
-
1866 Account const& owner,
-
1867 Account const& issuer,
-
1868 Account const&,
-
1869 auto vaultAccount,
-
1870 Vault& vault,
-
1871 PrettyAsset const& asset,
-
1872 auto&&...) {
-
1873 testcase("IOU cannot use different asset");
-
1874 PrettyAsset const foo = issuer["FOO"];
-
1875
-
1876 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1877 env(tx);
-
1878 env.close();
-
1879
-
1880 {
-
1881 // Cannot create new trustline to a vault
-
1882 auto tx = [&, account = vaultAccount(keylet)]() {
-
1883 Json::Value jv;
-
1884 jv[jss::Account] = issuer.human();
-
1885 {
-
1886 auto& ja = jv[jss::LimitAmount] =
-
1887 foo(0).value().getJson(JsonOptions::none);
-
1888 ja[jss::issuer] = toBase58(account);
-
1889 }
-
1890 jv[jss::TransactionType] = jss::TrustSet;
-
1891 jv[jss::Flags] = tfSetFreeze;
-
1892 return jv;
-
1893 }();
-
1894 env(tx, ter{tecNO_PERMISSION});
-
1895 env.close();
-
1896 }
-
1897
-
1898 {
-
1899 auto tx = vault.deposit(
-
1900 {.depositor = issuer, .id = keylet.key, .amount = foo(20)});
-
1901 env(tx, ter{tecWRONG_ASSET});
-
1902 env.close();
-
1903 }
-
1904
-
1905 {
-
1906 auto tx = vault.withdraw(
-
1907 {.depositor = issuer, .id = keylet.key, .amount = foo(20)});
-
1908 env(tx, ter{tecWRONG_ASSET});
-
1909 env.close();
-
1910 }
-
1911
-
1912 env(vault.del({.owner = owner, .id = keylet.key}));
-
1913 env.close();
-
1914 });
-
1915
-
1916 testCase([&, this](
-
1917 Env& env,
-
1918 Account const& owner,
-
1919 Account const& issuer,
-
1920 Account const& charlie,
-
1921 auto vaultAccount,
-
1922 Vault& vault,
-
1923 PrettyAsset const& asset,
-
1924 auto issuanceId,
-
1925 auto) {
-
1926 testcase("IOU frozen trust line to vault account");
+
1777 }
+
1778 }
+
1779
+
1780 void
+
1781 testWithIOU()
+
1782 {
+
1783 using namespace test::jtx;
+
1784
+
1785 auto testCase =
+
1786 [&, this](
+
1787 std::function<void(
+
1788 Env & env,
+
1789 Account const& owner,
+
1790 Account const& issuer,
+
1791 Account const& charlie,
+
1792 std::function<AccountID(ripple::Keylet)> vaultAccount,
+
1793 Vault& vault,
+
1794 PrettyAsset const& asset,
+
1795 std::function<MPTID(ripple::Keylet)> issuanceId,
+
1796 std::function<PrettyAmount(ripple::Keylet)> vaultBalance)>
+
1797 test) {
+
1798 Env env{
+
1799 *this, supported_amendments() | featureSingleAssetVault};
+
1800 Account const owner{"owner"};
+
1801 Account const issuer{"issuer"};
+
1802 Account const charlie{"charlie"};
+
1803 Vault vault{env};
+
1804 env.fund(XRP(1000), issuer, owner, charlie);
+
1805 env(fset(issuer, asfAllowTrustLineClawback));
+
1806 env.close();
+
1807
+
1808 PrettyAsset const asset = issuer["IOU"];
+
1809 env.trust(asset(1000), owner);
+
1810 env(pay(issuer, owner, asset(200)));
+
1811 env(rate(issuer, 1.25));
+
1812 env.close();
+
1813
+
1814 auto const [tx, keylet] =
+
1815 vault.create({.owner = owner, .asset = asset});
+
1816 env(tx);
+
1817 env.close();
+
1818
+
1819 auto const vaultAccount =
+
1820 [&env](ripple::Keylet keylet) -> AccountID {
+
1821 return env.le(keylet)->at(sfAccount);
+
1822 };
+
1823 auto const issuanceId = [&env](ripple::Keylet keylet) -> MPTID {
+
1824 return env.le(keylet)->at(sfShareMPTID);
+
1825 };
+
1826 auto const vaultBalance = //
+
1827 [&env, &vaultAccount, issue = asset.raw().get<Issue>()](
+
1828 ripple::Keylet keylet) -> PrettyAmount {
+
1829 auto const account = vaultAccount(keylet);
+
1830 auto const sle = env.le(keylet::line(account, issue));
+
1831 if (sle == nullptr)
+
1832 return {
+
1833 STAmount(issue, 0),
+
1834 env.lookup(issue.account).name()};
+
1835 auto amount = sle->getFieldAmount(sfBalance);
+
1836 amount.setIssuer(issue.account);
+
1837 if (account > issue.account)
+
1838 amount.negate();
+
1839 return {amount, env.lookup(issue.account).name()};
+
1840 };
+
1841
+
1842 test(
+
1843 env,
+
1844 owner,
+
1845 issuer,
+
1846 charlie,
+
1847 vaultAccount,
+
1848 vault,
+
1849 asset,
+
1850 issuanceId,
+
1851 vaultBalance);
+
1852 };
+
1853
+
1854 testCase([&, this](
+
1855 Env& env,
+
1856 Account const& owner,
+
1857 Account const& issuer,
+
1858 Account const&,
+
1859 auto vaultAccount,
+
1860 Vault& vault,
+
1861 PrettyAsset const& asset,
+
1862 auto&&...) {
+
1863 testcase("IOU cannot use different asset");
+
1864 PrettyAsset const foo = issuer["FOO"];
+
1865
+
1866 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1867 env(tx);
+
1868 env.close();
+
1869
+
1870 {
+
1871 // Cannot create new trustline to a vault
+
1872 auto tx = [&, account = vaultAccount(keylet)]() {
+
1873 Json::Value jv;
+
1874 jv[jss::Account] = issuer.human();
+
1875 {
+
1876 auto& ja = jv[jss::LimitAmount] =
+
1877 foo(0).value().getJson(JsonOptions::none);
+
1878 ja[jss::issuer] = toBase58(account);
+
1879 }
+
1880 jv[jss::TransactionType] = jss::TrustSet;
+
1881 jv[jss::Flags] = tfSetFreeze;
+
1882 return jv;
+
1883 }();
+
1884 env(tx, ter{tecNO_PERMISSION});
+
1885 env.close();
+
1886 }
+
1887
+
1888 {
+
1889 auto tx = vault.deposit(
+
1890 {.depositor = issuer, .id = keylet.key, .amount = foo(20)});
+
1891 env(tx, ter{tecWRONG_ASSET});
+
1892 env.close();
+
1893 }
+
1894
+
1895 {
+
1896 auto tx = vault.withdraw(
+
1897 {.depositor = issuer, .id = keylet.key, .amount = foo(20)});
+
1898 env(tx, ter{tecWRONG_ASSET});
+
1899 env.close();
+
1900 }
+
1901
+
1902 env(vault.del({.owner = owner, .id = keylet.key}));
+
1903 env.close();
+
1904 });
+
1905
+
1906 testCase([&, this](
+
1907 Env& env,
+
1908 Account const& owner,
+
1909 Account const& issuer,
+
1910 Account const& charlie,
+
1911 auto vaultAccount,
+
1912 Vault& vault,
+
1913 PrettyAsset const& asset,
+
1914 auto issuanceId,
+
1915 auto) {
+
1916 testcase("IOU frozen trust line to vault account");
+
1917
+
1918 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
1919 env(tx);
+
1920 env.close();
+
1921
+
1922 env(vault.deposit(
+
1923 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
+
1924 env.close();
+
1925
+
1926 Asset const share = Asset(issuanceId(keylet));
1927
-
1928 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
1929 env(tx);
-
1930 env.close();
-
1931
-
1932 env(vault.deposit(
-
1933 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
-
1934 env.close();
-
1935
-
1936 Asset const share = Asset(issuanceId(keylet));
-
1937
-
1938 // Freeze the trustline to the vault
-
1939 auto trustSet = [&, account = vaultAccount(keylet)]() {
-
1940 Json::Value jv;
-
1941 jv[jss::Account] = issuer.human();
-
1942 {
-
1943 auto& ja = jv[jss::LimitAmount] =
-
1944 asset(0).value().getJson(JsonOptions::none);
-
1945 ja[jss::issuer] = toBase58(account);
-
1946 }
-
1947 jv[jss::TransactionType] = jss::TrustSet;
-
1948 jv[jss::Flags] = tfSetFreeze;
-
1949 return jv;
-
1950 }();
-
1951 env(trustSet);
-
1952 env.close();
-
1953
-
1954 {
-
1955 // Note, the "frozen" state of the trust line to vault account
-
1956 // is reported as "locked" state of the vault shares, because
-
1957 // this state is attached to shares by means of the transitive
-
1958 // isFrozen.
-
1959 auto tx = vault.deposit(
-
1960 {.depositor = owner,
-
1961 .id = keylet.key,
-
1962 .amount = asset(80)});
-
1963 env(tx, ter{tecLOCKED});
-
1964 }
-
1965
-
1966 {
-
1967 auto tx = vault.withdraw(
-
1968 {.depositor = owner,
-
1969 .id = keylet.key,
-
1970 .amount = asset(100)});
-
1971 env(tx, ter{tecLOCKED});
-
1972
-
1973 // also when trying to withdraw to a 3rd party
-
1974 tx[sfDestination] = charlie.human();
-
1975 env(tx, ter{tecLOCKED});
-
1976 env.close();
-
1977 }
-
1978
-
1979 {
-
1980 // Clawback works, even when locked
-
1981 auto tx = vault.clawback(
-
1982 {.issuer = issuer,
-
1983 .id = keylet.key,
-
1984 .holder = owner,
-
1985 .amount = asset(50)});
-
1986 env(tx);
-
1987 env.close();
-
1988 }
-
1989
-
1990 // Clear the frozen state
-
1991 trustSet[jss::Flags] = tfClearFreeze;
-
1992 env(trustSet);
-
1993 env.close();
-
1994
-
1995 env(vault.withdraw(
-
1996 {.depositor = owner, .id = keylet.key, .amount = share(50)}));
-
1997
-
1998 env(vault.del({.owner = owner, .id = keylet.key}));
-
1999 env.close();
-
2000 });
-
2001
-
2002 testCase([&, this](
-
2003 Env& env,
-
2004 Account const& owner,
-
2005 Account const& issuer,
-
2006 Account const& charlie,
-
2007 auto,
-
2008 Vault& vault,
-
2009 PrettyAsset const& asset,
-
2010 auto issuanceId,
-
2011 auto vaultBalance) {
-
2012 testcase("IOU transfer fees not applied");
-
2013
-
2014 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
2015 env(tx);
-
2016 env.close();
-
2017
-
2018 env(vault.deposit(
-
2019 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
-
2020 env.close();
-
2021
-
2022 auto const issue = asset.raw().get<Issue>();
-
2023 Asset const share = Asset(issuanceId(keylet));
-
2024
-
2025 // transfer fees ignored on deposit
-
2026 BEAST_EXPECT(env.balance(owner, issue) == asset(100));
-
2027 BEAST_EXPECT(vaultBalance(keylet) == asset(100));
+
1928 // Freeze the trustline to the vault
+
1929 auto trustSet = [&, account = vaultAccount(keylet)]() {
+
1930 Json::Value jv;
+
1931 jv[jss::Account] = issuer.human();
+
1932 {
+
1933 auto& ja = jv[jss::LimitAmount] =
+
1934 asset(0).value().getJson(JsonOptions::none);
+
1935 ja[jss::issuer] = toBase58(account);
+
1936 }
+
1937 jv[jss::TransactionType] = jss::TrustSet;
+
1938 jv[jss::Flags] = tfSetFreeze;
+
1939 return jv;
+
1940 }();
+
1941 env(trustSet);
+
1942 env.close();
+
1943
+
1944 {
+
1945 // Note, the "frozen" state of the trust line to vault account
+
1946 // is reported as "locked" state of the vault shares, because
+
1947 // this state is attached to shares by means of the transitive
+
1948 // isFrozen.
+
1949 auto tx = vault.deposit(
+
1950 {.depositor = owner,
+
1951 .id = keylet.key,
+
1952 .amount = asset(80)});
+
1953 env(tx, ter{tecLOCKED});
+
1954 }
+
1955
+
1956 {
+
1957 auto tx = vault.withdraw(
+
1958 {.depositor = owner,
+
1959 .id = keylet.key,
+
1960 .amount = asset(100)});
+
1961 env(tx, ter{tecLOCKED});
+
1962
+
1963 // also when trying to withdraw to a 3rd party
+
1964 tx[sfDestination] = charlie.human();
+
1965 env(tx, ter{tecLOCKED});
+
1966 env.close();
+
1967 }
+
1968
+
1969 {
+
1970 // Clawback works, even when locked
+
1971 auto tx = vault.clawback(
+
1972 {.issuer = issuer,
+
1973 .id = keylet.key,
+
1974 .holder = owner,
+
1975 .amount = asset(50)});
+
1976 env(tx);
+
1977 env.close();
+
1978 }
+
1979
+
1980 // Clear the frozen state
+
1981 trustSet[jss::Flags] = tfClearFreeze;
+
1982 env(trustSet);
+
1983 env.close();
+
1984
+
1985 env(vault.withdraw(
+
1986 {.depositor = owner, .id = keylet.key, .amount = share(50)}));
+
1987
+
1988 env(vault.del({.owner = owner, .id = keylet.key}));
+
1989 env.close();
+
1990 });
+
1991
+
1992 testCase([&, this](
+
1993 Env& env,
+
1994 Account const& owner,
+
1995 Account const& issuer,
+
1996 Account const& charlie,
+
1997 auto,
+
1998 Vault& vault,
+
1999 PrettyAsset const& asset,
+
2000 auto issuanceId,
+
2001 auto vaultBalance) {
+
2002 testcase("IOU transfer fees not applied");
+
2003
+
2004 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
2005 env(tx);
+
2006 env.close();
+
2007
+
2008 env(vault.deposit(
+
2009 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
+
2010 env.close();
+
2011
+
2012 auto const issue = asset.raw().get<Issue>();
+
2013 Asset const share = Asset(issuanceId(keylet));
+
2014
+
2015 // transfer fees ignored on deposit
+
2016 BEAST_EXPECT(env.balance(owner, issue) == asset(100));
+
2017 BEAST_EXPECT(vaultBalance(keylet) == asset(100));
+
2018
+
2019 {
+
2020 auto tx = vault.clawback(
+
2021 {.issuer = issuer,
+
2022 .id = keylet.key,
+
2023 .holder = owner,
+
2024 .amount = asset(50)});
+
2025 env(tx);
+
2026 env.close();
+
2027 }
2028
-
2029 {
-
2030 auto tx = vault.clawback(
-
2031 {.issuer = issuer,
-
2032 .id = keylet.key,
-
2033 .holder = owner,
-
2034 .amount = asset(50)});
-
2035 env(tx);
-
2036 env.close();
-
2037 }
-
2038
-
2039 // transfer fees ignored on clawback
-
2040 BEAST_EXPECT(env.balance(owner, issue) == asset(100));
-
2041 BEAST_EXPECT(vaultBalance(keylet) == asset(50));
-
2042
-
2043 env(vault.withdraw(
-
2044 {.depositor = owner, .id = keylet.key, .amount = share(20)}));
-
2045
-
2046 // transfer fees ignored on withdraw
-
2047 BEAST_EXPECT(env.balance(owner, issue) == asset(120));
-
2048 BEAST_EXPECT(vaultBalance(keylet) == asset(30));
-
2049
-
2050 {
-
2051 auto tx = vault.withdraw(
-
2052 {.depositor = owner,
-
2053 .id = keylet.key,
-
2054 .amount = share(30)});
-
2055 tx[sfDestination] = charlie.human();
-
2056 env(tx);
-
2057 }
-
2058
-
2059 // transfer fees ignored on withdraw to 3rd party
-
2060 BEAST_EXPECT(env.balance(owner, issue) == asset(120));
-
2061 BEAST_EXPECT(env.balance(charlie, issue) == asset(30));
-
2062 BEAST_EXPECT(vaultBalance(keylet) == asset(0));
-
2063
-
2064 env(vault.del({.owner = owner, .id = keylet.key}));
-
2065 env.close();
-
2066 });
-
2067
-
2068 testCase([&, this](
-
2069 Env& env,
-
2070 Account const& owner,
-
2071 Account const& issuer,
-
2072 Account const& charlie,
-
2073 auto,
-
2074 Vault& vault,
-
2075 PrettyAsset const& asset,
-
2076 auto&&...) {
-
2077 testcase("IOU frozen trust line to depositor");
-
2078
-
2079 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
2080 env(tx);
-
2081 env.close();
-
2082
-
2083 env(vault.deposit(
-
2084 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
-
2085 env.close();
-
2086
-
2087 // Withdraw to 3rd party works
-
2088 auto const withdrawToCharlie = [&](ripple::Keylet keylet) {
-
2089 auto tx = vault.withdraw(
-
2090 {.depositor = owner,
-
2091 .id = keylet.key,
-
2092 .amount = asset(10)});
-
2093 tx[sfDestination] = charlie.human();
-
2094 return tx;
-
2095 }(keylet);
-
2096 env(withdrawToCharlie);
-
2097
-
2098 // Freeze the owner
-
2099 env(trust(issuer, asset(0), owner, tfSetFreeze));
-
2100 env.close();
-
2101
-
2102 // Cannot withdraw
-
2103 auto const withdraw = vault.withdraw(
-
2104 {.depositor = owner, .id = keylet.key, .amount = asset(10)});
-
2105 env(withdraw, ter{tecFROZEN});
-
2106
-
2107 // Cannot withdraw to 3rd party
-
2108 env(withdrawToCharlie, ter{tecLOCKED});
-
2109 env.close();
-
2110
-
2111 {
-
2112 // Cannot deposit some more
-
2113 auto tx = vault.deposit(
-
2114 {.depositor = owner,
-
2115 .id = keylet.key,
-
2116 .amount = asset(10)});
-
2117 env(tx, ter{tecFROZEN});
-
2118 }
-
2119
-
2120 {
-
2121 // Clawback still works
-
2122 auto tx = vault.clawback(
-
2123 {.issuer = issuer,
-
2124 .id = keylet.key,
-
2125 .holder = owner,
-
2126 .amount = asset(0)});
-
2127 env(tx);
-
2128 env.close();
-
2129 }
-
2130
-
2131 env(vault.del({.owner = owner, .id = keylet.key}));
-
2132 env.close();
-
2133 });
-
2134
-
2135 testCase([&, this](
-
2136 Env& env,
-
2137 Account const& owner,
-
2138 Account const& issuer,
-
2139 Account const& charlie,
-
2140 auto,
-
2141 Vault& vault,
-
2142 PrettyAsset const& asset,
-
2143 auto&&...) {
-
2144 testcase("IOU frozen trust line to 3rd party");
-
2145
-
2146 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
2147 env(tx);
-
2148 env.close();
-
2149
-
2150 env(vault.deposit(
-
2151 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
-
2152 env.close();
-
2153
-
2154 // Withdraw to 3rd party works
-
2155 auto const withdrawToCharlie = [&](ripple::Keylet keylet) {
-
2156 auto tx = vault.withdraw(
-
2157 {.depositor = owner,
-
2158 .id = keylet.key,
-
2159 .amount = asset(10)});
-
2160 tx[sfDestination] = charlie.human();
-
2161 return tx;
-
2162 }(keylet);
-
2163 env(withdrawToCharlie);
+
2029 // transfer fees ignored on clawback
+
2030 BEAST_EXPECT(env.balance(owner, issue) == asset(100));
+
2031 BEAST_EXPECT(vaultBalance(keylet) == asset(50));
+
2032
+
2033 env(vault.withdraw(
+
2034 {.depositor = owner, .id = keylet.key, .amount = share(20)}));
+
2035
+
2036 // transfer fees ignored on withdraw
+
2037 BEAST_EXPECT(env.balance(owner, issue) == asset(120));
+
2038 BEAST_EXPECT(vaultBalance(keylet) == asset(30));
+
2039
+
2040 {
+
2041 auto tx = vault.withdraw(
+
2042 {.depositor = owner,
+
2043 .id = keylet.key,
+
2044 .amount = share(30)});
+
2045 tx[sfDestination] = charlie.human();
+
2046 env(tx);
+
2047 }
+
2048
+
2049 // transfer fees ignored on withdraw to 3rd party
+
2050 BEAST_EXPECT(env.balance(owner, issue) == asset(120));
+
2051 BEAST_EXPECT(env.balance(charlie, issue) == asset(30));
+
2052 BEAST_EXPECT(vaultBalance(keylet) == asset(0));
+
2053
+
2054 env(vault.del({.owner = owner, .id = keylet.key}));
+
2055 env.close();
+
2056 });
+
2057
+
2058 testCase([&, this](
+
2059 Env& env,
+
2060 Account const& owner,
+
2061 Account const& issuer,
+
2062 Account const& charlie,
+
2063 auto,
+
2064 Vault& vault,
+
2065 PrettyAsset const& asset,
+
2066 auto&&...) {
+
2067 testcase("IOU frozen trust line to depositor");
+
2068
+
2069 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
2070 env(tx);
+
2071 env.close();
+
2072
+
2073 env(vault.deposit(
+
2074 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
+
2075 env.close();
+
2076
+
2077 // Withdraw to 3rd party works
+
2078 auto const withdrawToCharlie = [&](ripple::Keylet keylet) {
+
2079 auto tx = vault.withdraw(
+
2080 {.depositor = owner,
+
2081 .id = keylet.key,
+
2082 .amount = asset(10)});
+
2083 tx[sfDestination] = charlie.human();
+
2084 return tx;
+
2085 }(keylet);
+
2086 env(withdrawToCharlie);
+
2087
+
2088 // Freeze the owner
+
2089 env(trust(issuer, asset(0), owner, tfSetFreeze));
+
2090 env.close();
+
2091
+
2092 // Cannot withdraw
+
2093 auto const withdraw = vault.withdraw(
+
2094 {.depositor = owner, .id = keylet.key, .amount = asset(10)});
+
2095 env(withdraw, ter{tecFROZEN});
+
2096
+
2097 // Cannot withdraw to 3rd party
+
2098 env(withdrawToCharlie, ter{tecLOCKED});
+
2099 env.close();
+
2100
+
2101 {
+
2102 // Cannot deposit some more
+
2103 auto tx = vault.deposit(
+
2104 {.depositor = owner,
+
2105 .id = keylet.key,
+
2106 .amount = asset(10)});
+
2107 env(tx, ter{tecFROZEN});
+
2108 }
+
2109
+
2110 {
+
2111 // Clawback still works
+
2112 auto tx = vault.clawback(
+
2113 {.issuer = issuer,
+
2114 .id = keylet.key,
+
2115 .holder = owner,
+
2116 .amount = asset(0)});
+
2117 env(tx);
+
2118 env.close();
+
2119 }
+
2120
+
2121 env(vault.del({.owner = owner, .id = keylet.key}));
+
2122 env.close();
+
2123 });
+
2124
+
2125 testCase([&, this](
+
2126 Env& env,
+
2127 Account const& owner,
+
2128 Account const& issuer,
+
2129 Account const& charlie,
+
2130 auto,
+
2131 Vault& vault,
+
2132 PrettyAsset const& asset,
+
2133 auto&&...) {
+
2134 testcase("IOU frozen trust line to 3rd party");
+
2135
+
2136 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
2137 env(tx);
+
2138 env.close();
+
2139
+
2140 env(vault.deposit(
+
2141 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
+
2142 env.close();
+
2143
+
2144 // Withdraw to 3rd party works
+
2145 auto const withdrawToCharlie = [&](ripple::Keylet keylet) {
+
2146 auto tx = vault.withdraw(
+
2147 {.depositor = owner,
+
2148 .id = keylet.key,
+
2149 .amount = asset(10)});
+
2150 tx[sfDestination] = charlie.human();
+
2151 return tx;
+
2152 }(keylet);
+
2153 env(withdrawToCharlie);
+
2154
+
2155 // Freeze the 3rd party
+
2156 env(trust(issuer, asset(0), charlie, tfSetFreeze));
+
2157 env.close();
+
2158
+
2159 // Can withdraw
+
2160 auto const withdraw = vault.withdraw(
+
2161 {.depositor = owner, .id = keylet.key, .amount = asset(10)});
+
2162 env(withdraw);
+
2163 env.close();
2164
-
2165 // Freeze the 3rd party
-
2166 env(trust(issuer, asset(0), charlie, tfSetFreeze));
+
2165 // Cannot withdraw to 3rd party
+
2166 env(withdrawToCharlie, ter{tecFROZEN});
2167 env.close();
2168
-
2169 // Can withdraw
-
2170 auto const withdraw = vault.withdraw(
-
2171 {.depositor = owner, .id = keylet.key, .amount = asset(10)});
-
2172 env(withdraw);
-
2173 env.close();
-
2174
-
2175 // Cannot withdraw to 3rd party
-
2176 env(withdrawToCharlie, ter{tecFROZEN});
+
2169 env(vault.clawback(
+
2170 {.issuer = issuer,
+
2171 .id = keylet.key,
+
2172 .holder = owner,
+
2173 .amount = asset(0)}));
+
2174 env.close();
+
2175
+
2176 env(vault.del({.owner = owner, .id = keylet.key}));
2177 env.close();
-
2178
-
2179 env(vault.clawback(
-
2180 {.issuer = issuer,
-
2181 .id = keylet.key,
-
2182 .holder = owner,
-
2183 .amount = asset(0)}));
-
2184 env.close();
-
2185
-
2186 env(vault.del({.owner = owner, .id = keylet.key}));
-
2187 env.close();
-
2188 });
-
2189
-
2190 testCase([&, this](
-
2191 Env& env,
-
2192 Account const& owner,
-
2193 Account const& issuer,
-
2194 Account const& charlie,
-
2195 auto,
-
2196 Vault& vault,
-
2197 PrettyAsset const& asset,
-
2198 auto&&...) {
-
2199 testcase("IOU global freeze");
-
2200
-
2201 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
2202 env(tx);
-
2203 env.close();
-
2204
-
2205 env(vault.deposit(
-
2206 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
-
2207 env.close();
-
2208
-
2209 env(fset(issuer, asfGlobalFreeze));
-
2210 env.close();
-
2211
-
2212 {
-
2213 // Cannot withdraw
-
2214 auto tx = vault.withdraw(
-
2215 {.depositor = owner,
-
2216 .id = keylet.key,
-
2217 .amount = asset(10)});
-
2218 env(tx, ter{tecFROZEN});
-
2219
-
2220 // Cannot withdraw to 3rd party
-
2221 tx[sfDestination] = charlie.human();
-
2222 env(tx, ter{tecFROZEN});
-
2223 env.close();
-
2224
-
2225 // Cannot deposit some more
-
2226 tx = vault.deposit(
-
2227 {.depositor = owner,
-
2228 .id = keylet.key,
-
2229 .amount = asset(10)});
-
2230
-
2231 env(tx, ter{tecFROZEN});
-
2232 }
-
2233
-
2234 // Clawback is permitted
-
2235 env(vault.clawback(
-
2236 {.issuer = issuer,
-
2237 .id = keylet.key,
-
2238 .holder = owner,
-
2239 .amount = asset(0)}));
-
2240 env.close();
+
2178 });
+
2179
+
2180 testCase([&, this](
+
2181 Env& env,
+
2182 Account const& owner,
+
2183 Account const& issuer,
+
2184 Account const& charlie,
+
2185 auto,
+
2186 Vault& vault,
+
2187 PrettyAsset const& asset,
+
2188 auto&&...) {
+
2189 testcase("IOU global freeze");
+
2190
+
2191 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
2192 env(tx);
+
2193 env.close();
+
2194
+
2195 env(vault.deposit(
+
2196 {.depositor = owner, .id = keylet.key, .amount = asset(100)}));
+
2197 env.close();
+
2198
+
2199 env(fset(issuer, asfGlobalFreeze));
+
2200 env.close();
+
2201
+
2202 {
+
2203 // Cannot withdraw
+
2204 auto tx = vault.withdraw(
+
2205 {.depositor = owner,
+
2206 .id = keylet.key,
+
2207 .amount = asset(10)});
+
2208 env(tx, ter{tecFROZEN});
+
2209
+
2210 // Cannot withdraw to 3rd party
+
2211 tx[sfDestination] = charlie.human();
+
2212 env(tx, ter{tecFROZEN});
+
2213 env.close();
+
2214
+
2215 // Cannot deposit some more
+
2216 tx = vault.deposit(
+
2217 {.depositor = owner,
+
2218 .id = keylet.key,
+
2219 .amount = asset(10)});
+
2220
+
2221 env(tx, ter{tecFROZEN});
+
2222 }
+
2223
+
2224 // Clawback is permitted
+
2225 env(vault.clawback(
+
2226 {.issuer = issuer,
+
2227 .id = keylet.key,
+
2228 .holder = owner,
+
2229 .amount = asset(0)}));
+
2230 env.close();
+
2231
+
2232 env(vault.del({.owner = owner, .id = keylet.key}));
+
2233 env.close();
+
2234 });
+
2235 }
+
2236
+
2237 void
+
2238 testWithDomainCheck()
+
2239 {
+
2240 using namespace test::jtx;
2241
-
2242 env(vault.del({.owner = owner, .id = keylet.key}));
-
2243 env.close();
-
2244 });
-
2245 }
-
2246
-
2247 void
-
2248 testWithDomainCheck()
-
2249 {
-
2250 using namespace test::jtx;
-
2251
-
2252 testcase("private vault");
-
2253
-
2254 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
2255 Account issuer{"issuer"};
-
2256 Account owner{"owner"};
-
2257 Account depositor{"depositor"};
-
2258 Account charlie{"charlie"};
-
2259 Account pdOwner{"pdOwner"};
-
2260 Account credIssuer1{"credIssuer1"};
-
2261 Account credIssuer2{"credIssuer2"};
-
2262 std::string const credType = "credential";
-
2263 Vault vault{env};
-
2264 env.fund(
-
2265 XRP(1000),
-
2266 issuer,
-
2267 owner,
-
2268 depositor,
-
2269 charlie,
-
2270 pdOwner,
-
2271 credIssuer1,
-
2272 credIssuer2);
-
2273 env.close();
-
2274 env(fset(issuer, asfAllowTrustLineClawback));
+
2242 testcase("private vault");
+
2243
+
2244 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
2245 Account issuer{"issuer"};
+
2246 Account owner{"owner"};
+
2247 Account depositor{"depositor"};
+
2248 Account charlie{"charlie"};
+
2249 Account pdOwner{"pdOwner"};
+
2250 Account credIssuer1{"credIssuer1"};
+
2251 Account credIssuer2{"credIssuer2"};
+
2252 std::string const credType = "credential";
+
2253 Vault vault{env};
+
2254 env.fund(
+
2255 XRP(1000),
+
2256 issuer,
+
2257 owner,
+
2258 depositor,
+
2259 charlie,
+
2260 pdOwner,
+
2261 credIssuer1,
+
2262 credIssuer2);
+
2263 env.close();
+
2264 env(fset(issuer, asfAllowTrustLineClawback));
+
2265 env.close();
+
2266 env.require(flags(issuer, asfAllowTrustLineClawback));
+
2267
+
2268 PrettyAsset asset = issuer["IOU"];
+
2269 env.trust(asset(1000), owner);
+
2270 env(pay(issuer, owner, asset(500)));
+
2271 env.trust(asset(1000), depositor);
+
2272 env(pay(issuer, depositor, asset(500)));
+
2273 env.trust(asset(1000), charlie);
+
2274 env(pay(issuer, charlie, asset(5)));
2275 env.close();
-
2276 env.require(flags(issuer, asfAllowTrustLineClawback));
-
2277
-
2278 PrettyAsset asset = issuer["IOU"];
-
2279 env.trust(asset(1000), owner);
-
2280 env(pay(issuer, owner, asset(500)));
-
2281 env.trust(asset(1000), depositor);
-
2282 env(pay(issuer, depositor, asset(500)));
-
2283 env.trust(asset(1000), charlie);
-
2284 env(pay(issuer, charlie, asset(5)));
-
2285 env.close();
-
2286
-
2287 auto [tx, keylet] = vault.create(
-
2288 {.owner = owner, .asset = asset, .flags = tfVaultPrivate});
-
2289 env(tx);
-
2290 env.close();
-
2291 BEAST_EXPECT(env.le(keylet));
-
2292
-
2293 {
-
2294 testcase("private vault owner can deposit");
-
2295 auto tx = vault.deposit(
-
2296 {.depositor = owner, .id = keylet.key, .amount = asset(50)});
-
2297 env(tx);
-
2298 }
-
2299
-
2300 {
-
2301 testcase("private vault depositor not authorized yet");
-
2302 auto tx = vault.deposit(
-
2303 {.depositor = depositor,
-
2304 .id = keylet.key,
-
2305 .amount = asset(50)});
-
2306 env(tx, ter{tecNO_AUTH});
-
2307 }
+
2276
+
2277 auto [tx, keylet] = vault.create(
+
2278 {.owner = owner, .asset = asset, .flags = tfVaultPrivate});
+
2279 env(tx);
+
2280 env.close();
+
2281 BEAST_EXPECT(env.le(keylet));
+
2282
+
2283 {
+
2284 testcase("private vault owner can deposit");
+
2285 auto tx = vault.deposit(
+
2286 {.depositor = owner, .id = keylet.key, .amount = asset(50)});
+
2287 env(tx);
+
2288 }
+
2289
+
2290 {
+
2291 testcase("private vault depositor not authorized yet");
+
2292 auto tx = vault.deposit(
+
2293 {.depositor = depositor,
+
2294 .id = keylet.key,
+
2295 .amount = asset(50)});
+
2296 env(tx, ter{tecNO_AUTH});
+
2297 }
+
2298
+
2299 {
+
2300 testcase("private vault cannot set non-existing domain");
+
2301 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
2302 tx[sfDomainID] = to_string(base_uint<256>(42ul));
+
2303 env(tx, ter{tecOBJECT_NOT_FOUND});
+
2304 }
+
2305
+
2306 {
+
2307 testcase("private vault set domainId");
2308
-
2309 {
-
2310 testcase("private vault cannot set non-existing domain");
-
2311 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
2312 tx[sfDomainID] = to_string(base_uint<256>(42ul));
-
2313 env(tx, ter{tecOBJECT_NOT_FOUND});
-
2314 }
-
2315
-
2316 {
-
2317 testcase("private vault set domainId");
+
2309 {
+
2310 pdomain::Credentials const credentials1{
+
2311 {.issuer = credIssuer1, .credType = credType}};
+
2312
+
2313 env(pdomain::setTx(pdOwner, credentials1));
+
2314 auto const domainId1 = [&]() {
+
2315 auto tx = env.tx()->getJson(JsonOptions::none);
+
2316 return pdomain::getNewDomain(env.meta());
+
2317 }();
2318
-
2319 {
-
2320 pdomain::Credentials const credentials1{
-
2321 {.issuer = credIssuer1, .credType = credType}};
-
2322
-
2323 env(pdomain::setTx(pdOwner, credentials1));
-
2324 auto const domainId1 = [&]() {
-
2325 auto tx = env.tx()->getJson(JsonOptions::none);
-
2326 return pdomain::getNewDomain(env.meta());
-
2327 }();
+
2319 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
2320 tx[sfDomainID] = to_string(domainId1);
+
2321 env(tx);
+
2322 env.close();
+
2323
+
2324 // Update domain second time, should be harmless
+
2325 env(tx);
+
2326 env.close();
+
2327 }
2328
-
2329 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
2330 tx[sfDomainID] = to_string(domainId1);
-
2331 env(tx);
-
2332 env.close();
+
2329 {
+
2330 pdomain::Credentials const credentials{
+
2331 {.issuer = credIssuer1, .credType = credType},
+
2332 {.issuer = credIssuer2, .credType = credType}};
2333
-
2334 // Update domain second time, should be harmless
-
2335 env(tx);
-
2336 env.close();
-
2337 }
-
2338
-
2339 {
-
2340 pdomain::Credentials const credentials{
-
2341 {.issuer = credIssuer1, .credType = credType},
-
2342 {.issuer = credIssuer2, .credType = credType}};
-
2343
-
2344 env(pdomain::setTx(pdOwner, credentials));
-
2345 auto const domainId = [&]() {
-
2346 auto tx = env.tx()->getJson(JsonOptions::none);
-
2347 return pdomain::getNewDomain(env.meta());
-
2348 }();
-
2349
-
2350 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
2351 tx[sfDomainID] = to_string(domainId);
-
2352 env(tx);
-
2353 env.close();
-
2354 }
+
2334 env(pdomain::setTx(pdOwner, credentials));
+
2335 auto const domainId = [&]() {
+
2336 auto tx = env.tx()->getJson(JsonOptions::none);
+
2337 return pdomain::getNewDomain(env.meta());
+
2338 }();
+
2339
+
2340 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
2341 tx[sfDomainID] = to_string(domainId);
+
2342 env(tx);
+
2343 env.close();
+
2344 }
+
2345 }
+
2346
+
2347 {
+
2348 testcase("private vault depositor still not authorized");
+
2349 auto tx = vault.deposit(
+
2350 {.depositor = depositor,
+
2351 .id = keylet.key,
+
2352 .amount = asset(50)});
+
2353 env(tx, ter{tecNO_AUTH});
+
2354 env.close();
2355 }
2356
-
2357 {
-
2358 testcase("private vault depositor still not authorized");
-
2359 auto tx = vault.deposit(
-
2360 {.depositor = depositor,
-
2361 .id = keylet.key,
-
2362 .amount = asset(50)});
-
2363 env(tx, ter{tecNO_AUTH});
-
2364 env.close();
-
2365 }
-
2366
-
2367 auto const credKeylet =
-
2368 credentials::keylet(depositor, credIssuer1, credType);
-
2369 {
-
2370 testcase("private vault depositor now authorized");
-
2371 env(credentials::create(depositor, credIssuer1, credType));
-
2372 env(credentials::accept(depositor, credIssuer1, credType));
-
2373 env(credentials::create(charlie, credIssuer1, credType));
-
2374 // charlie's credential not accepted
-
2375 env.close();
-
2376 auto credSle = env.le(credKeylet);
-
2377 BEAST_EXPECT(credSle != nullptr);
-
2378
-
2379 auto tx = vault.deposit(
-
2380 {.depositor = depositor,
-
2381 .id = keylet.key,
-
2382 .amount = asset(50)});
-
2383 env(tx);
-
2384 env.close();
-
2385
-
2386 tx = vault.deposit(
-
2387 {.depositor = charlie, .id = keylet.key, .amount = asset(50)});
-
2388 env(tx, ter{tecNO_AUTH});
-
2389 env.close();
-
2390 }
+
2357 auto const credKeylet =
+
2358 credentials::keylet(depositor, credIssuer1, credType);
+
2359 {
+
2360 testcase("private vault depositor now authorized");
+
2361 env(credentials::create(depositor, credIssuer1, credType));
+
2362 env(credentials::accept(depositor, credIssuer1, credType));
+
2363 env(credentials::create(charlie, credIssuer1, credType));
+
2364 // charlie's credential not accepted
+
2365 env.close();
+
2366 auto credSle = env.le(credKeylet);
+
2367 BEAST_EXPECT(credSle != nullptr);
+
2368
+
2369 auto tx = vault.deposit(
+
2370 {.depositor = depositor,
+
2371 .id = keylet.key,
+
2372 .amount = asset(50)});
+
2373 env(tx);
+
2374 env.close();
+
2375
+
2376 tx = vault.deposit(
+
2377 {.depositor = charlie, .id = keylet.key, .amount = asset(50)});
+
2378 env(tx, ter{tecNO_AUTH});
+
2379 env.close();
+
2380 }
+
2381
+
2382 {
+
2383 testcase("private vault depositor lost authorization");
+
2384 env(credentials::deleteCred(
+
2385 credIssuer1, depositor, credIssuer1, credType));
+
2386 env(credentials::deleteCred(
+
2387 credIssuer1, charlie, credIssuer1, credType));
+
2388 env.close();
+
2389 auto credSle = env.le(credKeylet);
+
2390 BEAST_EXPECT(credSle == nullptr);
2391
-
2392 {
-
2393 testcase("private vault depositor lost authorization");
-
2394 env(credentials::deleteCred(
-
2395 credIssuer1, depositor, credIssuer1, credType));
-
2396 env(credentials::deleteCred(
-
2397 credIssuer1, charlie, credIssuer1, credType));
-
2398 env.close();
-
2399 auto credSle = env.le(credKeylet);
-
2400 BEAST_EXPECT(credSle == nullptr);
-
2401
-
2402 auto tx = vault.deposit(
-
2403 {.depositor = depositor,
-
2404 .id = keylet.key,
-
2405 .amount = asset(50)});
-
2406 env(tx, ter{tecNO_AUTH});
-
2407 env.close();
-
2408 }
-
2409
-
2410 auto const shares = [&env, keylet = keylet, this]() -> Asset {
-
2411 auto const vault = env.le(keylet);
-
2412 BEAST_EXPECT(vault != nullptr);
-
2413 return MPTIssue(vault->at(sfShareMPTID));
-
2414 }();
-
2415
-
2416 {
-
2417 testcase("private vault expired authorization");
-
2418 uint32_t const closeTime = env.current()
-
2419 ->info()
-
2420 .parentCloseTime.time_since_epoch()
-
2421 .count();
-
2422 {
-
2423 auto tx0 =
-
2424 credentials::create(depositor, credIssuer2, credType);
-
2425 tx0[sfExpiration] = closeTime + 20;
-
2426 env(tx0);
-
2427 tx0 = credentials::create(charlie, credIssuer2, credType);
-
2428 tx0[sfExpiration] = closeTime + 20;
-
2429 env(tx0);
-
2430 env.close();
-
2431
-
2432 env(credentials::accept(depositor, credIssuer2, credType));
-
2433 env(credentials::accept(charlie, credIssuer2, credType));
-
2434 env.close();
-
2435 }
-
2436
-
2437 {
-
2438 auto tx1 = vault.deposit(
-
2439 {.depositor = depositor,
-
2440 .id = keylet.key,
-
2441 .amount = asset(50)});
-
2442 env(tx1);
+
2392 auto tx = vault.deposit(
+
2393 {.depositor = depositor,
+
2394 .id = keylet.key,
+
2395 .amount = asset(50)});
+
2396 env(tx, ter{tecNO_AUTH});
+
2397 env.close();
+
2398 }
+
2399
+
2400 auto const shares = [&env, keylet = keylet, this]() -> Asset {
+
2401 auto const vault = env.le(keylet);
+
2402 BEAST_EXPECT(vault != nullptr);
+
2403 return MPTIssue(vault->at(sfShareMPTID));
+
2404 }();
+
2405
+
2406 {
+
2407 testcase("private vault expired authorization");
+
2408 uint32_t const closeTime = env.current()
+
2409 ->info()
+
2410 .parentCloseTime.time_since_epoch()
+
2411 .count();
+
2412 {
+
2413 auto tx0 =
+
2414 credentials::create(depositor, credIssuer2, credType);
+
2415 tx0[sfExpiration] = closeTime + 20;
+
2416 env(tx0);
+
2417 tx0 = credentials::create(charlie, credIssuer2, credType);
+
2418 tx0[sfExpiration] = closeTime + 20;
+
2419 env(tx0);
+
2420 env.close();
+
2421
+
2422 env(credentials::accept(depositor, credIssuer2, credType));
+
2423 env(credentials::accept(charlie, credIssuer2, credType));
+
2424 env.close();
+
2425 }
+
2426
+
2427 {
+
2428 auto tx1 = vault.deposit(
+
2429 {.depositor = depositor,
+
2430 .id = keylet.key,
+
2431 .amount = asset(50)});
+
2432 env(tx1);
+
2433 env.close();
+
2434
+
2435 auto const tokenKeylet = keylet::mptoken(
+
2436 shares.get<MPTIssue>().getMptID(), depositor.id());
+
2437 BEAST_EXPECT(env.le(tokenKeylet) != nullptr);
+
2438 }
+
2439
+
2440 {
+
2441 // time advance
+
2442 env.close();
2443 env.close();
-
2444
-
2445 auto const tokenKeylet = keylet::mptoken(
-
2446 shares.get<MPTIssue>().getMptID(), depositor.id());
-
2447 BEAST_EXPECT(env.le(tokenKeylet) != nullptr);
-
2448 }
+
2444 env.close();
+
2445
+
2446 auto const credsKeylet =
+
2447 credentials::keylet(depositor, credIssuer2, credType);
+
2448 BEAST_EXPECT(env.le(credsKeylet) != nullptr);
2449
-
2450 {
-
2451 // time advance
-
2452 env.close();
-
2453 env.close();
-
2454 env.close();
-
2455
-
2456 auto const credsKeylet =
-
2457 credentials::keylet(depositor, credIssuer2, credType);
-
2458 BEAST_EXPECT(env.le(credsKeylet) != nullptr);
+
2450 auto tx2 = vault.deposit(
+
2451 {.depositor = depositor,
+
2452 .id = keylet.key,
+
2453 .amount = asset(1)});
+
2454 env(tx2, ter{tecEXPIRED});
+
2455 env.close();
+
2456
+
2457 BEAST_EXPECT(env.le(credsKeylet) == nullptr);
+
2458 }
2459
-
2460 auto tx2 = vault.deposit(
-
2461 {.depositor = depositor,
-
2462 .id = keylet.key,
-
2463 .amount = asset(1)});
-
2464 env(tx2, ter{tecEXPIRED});
-
2465 env.close();
-
2466
-
2467 BEAST_EXPECT(env.le(credsKeylet) == nullptr);
-
2468 }
-
2469
-
2470 {
-
2471 auto const credsKeylet =
-
2472 credentials::keylet(charlie, credIssuer2, credType);
-
2473 BEAST_EXPECT(env.le(credsKeylet) != nullptr);
-
2474 auto const tokenKeylet = keylet::mptoken(
-
2475 shares.get<MPTIssue>().getMptID(), charlie.id());
+
2460 {
+
2461 auto const credsKeylet =
+
2462 credentials::keylet(charlie, credIssuer2, credType);
+
2463 BEAST_EXPECT(env.le(credsKeylet) != nullptr);
+
2464 auto const tokenKeylet = keylet::mptoken(
+
2465 shares.get<MPTIssue>().getMptID(), charlie.id());
+
2466 BEAST_EXPECT(env.le(tokenKeylet) == nullptr);
+
2467
+
2468 auto tx3 = vault.deposit(
+
2469 {.depositor = charlie,
+
2470 .id = keylet.key,
+
2471 .amount = asset(2)});
+
2472 env(tx3, ter{tecEXPIRED});
+
2473
+
2474 env.close();
+
2475 BEAST_EXPECT(env.le(credsKeylet) == nullptr);
2476 BEAST_EXPECT(env.le(tokenKeylet) == nullptr);
-
2477
-
2478 auto tx3 = vault.deposit(
-
2479 {.depositor = charlie,
-
2480 .id = keylet.key,
-
2481 .amount = asset(2)});
-
2482 env(tx3, ter{tecEXPIRED});
-
2483
-
2484 env.close();
-
2485 BEAST_EXPECT(env.le(credsKeylet) == nullptr);
-
2486 BEAST_EXPECT(env.le(tokenKeylet) == nullptr);
-
2487 }
-
2488 }
-
2489
-
2490 {
-
2491 testcase("private vault reset domainId");
-
2492 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
2493 tx[sfDomainID] = "0";
-
2494 env(tx);
-
2495 env.close();
-
2496
-
2497 tx = vault.deposit(
-
2498 {.depositor = depositor,
-
2499 .id = keylet.key,
-
2500 .amount = asset(50)});
-
2501 env(tx, ter{tecNO_AUTH});
-
2502 env.close();
-
2503
-
2504 tx = vault.withdraw(
-
2505 {.depositor = depositor,
-
2506 .id = keylet.key,
-
2507 .amount = asset(50)});
-
2508 env(tx);
-
2509
-
2510 tx = vault.clawback(
-
2511 {.issuer = issuer,
-
2512 .id = keylet.key,
-
2513 .holder = depositor,
-
2514 .amount = asset(0)});
-
2515 env(tx);
-
2516
-
2517 tx = vault.clawback(
-
2518 {.issuer = issuer,
-
2519 .id = keylet.key,
-
2520 .holder = owner,
-
2521 .amount = asset(0)});
-
2522 env(tx);
-
2523
-
2524 tx = vault.del({
-
2525 .owner = owner,
-
2526 .id = keylet.key,
-
2527 });
-
2528 env(tx);
-
2529 }
-
2530 }
-
2531
-
2532 void
-
2533 testWithDomainCheckXRP()
-
2534 {
-
2535 using namespace test::jtx;
-
2536
-
2537 testcase("private XRP vault");
-
2538
-
2539 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
2540 Account owner{"owner"};
-
2541 Account depositor{"depositor"};
-
2542 Account alice{"charlie"};
-
2543 std::string const credType = "credential";
-
2544 Vault vault{env};
-
2545 env.fund(XRP(100000), owner, depositor, alice);
-
2546 env.close();
-
2547
-
2548 PrettyAsset asset = xrpIssue();
-
2549 auto [tx, keylet] = vault.create(
-
2550 {.owner = owner, .asset = asset, .flags = tfVaultPrivate});
-
2551 env(tx);
-
2552 env.close();
+
2477 }
+
2478 }
+
2479
+
2480 {
+
2481 testcase("private vault reset domainId");
+
2482 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
2483 tx[sfDomainID] = "0";
+
2484 env(tx);
+
2485 env.close();
+
2486
+
2487 tx = vault.deposit(
+
2488 {.depositor = depositor,
+
2489 .id = keylet.key,
+
2490 .amount = asset(50)});
+
2491 env(tx, ter{tecNO_AUTH});
+
2492 env.close();
+
2493
+
2494 tx = vault.withdraw(
+
2495 {.depositor = depositor,
+
2496 .id = keylet.key,
+
2497 .amount = asset(50)});
+
2498 env(tx);
+
2499
+
2500 tx = vault.clawback(
+
2501 {.issuer = issuer,
+
2502 .id = keylet.key,
+
2503 .holder = depositor,
+
2504 .amount = asset(0)});
+
2505 env(tx);
+
2506
+
2507 tx = vault.clawback(
+
2508 {.issuer = issuer,
+
2509 .id = keylet.key,
+
2510 .holder = owner,
+
2511 .amount = asset(0)});
+
2512 env(tx);
+
2513
+
2514 tx = vault.del({
+
2515 .owner = owner,
+
2516 .id = keylet.key,
+
2517 });
+
2518 env(tx);
+
2519 }
+
2520 }
+
2521
+
2522 void
+
2523 testWithDomainCheckXRP()
+
2524 {
+
2525 using namespace test::jtx;
+
2526
+
2527 testcase("private XRP vault");
+
2528
+
2529 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
2530 Account owner{"owner"};
+
2531 Account depositor{"depositor"};
+
2532 Account alice{"charlie"};
+
2533 std::string const credType = "credential";
+
2534 Vault vault{env};
+
2535 env.fund(XRP(100000), owner, depositor, alice);
+
2536 env.close();
+
2537
+
2538 PrettyAsset asset = xrpIssue();
+
2539 auto [tx, keylet] = vault.create(
+
2540 {.owner = owner, .asset = asset, .flags = tfVaultPrivate});
+
2541 env(tx);
+
2542 env.close();
+
2543
+
2544 auto const [vaultAccount, issuanceId] =
+
2545 [&env, keylet = keylet, this]() -> std::tuple<AccountID, uint192> {
+
2546 auto const vault = env.le(keylet);
+
2547 BEAST_EXPECT(vault != nullptr);
+
2548 return {vault->at(sfAccount), vault->at(sfShareMPTID)};
+
2549 }();
+
2550 BEAST_EXPECT(env.le(keylet::account(vaultAccount)));
+
2551 BEAST_EXPECT(env.le(keylet::mptIssuance(issuanceId)));
+
2552 PrettyAsset shares{issuanceId};
2553
-
2554 auto const [vaultAccount, issuanceId] =
-
2555 [&env, keylet = keylet, this]() -> std::tuple<AccountID, uint192> {
-
2556 auto const vault = env.le(keylet);
-
2557 BEAST_EXPECT(vault != nullptr);
-
2558 return {vault->at(sfAccount), vault->at(sfShareMPTID)};
-
2559 }();
-
2560 BEAST_EXPECT(env.le(keylet::account(vaultAccount)));
-
2561 BEAST_EXPECT(env.le(keylet::mptIssuance(issuanceId)));
-
2562 PrettyAsset shares{issuanceId};
-
2563
-
2564 {
-
2565 testcase("private XRP vault owner can deposit");
-
2566 auto tx = vault.deposit(
-
2567 {.depositor = owner, .id = keylet.key, .amount = asset(50)});
-
2568 env(tx);
-
2569 }
-
2570
-
2571 {
-
2572 testcase("private XRP vault cannot pay shares to depositor yet");
-
2573 env(pay(owner, depositor, shares(1)), ter{tecNO_AUTH});
-
2574 }
-
2575
-
2576 {
-
2577 testcase("private XRP vault depositor not authorized yet");
-
2578 auto tx = vault.deposit(
-
2579 {.depositor = depositor,
-
2580 .id = keylet.key,
-
2581 .amount = asset(50)});
-
2582 env(tx, ter{tecNO_AUTH});
-
2583 }
-
2584
-
2585 {
-
2586 testcase("private XRP vault set DomainID");
-
2587 pdomain::Credentials const credentials{
-
2588 {.issuer = owner, .credType = credType}};
-
2589
-
2590 env(pdomain::setTx(owner, credentials));
-
2591 auto const domainId = [&]() {
-
2592 auto tx = env.tx()->getJson(JsonOptions::none);
-
2593 return pdomain::getNewDomain(env.meta());
-
2594 }();
-
2595
-
2596 auto tx = vault.set({.owner = owner, .id = keylet.key});
-
2597 tx[sfDomainID] = to_string(domainId);
-
2598 env(tx);
-
2599 env.close();
-
2600 }
-
2601
-
2602 auto const credKeylet = credentials::keylet(depositor, owner, credType);
-
2603 {
-
2604 testcase("private XRP vault depositor now authorized");
-
2605 env(credentials::create(depositor, owner, credType));
-
2606 env(credentials::accept(depositor, owner, credType));
-
2607 env.close();
-
2608
-
2609 BEAST_EXPECT(env.le(credKeylet));
-
2610 auto tx = vault.deposit(
-
2611 {.depositor = depositor,
-
2612 .id = keylet.key,
-
2613 .amount = asset(50)});
-
2614 env(tx);
-
2615 env.close();
-
2616 }
-
2617
-
2618 {
-
2619 testcase("private XRP vault can pay shares to depositor");
-
2620 env(pay(owner, depositor, shares(1)));
-
2621 }
-
2622
-
2623 {
-
2624 testcase("private XRP vault cannot pay shares to 3rd party");
-
2625 Json::Value jv;
-
2626 jv[sfAccount] = alice.human();
-
2627 jv[sfTransactionType] = jss::MPTokenAuthorize;
-
2628 jv[sfMPTokenIssuanceID] = to_string(issuanceId);
-
2629 env(jv);
-
2630 env.close();
-
2631
-
2632 env(pay(owner, alice, shares(1)), ter{tecNO_AUTH});
-
2633 }
-
2634 }
-
2635
-
2636 void
-
2637 testFailedPseudoAccount()
-
2638 {
-
2639 using namespace test::jtx;
-
2640
-
2641 testcase("failed pseudo-account allocation");
-
2642 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
2643 Account const owner{"owner"};
-
2644 Vault vault{env};
-
2645 env.fund(XRP(1000), owner);
-
2646
-
2647 auto const keylet = keylet::vault(owner.id(), env.seq(owner));
-
2648 for (int i = 0; i < 256; ++i)
-
2649 {
-
2650 AccountID const accountId =
-
2651 ripple::pseudoAccountAddress(*env.current(), keylet.key);
-
2652
-
2653 env(pay(env.master.id(), accountId, XRP(1000)),
-
2654 seq(autofill),
-
2655 fee(autofill),
-
2656 sig(autofill));
-
2657 }
-
2658
-
2659 auto [tx, keylet1] =
-
2660 vault.create({.owner = owner, .asset = xrpIssue()});
-
2661 BEAST_EXPECT(keylet.key == keylet1.key);
-
2662 env(tx, ter{terADDRESS_COLLISION});
-
2663 }
-
2664
-
2665 void
-
2666 testRPC()
-
2667 {
-
2668 using namespace test::jtx;
-
2669
-
2670 testcase("RPC");
-
2671 Env env{*this, supported_amendments() | featureSingleAssetVault};
-
2672 Account const owner{"owner"};
-
2673 Account const issuer{"issuer"};
-
2674 Vault vault{env};
-
2675 env.fund(XRP(1000), issuer, owner);
+
2554 {
+
2555 testcase("private XRP vault owner can deposit");
+
2556 auto tx = vault.deposit(
+
2557 {.depositor = owner, .id = keylet.key, .amount = asset(50)});
+
2558 env(tx);
+
2559 }
+
2560
+
2561 {
+
2562 testcase("private XRP vault cannot pay shares to depositor yet");
+
2563 env(pay(owner, depositor, shares(1)), ter{tecNO_AUTH});
+
2564 }
+
2565
+
2566 {
+
2567 testcase("private XRP vault depositor not authorized yet");
+
2568 auto tx = vault.deposit(
+
2569 {.depositor = depositor,
+
2570 .id = keylet.key,
+
2571 .amount = asset(50)});
+
2572 env(tx, ter{tecNO_AUTH});
+
2573 }
+
2574
+
2575 {
+
2576 testcase("private XRP vault set DomainID");
+
2577 pdomain::Credentials const credentials{
+
2578 {.issuer = owner, .credType = credType}};
+
2579
+
2580 env(pdomain::setTx(owner, credentials));
+
2581 auto const domainId = [&]() {
+
2582 auto tx = env.tx()->getJson(JsonOptions::none);
+
2583 return pdomain::getNewDomain(env.meta());
+
2584 }();
+
2585
+
2586 auto tx = vault.set({.owner = owner, .id = keylet.key});
+
2587 tx[sfDomainID] = to_string(domainId);
+
2588 env(tx);
+
2589 env.close();
+
2590 }
+
2591
+
2592 auto const credKeylet = credentials::keylet(depositor, owner, credType);
+
2593 {
+
2594 testcase("private XRP vault depositor now authorized");
+
2595 env(credentials::create(depositor, owner, credType));
+
2596 env(credentials::accept(depositor, owner, credType));
+
2597 env.close();
+
2598
+
2599 BEAST_EXPECT(env.le(credKeylet));
+
2600 auto tx = vault.deposit(
+
2601 {.depositor = depositor,
+
2602 .id = keylet.key,
+
2603 .amount = asset(50)});
+
2604 env(tx);
+
2605 env.close();
+
2606 }
+
2607
+
2608 {
+
2609 testcase("private XRP vault can pay shares to depositor");
+
2610 env(pay(owner, depositor, shares(1)));
+
2611 }
+
2612
+
2613 {
+
2614 testcase("private XRP vault cannot pay shares to 3rd party");
+
2615 Json::Value jv;
+
2616 jv[sfAccount] = alice.human();
+
2617 jv[sfTransactionType] = jss::MPTokenAuthorize;
+
2618 jv[sfMPTokenIssuanceID] = to_string(issuanceId);
+
2619 env(jv);
+
2620 env.close();
+
2621
+
2622 env(pay(owner, alice, shares(1)), ter{tecNO_AUTH});
+
2623 }
+
2624 }
+
2625
+
2626 void
+
2627 testFailedPseudoAccount()
+
2628 {
+
2629 using namespace test::jtx;
+
2630
+
2631 testcase("failed pseudo-account allocation");
+
2632 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
2633 Account const owner{"owner"};
+
2634 Vault vault{env};
+
2635 env.fund(XRP(1000), owner);
+
2636
+
2637 auto const keylet = keylet::vault(owner.id(), env.seq(owner));
+
2638 for (int i = 0; i < 256; ++i)
+
2639 {
+
2640 AccountID const accountId =
+
2641 ripple::pseudoAccountAddress(*env.current(), keylet.key);
+
2642
+
2643 env(pay(env.master.id(), accountId, XRP(1000)),
+
2644 seq(autofill),
+
2645 fee(autofill),
+
2646 sig(autofill));
+
2647 }
+
2648
+
2649 auto [tx, keylet1] =
+
2650 vault.create({.owner = owner, .asset = xrpIssue()});
+
2651 BEAST_EXPECT(keylet.key == keylet1.key);
+
2652 env(tx, ter{terADDRESS_COLLISION});
+
2653 }
+
2654
+
2655 void
+
2656 testRPC()
+
2657 {
+
2658 using namespace test::jtx;
+
2659
+
2660 testcase("RPC");
+
2661 Env env{*this, supported_amendments() | featureSingleAssetVault};
+
2662 Account const owner{"owner"};
+
2663 Account const issuer{"issuer"};
+
2664 Vault vault{env};
+
2665 env.fund(XRP(1000), issuer, owner);
+
2666 env.close();
+
2667
+
2668 PrettyAsset asset = issuer["IOU"];
+
2669 env.trust(asset(1000), owner);
+
2670 env(pay(issuer, owner, asset(200)));
+
2671 env.close();
+
2672
+
2673 auto const sequence = env.seq(owner);
+
2674 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
+
2675 env(tx);
2676 env.close();
2677
-
2678 PrettyAsset asset = issuer["IOU"];
-
2679 env.trust(asset(1000), owner);
-
2680 env(pay(issuer, owner, asset(200)));
-
2681 env.close();
-
2682
-
2683 auto const sequence = env.seq(owner);
-
2684 auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
-
2685 env(tx);
-
2686 env.close();
-
2687
-
2688 // Set some fields
-
2689 {
-
2690 auto tx1 = vault.deposit(
-
2691 {.depositor = owner, .id = keylet.key, .amount = asset(50)});
-
2692 env(tx1);
-
2693
-
2694 auto tx2 = vault.set({.owner = owner, .id = keylet.key});
-
2695 tx2[sfAssetsMaximum] = asset(1000).number();
-
2696 env(tx2);
-
2697 env.close();
-
2698 }
-
2699
-
2700 auto const sleVault = [&env, keylet = keylet, this]() {
-
2701 auto const vault = env.le(keylet);
-
2702 BEAST_EXPECT(vault != nullptr);
-
2703 return vault;
-
2704 }();
-
2705
-
2706 auto const check = [&, keylet = keylet, sle = sleVault, this](
-
2707 Json::Value const& vault,
-
2708 Json::Value const& issuance = Json::nullValue) {
-
2709 BEAST_EXPECT(vault.isObject());
-
2710
-
2711 constexpr auto checkString =
-
2712 [](auto& node, SField const& field, std::string v) -> bool {
-
2713 return node.isMember(field.fieldName) &&
-
2714 node[field.fieldName].isString() &&
-
2715 node[field.fieldName] == v;
-
2716 };
-
2717 constexpr auto checkObject =
-
2718 [](auto& node, SField const& field, Json::Value v) -> bool {
-
2719 return node.isMember(field.fieldName) &&
-
2720 node[field.fieldName].isObject() &&
-
2721 node[field.fieldName] == v;
-
2722 };
-
2723 constexpr auto checkInt =
-
2724 [](auto& node, SField const& field, int v) -> bool {
-
2725 return node.isMember(field.fieldName) &&
-
2726 ((node[field.fieldName].isInt() &&
-
2727 node[field.fieldName] == Json::Int(v)) ||
-
2728 (node[field.fieldName].isUInt() &&
-
2729 node[field.fieldName] == Json::UInt(v)));
-
2730 };
-
2731
-
2732 BEAST_EXPECT(vault["LedgerEntryType"].asString() == "Vault");
-
2733 BEAST_EXPECT(vault[jss::index].asString() == strHex(keylet.key));
-
2734 BEAST_EXPECT(checkInt(vault, sfFlags, 0));
-
2735 // Ignore all other standard fields, this test doesn't care
-
2736
-
2737 BEAST_EXPECT(
-
2738 checkString(vault, sfAccount, toBase58(sle->at(sfAccount))));
-
2739 BEAST_EXPECT(
-
2740 checkObject(vault, sfAsset, to_json(sle->at(sfAsset))));
-
2741 BEAST_EXPECT(checkString(vault, sfAssetsAvailable, "50"));
-
2742 BEAST_EXPECT(checkString(vault, sfAssetsMaximum, "1000"));
-
2743 BEAST_EXPECT(checkString(vault, sfAssetsTotal, "50"));
-
2744 BEAST_EXPECT(checkString(vault, sfLossUnrealized, "0"));
-
2745
-
2746 auto const strShareID = strHex(sle->at(sfShareMPTID));
-
2747 BEAST_EXPECT(checkString(vault, sfShareMPTID, strShareID));
-
2748 BEAST_EXPECT(checkString(vault, sfOwner, toBase58(owner.id())));
-
2749 BEAST_EXPECT(checkInt(vault, sfSequence, sequence));
-
2750 BEAST_EXPECT(checkInt(
-
2751 vault, sfWithdrawalPolicy, vaultStrategyFirstComeFirstServe));
-
2752
-
2753 if (issuance.isObject())
-
2754 {
-
2755 BEAST_EXPECT(
-
2756 issuance["LedgerEntryType"].asString() ==
-
2757 "MPTokenIssuance");
-
2758 BEAST_EXPECT(
-
2759 issuance[jss::mpt_issuance_id].asString() == strShareID);
-
2760 BEAST_EXPECT(checkInt(issuance, sfSequence, 1));
-
2761 BEAST_EXPECT(checkInt(
-
2762 issuance,
-
2763 sfFlags,
-
2764 int(lsfMPTCanEscrow | lsfMPTCanTrade | lsfMPTCanTransfer)));
-
2765 BEAST_EXPECT(checkString(issuance, sfOutstandingAmount, "50"));
-
2766 }
-
2767 };
-
2768
-
2769 {
-
2770 testcase("RPC ledger_entry selected by key");
-
2771 Json::Value jvParams;
-
2772 jvParams[jss::ledger_index] = jss::validated;
-
2773 jvParams[jss::vault] = strHex(keylet.key);
-
2774 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2775
-
2776 BEAST_EXPECT(!jvVault[jss::result].isMember(jss::error));
-
2777 BEAST_EXPECT(jvVault[jss::result].isMember(jss::node));
-
2778 check(jvVault[jss::result][jss::node]);
-
2779 }
-
2780
-
2781 {
-
2782 testcase("RPC ledger_entry selected by owner and seq");
-
2783 Json::Value jvParams;
-
2784 jvParams[jss::ledger_index] = jss::validated;
-
2785 jvParams[jss::vault][jss::owner] = owner.human();
-
2786 jvParams[jss::vault][jss::seq] = sequence;
-
2787 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2788
-
2789 BEAST_EXPECT(!jvVault[jss::result].isMember(jss::error));
-
2790 BEAST_EXPECT(jvVault[jss::result].isMember(jss::node));
-
2791 check(jvVault[jss::result][jss::node]);
+
2678 // Set some fields
+
2679 {
+
2680 auto tx1 = vault.deposit(
+
2681 {.depositor = owner, .id = keylet.key, .amount = asset(50)});
+
2682 env(tx1);
+
2683
+
2684 auto tx2 = vault.set({.owner = owner, .id = keylet.key});
+
2685 tx2[sfAssetsMaximum] = asset(1000).number();
+
2686 env(tx2);
+
2687 env.close();
+
2688 }
+
2689
+
2690 auto const sleVault = [&env, keylet = keylet, this]() {
+
2691 auto const vault = env.le(keylet);
+
2692 BEAST_EXPECT(vault != nullptr);
+
2693 return vault;
+
2694 }();
+
2695
+
2696 auto const check = [&, keylet = keylet, sle = sleVault, this](
+
2697 Json::Value const& vault,
+
2698 Json::Value const& issuance = Json::nullValue) {
+
2699 BEAST_EXPECT(vault.isObject());
+
2700
+
2701 constexpr auto checkString =
+
2702 [](auto& node, SField const& field, std::string v) -> bool {
+
2703 return node.isMember(field.fieldName) &&
+
2704 node[field.fieldName].isString() &&
+
2705 node[field.fieldName] == v;
+
2706 };
+
2707 constexpr auto checkObject =
+
2708 [](auto& node, SField const& field, Json::Value v) -> bool {
+
2709 return node.isMember(field.fieldName) &&
+
2710 node[field.fieldName].isObject() &&
+
2711 node[field.fieldName] == v;
+
2712 };
+
2713 constexpr auto checkInt =
+
2714 [](auto& node, SField const& field, int v) -> bool {
+
2715 return node.isMember(field.fieldName) &&
+
2716 ((node[field.fieldName].isInt() &&
+
2717 node[field.fieldName] == Json::Int(v)) ||
+
2718 (node[field.fieldName].isUInt() &&
+
2719 node[field.fieldName] == Json::UInt(v)));
+
2720 };
+
2721
+
2722 BEAST_EXPECT(vault["LedgerEntryType"].asString() == "Vault");
+
2723 BEAST_EXPECT(vault[jss::index].asString() == strHex(keylet.key));
+
2724 BEAST_EXPECT(checkInt(vault, sfFlags, 0));
+
2725 // Ignore all other standard fields, this test doesn't care
+
2726
+
2727 BEAST_EXPECT(
+
2728 checkString(vault, sfAccount, toBase58(sle->at(sfAccount))));
+
2729 BEAST_EXPECT(
+
2730 checkObject(vault, sfAsset, to_json(sle->at(sfAsset))));
+
2731 BEAST_EXPECT(checkString(vault, sfAssetsAvailable, "50"));
+
2732 BEAST_EXPECT(checkString(vault, sfAssetsMaximum, "1000"));
+
2733 BEAST_EXPECT(checkString(vault, sfAssetsTotal, "50"));
+
2734 BEAST_EXPECT(checkString(vault, sfLossUnrealized, "0"));
+
2735
+
2736 auto const strShareID = strHex(sle->at(sfShareMPTID));
+
2737 BEAST_EXPECT(checkString(vault, sfShareMPTID, strShareID));
+
2738 BEAST_EXPECT(checkString(vault, sfOwner, toBase58(owner.id())));
+
2739 BEAST_EXPECT(checkInt(vault, sfSequence, sequence));
+
2740 BEAST_EXPECT(checkInt(
+
2741 vault, sfWithdrawalPolicy, vaultStrategyFirstComeFirstServe));
+
2742
+
2743 if (issuance.isObject())
+
2744 {
+
2745 BEAST_EXPECT(
+
2746 issuance["LedgerEntryType"].asString() ==
+
2747 "MPTokenIssuance");
+
2748 BEAST_EXPECT(
+
2749 issuance[jss::mpt_issuance_id].asString() == strShareID);
+
2750 BEAST_EXPECT(checkInt(issuance, sfSequence, 1));
+
2751 BEAST_EXPECT(checkInt(
+
2752 issuance,
+
2753 sfFlags,
+
2754 int(lsfMPTCanEscrow | lsfMPTCanTrade | lsfMPTCanTransfer)));
+
2755 BEAST_EXPECT(checkString(issuance, sfOutstandingAmount, "50"));
+
2756 }
+
2757 };
+
2758
+
2759 {
+
2760 testcase("RPC ledger_entry selected by key");
+
2761 Json::Value jvParams;
+
2762 jvParams[jss::ledger_index] = jss::validated;
+
2763 jvParams[jss::vault] = strHex(keylet.key);
+
2764 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2765
+
2766 BEAST_EXPECT(!jvVault[jss::result].isMember(jss::error));
+
2767 BEAST_EXPECT(jvVault[jss::result].isMember(jss::node));
+
2768 check(jvVault[jss::result][jss::node]);
+
2769 }
+
2770
+
2771 {
+
2772 testcase("RPC ledger_entry selected by owner and seq");
+
2773 Json::Value jvParams;
+
2774 jvParams[jss::ledger_index] = jss::validated;
+
2775 jvParams[jss::vault][jss::owner] = owner.human();
+
2776 jvParams[jss::vault][jss::seq] = sequence;
+
2777 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2778
+
2779 BEAST_EXPECT(!jvVault[jss::result].isMember(jss::error));
+
2780 BEAST_EXPECT(jvVault[jss::result].isMember(jss::node));
+
2781 check(jvVault[jss::result][jss::node]);
+
2782 }
+
2783
+
2784 {
+
2785 testcase("RPC ledger_entry cannot find vault by key");
+
2786 Json::Value jvParams;
+
2787 jvParams[jss::ledger_index] = jss::validated;
+
2788 jvParams[jss::vault] = to_string(uint256(42));
+
2789 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2790 BEAST_EXPECT(
+
2791 jvVault[jss::result][jss::error].asString() == "entryNotFound");
2792 }
2793
2794 {
-
2795 testcase("RPC ledger_entry cannot find vault by key");
+
2795 testcase("RPC ledger_entry cannot find vault by owner and seq");
2796 Json::Value jvParams;
2797 jvParams[jss::ledger_index] = jss::validated;
-
2798 jvParams[jss::vault] = to_string(uint256(42));
-
2799 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2800 BEAST_EXPECT(
-
2801 jvVault[jss::result][jss::error].asString() == "entryNotFound");
-
2802 }
-
2803
-
2804 {
-
2805 testcase("RPC ledger_entry cannot find vault by owner and seq");
-
2806 Json::Value jvParams;
-
2807 jvParams[jss::ledger_index] = jss::validated;
-
2808 jvParams[jss::vault][jss::owner] = issuer.human();
-
2809 jvParams[jss::vault][jss::seq] = 1'000'000;
+
2798 jvParams[jss::vault][jss::owner] = issuer.human();
+
2799 jvParams[jss::vault][jss::seq] = 1'000'000;
+
2800 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2801 BEAST_EXPECT(
+
2802 jvVault[jss::result][jss::error].asString() == "entryNotFound");
+
2803 }
+
2804
+
2805 {
+
2806 testcase("RPC ledger_entry malformed key");
+
2807 Json::Value jvParams;
+
2808 jvParams[jss::ledger_index] = jss::validated;
+
2809 jvParams[jss::vault] = 42;
2810 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
2811 BEAST_EXPECT(
-
2812 jvVault[jss::result][jss::error].asString() == "entryNotFound");
-
2813 }
-
2814
-
2815 {
-
2816 testcase("RPC ledger_entry malformed key");
-
2817 Json::Value jvParams;
-
2818 jvParams[jss::ledger_index] = jss::validated;
-
2819 jvParams[jss::vault] = 42;
-
2820 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2821 BEAST_EXPECT(
-
2822 jvVault[jss::result][jss::error].asString() ==
-
2823 "malformedRequest");
-
2824 }
-
2825
-
2826 {
-
2827 testcase("RPC ledger_entry malformed owner");
-
2828 Json::Value jvParams;
-
2829 jvParams[jss::ledger_index] = jss::validated;
-
2830 jvParams[jss::vault][jss::owner] = 42;
-
2831 jvParams[jss::vault][jss::seq] = sequence;
-
2832 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2833 BEAST_EXPECT(
-
2834 jvVault[jss::result][jss::error].asString() ==
-
2835 "malformedOwner");
-
2836 }
-
2837
-
2838 {
-
2839 testcase("RPC ledger_entry malformed seq");
-
2840 Json::Value jvParams;
-
2841 jvParams[jss::ledger_index] = jss::validated;
-
2842 jvParams[jss::vault][jss::owner] = issuer.human();
-
2843 jvParams[jss::vault][jss::seq] = "foo";
-
2844 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2845 BEAST_EXPECT(
-
2846 jvVault[jss::result][jss::error].asString() ==
-
2847 "malformedRequest");
-
2848 }
-
2849
-
2850 {
-
2851 testcase("RPC ledger_entry zero seq");
-
2852 Json::Value jvParams;
-
2853 jvParams[jss::ledger_index] = jss::validated;
-
2854 jvParams[jss::vault][jss::owner] = issuer.human();
-
2855 jvParams[jss::vault][jss::seq] = 0;
-
2856 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2857 BEAST_EXPECT(
-
2858 jvVault[jss::result][jss::error].asString() ==
-
2859 "malformedRequest");
-
2860 }
-
2861
-
2862 {
-
2863 testcase("RPC ledger_entry negative seq");
-
2864 Json::Value jvParams;
-
2865 jvParams[jss::ledger_index] = jss::validated;
-
2866 jvParams[jss::vault][jss::owner] = issuer.human();
-
2867 jvParams[jss::vault][jss::seq] = -1;
-
2868 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2869 BEAST_EXPECT(
-
2870 jvVault[jss::result][jss::error].asString() ==
-
2871 "malformedRequest");
-
2872 }
-
2873
-
2874 {
-
2875 testcase("RPC ledger_entry oversized seq");
-
2876 Json::Value jvParams;
-
2877 jvParams[jss::ledger_index] = jss::validated;
-
2878 jvParams[jss::vault][jss::owner] = issuer.human();
-
2879 jvParams[jss::vault][jss::seq] = 1e20;
-
2880 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2881 BEAST_EXPECT(
-
2882 jvVault[jss::result][jss::error].asString() ==
-
2883 "malformedRequest");
-
2884 }
-
2885
-
2886 {
-
2887 testcase("RPC ledger_entry bool seq");
-
2888 Json::Value jvParams;
-
2889 jvParams[jss::ledger_index] = jss::validated;
-
2890 jvParams[jss::vault][jss::owner] = issuer.human();
-
2891 jvParams[jss::vault][jss::seq] = true;
-
2892 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
-
2893 BEAST_EXPECT(
-
2894 jvVault[jss::result][jss::error].asString() ==
-
2895 "malformedRequest");
-
2896 }
-
2897
-
2898 {
-
2899 testcase("RPC account_objects");
+
2812 jvVault[jss::result][jss::error].asString() ==
+
2813 "malformedRequest");
+
2814 }
+
2815
+
2816 {
+
2817 testcase("RPC ledger_entry malformed owner");
+
2818 Json::Value jvParams;
+
2819 jvParams[jss::ledger_index] = jss::validated;
+
2820 jvParams[jss::vault][jss::owner] = 42;
+
2821 jvParams[jss::vault][jss::seq] = sequence;
+
2822 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2823 BEAST_EXPECT(
+
2824 jvVault[jss::result][jss::error].asString() ==
+
2825 "malformedOwner");
+
2826 }
+
2827
+
2828 {
+
2829 testcase("RPC ledger_entry malformed seq");
+
2830 Json::Value jvParams;
+
2831 jvParams[jss::ledger_index] = jss::validated;
+
2832 jvParams[jss::vault][jss::owner] = issuer.human();
+
2833 jvParams[jss::vault][jss::seq] = "foo";
+
2834 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2835 BEAST_EXPECT(
+
2836 jvVault[jss::result][jss::error].asString() ==
+
2837 "malformedRequest");
+
2838 }
+
2839
+
2840 {
+
2841 testcase("RPC ledger_entry zero seq");
+
2842 Json::Value jvParams;
+
2843 jvParams[jss::ledger_index] = jss::validated;
+
2844 jvParams[jss::vault][jss::owner] = issuer.human();
+
2845 jvParams[jss::vault][jss::seq] = 0;
+
2846 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2847 BEAST_EXPECT(
+
2848 jvVault[jss::result][jss::error].asString() ==
+
2849 "malformedRequest");
+
2850 }
+
2851
+
2852 {
+
2853 testcase("RPC ledger_entry negative seq");
+
2854 Json::Value jvParams;
+
2855 jvParams[jss::ledger_index] = jss::validated;
+
2856 jvParams[jss::vault][jss::owner] = issuer.human();
+
2857 jvParams[jss::vault][jss::seq] = -1;
+
2858 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2859 BEAST_EXPECT(
+
2860 jvVault[jss::result][jss::error].asString() ==
+
2861 "malformedRequest");
+
2862 }
+
2863
+
2864 {
+
2865 testcase("RPC ledger_entry oversized seq");
+
2866 Json::Value jvParams;
+
2867 jvParams[jss::ledger_index] = jss::validated;
+
2868 jvParams[jss::vault][jss::owner] = issuer.human();
+
2869 jvParams[jss::vault][jss::seq] = 1e20;
+
2870 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2871 BEAST_EXPECT(
+
2872 jvVault[jss::result][jss::error].asString() ==
+
2873 "malformedRequest");
+
2874 }
+
2875
+
2876 {
+
2877 testcase("RPC ledger_entry bool seq");
+
2878 Json::Value jvParams;
+
2879 jvParams[jss::ledger_index] = jss::validated;
+
2880 jvParams[jss::vault][jss::owner] = issuer.human();
+
2881 jvParams[jss::vault][jss::seq] = true;
+
2882 auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
+
2883 BEAST_EXPECT(
+
2884 jvVault[jss::result][jss::error].asString() ==
+
2885 "malformedRequest");
+
2886 }
+
2887
+
2888 {
+
2889 testcase("RPC account_objects");
+
2890
+
2891 Json::Value jvParams;
+
2892 jvParams[jss::account] = owner.human();
+
2893 jvParams[jss::type] = jss::vault;
+
2894 auto jv = env.rpc(
+
2895 "json", "account_objects", to_string(jvParams))[jss::result];
+
2896
+
2897 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
+
2898 check(jv[jss::account_objects][0u]);
+
2899 }
2900
-
2901 Json::Value jvParams;
-
2902 jvParams[jss::account] = owner.human();
-
2903 jvParams[jss::type] = jss::vault;
-
2904 auto jv = env.rpc(
-
2905 "json", "account_objects", to_string(jvParams))[jss::result];
-
2906
-
2907 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
-
2908 check(jv[jss::account_objects][0u]);
-
2909 }
-
2910
-
2911 {
-
2912 testcase("RPC ledger_data");
+
2901 {
+
2902 testcase("RPC ledger_data");
+
2903
+
2904 Json::Value jvParams;
+
2905 jvParams[jss::ledger_index] = jss::validated;
+
2906 jvParams[jss::binary] = false;
+
2907 jvParams[jss::type] = jss::vault;
+
2908 Json::Value jv =
+
2909 env.rpc("json", "ledger_data", to_string(jvParams));
+
2910 BEAST_EXPECT(jv[jss::result][jss::state].size() == 1);
+
2911 check(jv[jss::result][jss::state][0u]);
+
2912 }
2913
-
2914 Json::Value jvParams;
-
2915 jvParams[jss::ledger_index] = jss::validated;
-
2916 jvParams[jss::binary] = false;
-
2917 jvParams[jss::type] = jss::vault;
-
2918 Json::Value jv =
-
2919 env.rpc("json", "ledger_data", to_string(jvParams));
-
2920 BEAST_EXPECT(jv[jss::result][jss::state].size() == 1);
-
2921 check(jv[jss::result][jss::state][0u]);
-
2922 }
-
2923
-
2924 {
-
2925 testcase("RPC vault_info command line");
-
2926 Json::Value jv =
-
2927 env.rpc("vault_info", strHex(keylet.key), "validated");
-
2928
-
2929 BEAST_EXPECT(!jv[jss::result].isMember(jss::error));
-
2930 BEAST_EXPECT(jv[jss::result].isMember(jss::vault));
-
2931 check(
-
2932 jv[jss::result][jss::vault],
-
2933 jv[jss::result][jss::vault][jss::shares]);
-
2934 }
-
2935
-
2936 {
-
2937 testcase("RPC vault_info json");
-
2938 Json::Value jvParams;
-
2939 jvParams[jss::ledger_index] = jss::validated;
-
2940 jvParams[jss::vault_id] = strHex(keylet.key);
-
2941 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
2942
-
2943 BEAST_EXPECT(!jv[jss::result].isMember(jss::error));
-
2944 BEAST_EXPECT(jv[jss::result].isMember(jss::vault));
-
2945 check(
-
2946 jv[jss::result][jss::vault],
-
2947 jv[jss::result][jss::vault][jss::shares]);
+
2914 {
+
2915 testcase("RPC vault_info command line");
+
2916 Json::Value jv =
+
2917 env.rpc("vault_info", strHex(keylet.key), "validated");
+
2918
+
2919 BEAST_EXPECT(!jv[jss::result].isMember(jss::error));
+
2920 BEAST_EXPECT(jv[jss::result].isMember(jss::vault));
+
2921 check(
+
2922 jv[jss::result][jss::vault],
+
2923 jv[jss::result][jss::vault][jss::shares]);
+
2924 }
+
2925
+
2926 {
+
2927 testcase("RPC vault_info json");
+
2928 Json::Value jvParams;
+
2929 jvParams[jss::ledger_index] = jss::validated;
+
2930 jvParams[jss::vault_id] = strHex(keylet.key);
+
2931 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
2932
+
2933 BEAST_EXPECT(!jv[jss::result].isMember(jss::error));
+
2934 BEAST_EXPECT(jv[jss::result].isMember(jss::vault));
+
2935 check(
+
2936 jv[jss::result][jss::vault],
+
2937 jv[jss::result][jss::vault][jss::shares]);
+
2938 }
+
2939
+
2940 {
+
2941 testcase("RPC vault_info invalid vault_id");
+
2942 Json::Value jvParams;
+
2943 jvParams[jss::ledger_index] = jss::validated;
+
2944 jvParams[jss::vault_id] = "foobar";
+
2945 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
2946 BEAST_EXPECT(
+
2947 jv[jss::result][jss::error].asString() == "malformedRequest");
2948 }
2949
2950 {
-
2951 testcase("RPC vault_info invalid vault_id");
+
2951 testcase("RPC vault_info json invalid index");
2952 Json::Value jvParams;
2953 jvParams[jss::ledger_index] = jss::validated;
-
2954 jvParams[jss::vault_id] = "foobar";
+
2954 jvParams[jss::vault_id] = 0;
2955 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
2956 BEAST_EXPECT(
2957 jv[jss::result][jss::error].asString() == "malformedRequest");
2958 }
2959
2960 {
-
2961 testcase("RPC vault_info json invalid index");
+
2961 testcase("RPC vault_info json by owner and sequence");
2962 Json::Value jvParams;
2963 jvParams[jss::ledger_index] = jss::validated;
-
2964 jvParams[jss::vault_id] = 0;
-
2965 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
2966 BEAST_EXPECT(
-
2967 jv[jss::result][jss::error].asString() == "malformedRequest");
-
2968 }
-
2969
-
2970 {
-
2971 testcase("RPC vault_info json by owner and sequence");
-
2972 Json::Value jvParams;
-
2973 jvParams[jss::ledger_index] = jss::validated;
-
2974 jvParams[jss::owner] = owner.human();
-
2975 jvParams[jss::seq] = sequence;
-
2976 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
2977
-
2978 BEAST_EXPECT(!jv[jss::result].isMember(jss::error));
-
2979 BEAST_EXPECT(jv[jss::result].isMember(jss::vault));
-
2980 check(
-
2981 jv[jss::result][jss::vault],
-
2982 jv[jss::result][jss::vault][jss::shares]);
-
2983 }
-
2984
-
2985 {
-
2986 testcase("RPC vault_info json malformed sequence");
-
2987 Json::Value jvParams;
-
2988 jvParams[jss::ledger_index] = jss::validated;
-
2989 jvParams[jss::owner] = owner.human();
-
2990 jvParams[jss::seq] = "foobar";
-
2991 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
2992 BEAST_EXPECT(
-
2993 jv[jss::result][jss::error].asString() == "malformedRequest");
-
2994 }
-
2995
-
2996 {
-
2997 testcase("RPC vault_info json invalid sequence");
-
2998 Json::Value jvParams;
-
2999 jvParams[jss::ledger_index] = jss::validated;
-
3000 jvParams[jss::owner] = owner.human();
-
3001 jvParams[jss::seq] = 0;
-
3002 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
3003 BEAST_EXPECT(
-
3004 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3005 }
-
3006
-
3007 {
-
3008 testcase("RPC vault_info json negative sequence");
-
3009 Json::Value jvParams;
-
3010 jvParams[jss::ledger_index] = jss::validated;
-
3011 jvParams[jss::owner] = owner.human();
-
3012 jvParams[jss::seq] = -1;
-
3013 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
3014 BEAST_EXPECT(
-
3015 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3016 }
-
3017
-
3018 {
-
3019 testcase("RPC vault_info json oversized sequence");
-
3020 Json::Value jvParams;
-
3021 jvParams[jss::ledger_index] = jss::validated;
-
3022 jvParams[jss::owner] = owner.human();
-
3023 jvParams[jss::seq] = 1e20;
-
3024 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
3025 BEAST_EXPECT(
-
3026 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3027 }
-
3028
-
3029 {
-
3030 testcase("RPC vault_info json bool sequence");
-
3031 Json::Value jvParams;
-
3032 jvParams[jss::ledger_index] = jss::validated;
-
3033 jvParams[jss::owner] = owner.human();
-
3034 jvParams[jss::seq] = true;
-
3035 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
3036 BEAST_EXPECT(
-
3037 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3038 }
-
3039
-
3040 {
-
3041 testcase("RPC vault_info json malformed owner");
-
3042 Json::Value jvParams;
-
3043 jvParams[jss::ledger_index] = jss::validated;
-
3044 jvParams[jss::owner] = "foobar";
-
3045 jvParams[jss::seq] = sequence;
+
2964 jvParams[jss::owner] = owner.human();
+
2965 jvParams[jss::seq] = sequence;
+
2966 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
2967
+
2968 BEAST_EXPECT(!jv[jss::result].isMember(jss::error));
+
2969 BEAST_EXPECT(jv[jss::result].isMember(jss::vault));
+
2970 check(
+
2971 jv[jss::result][jss::vault],
+
2972 jv[jss::result][jss::vault][jss::shares]);
+
2973 }
+
2974
+
2975 {
+
2976 testcase("RPC vault_info json malformed sequence");
+
2977 Json::Value jvParams;
+
2978 jvParams[jss::ledger_index] = jss::validated;
+
2979 jvParams[jss::owner] = owner.human();
+
2980 jvParams[jss::seq] = "foobar";
+
2981 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
2982 BEAST_EXPECT(
+
2983 jv[jss::result][jss::error].asString() == "malformedRequest");
+
2984 }
+
2985
+
2986 {
+
2987 testcase("RPC vault_info json invalid sequence");
+
2988 Json::Value jvParams;
+
2989 jvParams[jss::ledger_index] = jss::validated;
+
2990 jvParams[jss::owner] = owner.human();
+
2991 jvParams[jss::seq] = 0;
+
2992 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
2993 BEAST_EXPECT(
+
2994 jv[jss::result][jss::error].asString() == "malformedRequest");
+
2995 }
+
2996
+
2997 {
+
2998 testcase("RPC vault_info json negative sequence");
+
2999 Json::Value jvParams;
+
3000 jvParams[jss::ledger_index] = jss::validated;
+
3001 jvParams[jss::owner] = owner.human();
+
3002 jvParams[jss::seq] = -1;
+
3003 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
3004 BEAST_EXPECT(
+
3005 jv[jss::result][jss::error].asString() == "malformedRequest");
+
3006 }
+
3007
+
3008 {
+
3009 testcase("RPC vault_info json oversized sequence");
+
3010 Json::Value jvParams;
+
3011 jvParams[jss::ledger_index] = jss::validated;
+
3012 jvParams[jss::owner] = owner.human();
+
3013 jvParams[jss::seq] = 1e20;
+
3014 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
3015 BEAST_EXPECT(
+
3016 jv[jss::result][jss::error].asString() == "malformedRequest");
+
3017 }
+
3018
+
3019 {
+
3020 testcase("RPC vault_info json bool sequence");
+
3021 Json::Value jvParams;
+
3022 jvParams[jss::ledger_index] = jss::validated;
+
3023 jvParams[jss::owner] = owner.human();
+
3024 jvParams[jss::seq] = true;
+
3025 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
3026 BEAST_EXPECT(
+
3027 jv[jss::result][jss::error].asString() == "malformedRequest");
+
3028 }
+
3029
+
3030 {
+
3031 testcase("RPC vault_info json malformed owner");
+
3032 Json::Value jvParams;
+
3033 jvParams[jss::ledger_index] = jss::validated;
+
3034 jvParams[jss::owner] = "foobar";
+
3035 jvParams[jss::seq] = sequence;
+
3036 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
3037 BEAST_EXPECT(
+
3038 jv[jss::result][jss::error].asString() == "malformedRequest");
+
3039 }
+
3040
+
3041 {
+
3042 testcase("RPC vault_info json invalid combination only owner");
+
3043 Json::Value jvParams;
+
3044 jvParams[jss::ledger_index] = jss::validated;
+
3045 jvParams[jss::owner] = owner.human();
3046 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
3047 BEAST_EXPECT(
3048 jv[jss::result][jss::error].asString() == "malformedRequest");
3049 }
3050
3051 {
-
3052 testcase("RPC vault_info json invalid combination only owner");
+
3052 testcase("RPC vault_info json invalid combination only seq");
3053 Json::Value jvParams;
3054 jvParams[jss::ledger_index] = jss::validated;
-
3055 jvParams[jss::owner] = owner.human();
+
3055 jvParams[jss::seq] = sequence;
3056 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
3057 BEAST_EXPECT(
3058 jv[jss::result][jss::error].asString() == "malformedRequest");
3059 }
3060
3061 {
-
3062 testcase("RPC vault_info json invalid combination only seq");
+
3062 testcase("RPC vault_info json invalid combination seq vault_id");
3063 Json::Value jvParams;
3064 jvParams[jss::ledger_index] = jss::validated;
-
3065 jvParams[jss::seq] = sequence;
-
3066 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
3067 BEAST_EXPECT(
-
3068 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3069 }
-
3070
-
3071 {
-
3072 testcase("RPC vault_info json invalid combination seq vault_id");
-
3073 Json::Value jvParams;
-
3074 jvParams[jss::ledger_index] = jss::validated;
-
3075 jvParams[jss::vault_id] = strHex(keylet.key);
-
3076 jvParams[jss::seq] = sequence;
-
3077 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
3078 BEAST_EXPECT(
-
3079 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3080 }
-
3081
-
3082 {
-
3083 testcase("RPC vault_info json invalid combination owner vault_id");
-
3084 Json::Value jvParams;
-
3085 jvParams[jss::ledger_index] = jss::validated;
-
3086 jvParams[jss::vault_id] = strHex(keylet.key);
-
3087 jvParams[jss::owner] = owner.human();
-
3088 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
3089 BEAST_EXPECT(
-
3090 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3091 }
-
3092
-
3093 {
-
3094 testcase(
-
3095 "RPC vault_info json invalid combination owner seq "
-
3096 "vault_id");
-
3097 Json::Value jvParams;
-
3098 jvParams[jss::ledger_index] = jss::validated;
-
3099 jvParams[jss::vault_id] = strHex(keylet.key);
-
3100 jvParams[jss::seq] = sequence;
-
3101 jvParams[jss::owner] = owner.human();
-
3102 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
3103 BEAST_EXPECT(
-
3104 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3105 }
-
3106
-
3107 {
-
3108 testcase("RPC vault_info json no input");
-
3109 Json::Value jvParams;
-
3110 jvParams[jss::ledger_index] = jss::validated;
-
3111 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
-
3112 BEAST_EXPECT(
-
3113 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3114 }
-
3115
-
3116 {
-
3117 testcase("RPC vault_info command line invalid index");
-
3118 Json::Value jv = env.rpc("vault_info", "foobar", "validated");
-
3119 BEAST_EXPECT(jv[jss::error].asString() == "invalidParams");
-
3120 }
-
3121
-
3122 {
-
3123 testcase("RPC vault_info command line invalid index");
-
3124 Json::Value jv = env.rpc("vault_info", "0", "validated");
-
3125 BEAST_EXPECT(
-
3126 jv[jss::result][jss::error].asString() == "malformedRequest");
-
3127 }
-
3128
-
3129 {
-
3130 testcase("RPC vault_info command line invalid index");
-
3131 Json::Value jv =
-
3132 env.rpc("vault_info", strHex(uint256(42)), "validated");
-
3133 BEAST_EXPECT(
-
3134 jv[jss::result][jss::error].asString() == "entryNotFound");
-
3135 }
-
3136
-
3137 {
-
3138 testcase("RPC vault_info command line invalid ledger");
-
3139 Json::Value jv = env.rpc("vault_info", strHex(keylet.key), "0");
-
3140 BEAST_EXPECT(
-
3141 jv[jss::result][jss::error].asString() == "lgrNotFound");
-
3142 }
-
3143 }
-
3144
-
3145public:
-
3146 void
-
3147 run() override
-
3148 {
-
3149 testSequences();
-
3150 testPreflight();
-
3151 testCreateFailXRP();
-
3152 testCreateFailIOU();
-
3153 testCreateFailMPT();
-
3154 testWithMPT();
-
3155 testWithIOU();
-
3156 testWithDomainCheck();
-
3157 testWithDomainCheckXRP();
-
3158 testNonTransferableShares();
-
3159 testFailedPseudoAccount();
-
3160 testRPC();
-
3161 }
-
3162};
-
3163
-
3164BEAST_DEFINE_TESTSUITE_PRIO(Vault, tx, ripple, 1);
-
3165
-
3166} // namespace ripple
+
3065 jvParams[jss::vault_id] = strHex(keylet.key);
+
3066 jvParams[jss::seq] = sequence;
+
3067 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
3068 BEAST_EXPECT(
+
3069 jv[jss::result][jss::error].asString() == "malformedRequest");
+
3070 }
+
3071
+
3072 {
+
3073 testcase("RPC vault_info json invalid combination owner vault_id");
+
3074 Json::Value jvParams;
+
3075 jvParams[jss::ledger_index] = jss::validated;
+
3076 jvParams[jss::vault_id] = strHex(keylet.key);
+
3077 jvParams[jss::owner] = owner.human();
+
3078 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
3079 BEAST_EXPECT(
+
3080 jv[jss::result][jss::error].asString() == "malformedRequest");
+
3081 }
+
3082
+
3083 {
+
3084 testcase(
+
3085 "RPC vault_info json invalid combination owner seq "
+
3086 "vault_id");
+
3087 Json::Value jvParams;
+
3088 jvParams[jss::ledger_index] = jss::validated;
+
3089 jvParams[jss::vault_id] = strHex(keylet.key);
+
3090 jvParams[jss::seq] = sequence;
+
3091 jvParams[jss::owner] = owner.human();
+
3092 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
3093 BEAST_EXPECT(
+
3094 jv[jss::result][jss::error].asString() == "malformedRequest");
+
3095 }
+
3096
+
3097 {
+
3098 testcase("RPC vault_info json no input");
+
3099 Json::Value jvParams;
+
3100 jvParams[jss::ledger_index] = jss::validated;
+
3101 auto jv = env.rpc("json", "vault_info", to_string(jvParams));
+
3102 BEAST_EXPECT(
+
3103 jv[jss::result][jss::error].asString() == "malformedRequest");
+
3104 }
+
3105
+
3106 {
+
3107 testcase("RPC vault_info command line invalid index");
+
3108 Json::Value jv = env.rpc("vault_info", "foobar", "validated");
+
3109 BEAST_EXPECT(jv[jss::error].asString() == "invalidParams");
+
3110 }
+
3111
+
3112 {
+
3113 testcase("RPC vault_info command line invalid index");
+
3114 Json::Value jv = env.rpc("vault_info", "0", "validated");
+
3115 BEAST_EXPECT(
+
3116 jv[jss::result][jss::error].asString() == "malformedRequest");
+
3117 }
+
3118
+
3119 {
+
3120 testcase("RPC vault_info command line invalid index");
+
3121 Json::Value jv =
+
3122 env.rpc("vault_info", strHex(uint256(42)), "validated");
+
3123 BEAST_EXPECT(
+
3124 jv[jss::result][jss::error].asString() == "entryNotFound");
+
3125 }
+
3126
+
3127 {
+
3128 testcase("RPC vault_info command line invalid ledger");
+
3129 Json::Value jv = env.rpc("vault_info", strHex(keylet.key), "0");
+
3130 BEAST_EXPECT(
+
3131 jv[jss::result][jss::error].asString() == "lgrNotFound");
+
3132 }
+
3133 }
+
3134
+
3135public:
+
3136 void
+
3137 run() override
+
3138 {
+
3139 testSequences();
+
3140 testPreflight();
+
3141 testCreateFailXRP();
+
3142 testCreateFailIOU();
+
3143 testCreateFailMPT();
+
3144 testWithMPT();
+
3145 testWithIOU();
+
3146 testWithDomainCheck();
+
3147 testWithDomainCheckXRP();
+
3148 testNonTransferableShares();
+
3149 testFailedPseudoAccount();
+
3150 testRPC();
+
3151 }
+
3152};
+
3153
+
3154BEAST_DEFINE_TESTSUITE_PRIO(Vault, tx, ripple, 1);
+
3155
+
3156} // namespace ripple
std::string
Json::Value
Represents a JSON value.
Definition: json_value.h:150
beast::unit_test::suite
A testsuite class.
Definition: suite.h:55
@@ -3257,23 +3247,23 @@ $(function() {
ripple::STAmount
Definition: STAmount.h:50
ripple::STAmount::setIssuer
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:588
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:496
-
ripple::Vault_test
Definition: Vault_test.cpp:57
-
ripple::Vault_test::testCreateFailIOU
void testCreateFailIOU()
Definition: Vault_test.cpp:1099
-
ripple::Vault_test::testWithMPT
void testWithMPT()
Definition: Vault_test.cpp:1344
-
ripple::Vault_test::testFailedPseudoAccount
void testFailedPseudoAccount()
Definition: Vault_test.cpp:2637
-
ripple::Vault_test::PrettyAsset
ripple::test::jtx::PrettyAsset PrettyAsset
Definition: Vault_test.cpp:58
-
ripple::Vault_test::testRPC
void testRPC()
Definition: Vault_test.cpp:2666
-
ripple::Vault_test::testPreflight
void testPreflight()
Definition: Vault_test.cpp:422
-
ripple::Vault_test::testWithIOU
void testWithIOU()
Definition: Vault_test.cpp:1791
-
ripple::Vault_test::testNonTransferableShares
void testNonTransferableShares()
Definition: Vault_test.cpp:1233
-
ripple::Vault_test::testCreateFailMPT
void testCreateFailMPT()
Definition: Vault_test.cpp:1211
-
ripple::Vault_test::testWithDomainCheck
void testWithDomainCheck()
Definition: Vault_test.cpp:2248
-
ripple::Vault_test::negativeAmount
static auto constexpr negativeAmount
Definition: Vault_test.cpp:61
-
ripple::Vault_test::run
void run() override
Runs the suite.
Definition: Vault_test.cpp:3147
-
ripple::Vault_test::testSequences
void testSequences()
Definition: Vault_test.cpp:67
-
ripple::Vault_test::testWithDomainCheckXRP
void testWithDomainCheckXRP()
Definition: Vault_test.cpp:2533
-
ripple::Vault_test::PrettyAmount
ripple::test::jtx::PrettyAmount PrettyAmount
Definition: Vault_test.cpp:59
-
ripple::Vault_test::testCreateFailXRP
void testCreateFailXRP()
Definition: Vault_test.cpp:952
+
ripple::Vault_test
Definition: Vault_test.cpp:47
+
ripple::Vault_test::testCreateFailIOU
void testCreateFailIOU()
Definition: Vault_test.cpp:1089
+
ripple::Vault_test::testWithMPT
void testWithMPT()
Definition: Vault_test.cpp:1334
+
ripple::Vault_test::testFailedPseudoAccount
void testFailedPseudoAccount()
Definition: Vault_test.cpp:2627
+
ripple::Vault_test::PrettyAsset
ripple::test::jtx::PrettyAsset PrettyAsset
Definition: Vault_test.cpp:48
+
ripple::Vault_test::testRPC
void testRPC()
Definition: Vault_test.cpp:2656
+
ripple::Vault_test::testPreflight
void testPreflight()
Definition: Vault_test.cpp:412
+
ripple::Vault_test::testWithIOU
void testWithIOU()
Definition: Vault_test.cpp:1781
+
ripple::Vault_test::testNonTransferableShares
void testNonTransferableShares()
Definition: Vault_test.cpp:1223
+
ripple::Vault_test::testCreateFailMPT
void testCreateFailMPT()
Definition: Vault_test.cpp:1201
+
ripple::Vault_test::testWithDomainCheck
void testWithDomainCheck()
Definition: Vault_test.cpp:2238
+
ripple::Vault_test::negativeAmount
static auto constexpr negativeAmount
Definition: Vault_test.cpp:51
+
ripple::Vault_test::run
void run() override
Runs the suite.
Definition: Vault_test.cpp:3137
+
ripple::Vault_test::testSequences
void testSequences()
Definition: Vault_test.cpp:57
+
ripple::Vault_test::testWithDomainCheckXRP
void testWithDomainCheckXRP()
Definition: Vault_test.cpp:2523
+
ripple::Vault_test::PrettyAmount
ripple::test::jtx::PrettyAmount PrettyAmount
Definition: Vault_test.cpp:49
+
ripple::Vault_test::testCreateFailXRP
void testCreateFailXRP()
Definition: Vault_test.cpp:942
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:86
std::function
Json::nullValue
@ nullValue
'null' value
Definition: json_value.h:39
diff --git a/classripple_1_1Vault__test.html b/classripple_1_1Vault__test.html index 4cc91c51a1..3a96f75208 100644 --- a/classripple_1_1Vault__test.html +++ b/classripple_1_1Vault__test.html @@ -256,7 +256,7 @@ Static Private Attributes

Detailed Description

-

Definition at line 56 of file Vault_test.cpp.

+

Definition at line 46 of file Vault_test.cpp.

Member Typedef Documentation

◆ PrettyAsset

@@ -278,7 +278,7 @@ Static Private Attributes
-

Definition at line 58 of file Vault_test.cpp.

+

Definition at line 48 of file Vault_test.cpp.

@@ -302,7 +302,7 @@ Static Private Attributes
-

Definition at line 59 of file Vault_test.cpp.

+

Definition at line 49 of file Vault_test.cpp.

@@ -330,7 +330,7 @@ Static Private Attributes
-

Definition at line 67 of file Vault_test.cpp.

+

Definition at line 57 of file Vault_test.cpp.

@@ -357,7 +357,7 @@ Static Private Attributes
-

Definition at line 422 of file Vault_test.cpp.

+

Definition at line 412 of file Vault_test.cpp.

@@ -384,7 +384,7 @@ Static Private Attributes
-

Definition at line 952 of file Vault_test.cpp.

+

Definition at line 942 of file Vault_test.cpp.

@@ -411,7 +411,7 @@ Static Private Attributes
-

Definition at line 1099 of file Vault_test.cpp.

+

Definition at line 1089 of file Vault_test.cpp.

@@ -438,7 +438,7 @@ Static Private Attributes
-

Definition at line 1211 of file Vault_test.cpp.

+

Definition at line 1201 of file Vault_test.cpp.

@@ -465,7 +465,7 @@ Static Private Attributes
-

Definition at line 1233 of file Vault_test.cpp.

+

Definition at line 1223 of file Vault_test.cpp.

@@ -492,7 +492,7 @@ Static Private Attributes
-

Definition at line 1344 of file Vault_test.cpp.

+

Definition at line 1334 of file Vault_test.cpp.

@@ -519,7 +519,7 @@ Static Private Attributes
-

Definition at line 1791 of file Vault_test.cpp.

+

Definition at line 1781 of file Vault_test.cpp.

@@ -546,7 +546,7 @@ Static Private Attributes
-

Definition at line 2248 of file Vault_test.cpp.

+

Definition at line 2238 of file Vault_test.cpp.

@@ -573,7 +573,7 @@ Static Private Attributes
-

Definition at line 2533 of file Vault_test.cpp.

+

Definition at line 2523 of file Vault_test.cpp.

@@ -600,7 +600,7 @@ Static Private Attributes
-

Definition at line 2637 of file Vault_test.cpp.

+

Definition at line 2627 of file Vault_test.cpp.

@@ -627,7 +627,7 @@ Static Private Attributes
-

Definition at line 2666 of file Vault_test.cpp.

+

Definition at line 2656 of file Vault_test.cpp.

@@ -658,7 +658,7 @@ Static Private Attributes

Implements beast::unit_test::suite.

-

Definition at line 3147 of file Vault_test.cpp.

+

Definition at line 3137 of file Vault_test.cpp.

@@ -1407,10 +1407,10 @@ template<class Condition >
[](PrettyAsset const& asset) -> PrettyAmount {
return {STAmount{asset.raw(), 1ul, 0, true, STAmount::unchecked{}}, ""};
}
-
ripple::Vault_test::PrettyAsset
ripple::test::jtx::PrettyAsset PrettyAsset
Definition: Vault_test.cpp:58
-
ripple::Vault_test::PrettyAmount
ripple::test::jtx::PrettyAmount PrettyAmount
Definition: Vault_test.cpp:59
+
ripple::Vault_test::PrettyAsset
ripple::test::jtx::PrettyAsset PrettyAsset
Definition: Vault_test.cpp:48
+
ripple::Vault_test::PrettyAmount
ripple::test::jtx::PrettyAmount PrettyAmount
Definition: Vault_test.cpp:49
-

Definition at line 61 of file Vault_test.cpp.

+

Definition at line 51 of file Vault_test.cpp.

diff --git a/classripple_1_1test_1_1jtx_1_1MPTTester.html b/classripple_1_1test_1_1jtx_1_1MPTTester.html index 9dd65e72f6..50642b11ad 100644 --- a/classripple_1_1test_1_1jtx_1_1MPTTester.html +++ b/classripple_1_1test_1_1jtx_1_1MPTTester.html @@ -213,7 +213,7 @@ Private Attributes

Detailed Description

-

Definition at line 144 of file mpt.h.

+

Definition at line 145 of file mpt.h.

Member Typedef Documentation

◆ SLEP

@@ -235,7 +235,7 @@ Private Attributes
-

Definition at line 219 of file mpt.h.

+

Definition at line 220 of file mpt.h.

@@ -452,7 +452,7 @@ Private Attributes
-

Definition at line 180 of file mpt.h.

+

Definition at line 181 of file mpt.h.

@@ -601,7 +601,7 @@ Private Attributes
-

Definition at line 205 of file mpt.h.

+

Definition at line 206 of file mpt.h.

@@ -719,7 +719,7 @@ template<typename A >
-

Definition at line 227 of file mpt.h.

+

Definition at line 228 of file mpt.h.

@@ -800,7 +800,7 @@ template<typename A >
-

Definition at line 146 of file mpt.h.

+

Definition at line 147 of file mpt.h.

@@ -824,7 +824,7 @@ template<typename A >
-

Definition at line 147 of file mpt.h.

+

Definition at line 148 of file mpt.h.

@@ -848,7 +848,7 @@ template<typename A >
-

Definition at line 148 of file mpt.h.

+

Definition at line 149 of file mpt.h.

@@ -872,7 +872,7 @@ template<typename A >
-

Definition at line 149 of file mpt.h.

+

Definition at line 150 of file mpt.h.

@@ -896,7 +896,7 @@ template<typename A >
-

Definition at line 150 of file mpt.h.

+

Definition at line 151 of file mpt.h.

diff --git a/classripple_1_1test_1_1jtx_1_1PermissionedDEX.html b/classripple_1_1test_1_1jtx_1_1PermissionedDEX.html index 40a6633963..a5d5f51e91 100644 --- a/classripple_1_1test_1_1jtx_1_1PermissionedDEX.html +++ b/classripple_1_1test_1_1jtx_1_1PermissionedDEX.html @@ -133,7 +133,7 @@ Public Attributes

Detailed Description

-

Definition at line 34 of file permissioned_dex.h.

+

Definition at line 36 of file permissioned_dex.h.

Constructor & Destructor Documentation

◆ PermissionedDEX()

@@ -168,7 +168,7 @@ Public Attributes
-

Definition at line 37 of file permissioned_dex.h.

+

Definition at line 39 of file permissioned_dex.h.

@@ -184,7 +184,7 @@ Public Attributes
-

Definition at line 38 of file permissioned_dex.h.

+

Definition at line 40 of file permissioned_dex.h.

@@ -200,7 +200,7 @@ Public Attributes
-

Definition at line 39 of file permissioned_dex.h.

+

Definition at line 41 of file permissioned_dex.h.

@@ -216,7 +216,7 @@ Public Attributes
-

Definition at line 40 of file permissioned_dex.h.

+

Definition at line 42 of file permissioned_dex.h.

@@ -232,7 +232,7 @@ Public Attributes
-

Definition at line 41 of file permissioned_dex.h.

+

Definition at line 43 of file permissioned_dex.h.

@@ -248,7 +248,7 @@ Public Attributes
-

Definition at line 42 of file permissioned_dex.h.

+

Definition at line 44 of file permissioned_dex.h.

@@ -264,7 +264,7 @@ Public Attributes
-

Definition at line 43 of file permissioned_dex.h.

+

Definition at line 45 of file permissioned_dex.h.

@@ -280,7 +280,7 @@ Public Attributes
-

Definition at line 44 of file permissioned_dex.h.

+

Definition at line 46 of file permissioned_dex.h.

diff --git a/classripple_1_1test_1_1jtx_1_1mptbalance.html b/classripple_1_1test_1_1jtx_1_1mptbalance.html index 5816387ae4..3f091ef754 100644 --- a/classripple_1_1test_1_1jtx_1_1mptbalance.html +++ b/classripple_1_1test_1_1jtx_1_1mptbalance.html @@ -158,7 +158,7 @@ Private Attributes

Detailed Description

-

Definition at line 57 of file mpt.h.

+

Definition at line 58 of file mpt.h.

Constructor & Destructor Documentation

◆ mptbalance()

@@ -192,7 +192,7 @@ Private Attributes
-

Definition at line 65 of file mpt.h.

+

Definition at line 66 of file mpt.h.

@@ -238,7 +238,7 @@ Private Attributes
-

Definition at line 60 of file mpt.h.

+

Definition at line 61 of file mpt.h.

@@ -262,7 +262,7 @@ Private Attributes
-

Definition at line 61 of file mpt.h.

+

Definition at line 62 of file mpt.h.

@@ -286,7 +286,7 @@ Private Attributes
-

Definition at line 62 of file mpt.h.

+

Definition at line 63 of file mpt.h.

diff --git a/classripple_1_1test_1_1jtx_1_1mptflags.html b/classripple_1_1test_1_1jtx_1_1mptflags.html index a61fdb44b1..7f636ccb92 100644 --- a/classripple_1_1test_1_1jtx_1_1mptflags.html +++ b/classripple_1_1test_1_1jtx_1_1mptflags.html @@ -158,7 +158,7 @@ Private Attributes

Detailed Description

-

Definition at line 36 of file mpt.h.

+

Definition at line 37 of file mpt.h.

Constructor & Destructor Documentation

◆ mptflags()

@@ -192,7 +192,7 @@ Private Attributes
-

Definition at line 44 of file mpt.h.

+

Definition at line 45 of file mpt.h.

@@ -238,7 +238,7 @@ Private Attributes
-

Definition at line 39 of file mpt.h.

+

Definition at line 40 of file mpt.h.

@@ -262,7 +262,7 @@ Private Attributes
-

Definition at line 40 of file mpt.h.

+

Definition at line 41 of file mpt.h.

@@ -286,7 +286,7 @@ Private Attributes
-

Definition at line 41 of file mpt.h.

+

Definition at line 42 of file mpt.h.

diff --git a/classripple_1_1test_1_1jtx_1_1requireAny.html b/classripple_1_1test_1_1jtx_1_1requireAny.html index 1d43650c25..da149706e8 100644 --- a/classripple_1_1test_1_1jtx_1_1requireAny.html +++ b/classripple_1_1test_1_1jtx_1_1requireAny.html @@ -106,7 +106,7 @@ Private Attributes

Detailed Description

-

Definition at line 74 of file mpt.h.

+

Definition at line 75 of file mpt.h.

Constructor & Destructor Documentation

◆ requireAny()

@@ -124,7 +124,7 @@ Private Attributes
-

Definition at line 80 of file mpt.h.

+

Definition at line 81 of file mpt.h.

@@ -170,7 +170,7 @@ Private Attributes
-

Definition at line 77 of file mpt.h.

+

Definition at line 78 of file mpt.h.

diff --git a/jtx_8h_source.html b/jtx_8h_source.html index f48dc56218..88ec932023 100644 --- a/jtx_8h_source.html +++ b/jtx_8h_source.html @@ -100,62 +100,63 @@ $(function() {
22
23// Convenience header that includes everything
24
-
25#include <test/jtx/Account.h>
-
26#include <test/jtx/Env.h>
-
27#include <test/jtx/Env_ss.h>
-
28#include <test/jtx/JTx.h>
-
29#include <test/jtx/TestHelpers.h>
-
30#include <test/jtx/account_txn_id.h>
-
31#include <test/jtx/acctdelete.h>
-
32#include <test/jtx/amount.h>
-
33#include <test/jtx/balance.h>
-
34#include <test/jtx/batch.h>
-
35#include <test/jtx/check.h>
-
36#include <test/jtx/credentials.h>
-
37#include <test/jtx/delegate.h>
-
38#include <test/jtx/delivermin.h>
-
39#include <test/jtx/deposit.h>
-
40#include <test/jtx/did.h>
-
41#include <test/jtx/domain.h>
-
42#include <test/jtx/escrow.h>
-
43#include <test/jtx/fee.h>
-
44#include <test/jtx/flags.h>
-
45#include <test/jtx/invoice_id.h>
-
46#include <test/jtx/jtx_json.h>
-
47#include <test/jtx/last_ledger_sequence.h>
-
48#include <test/jtx/ledgerStateFix.h>
-
49#include <test/jtx/memo.h>
-
50#include <test/jtx/mpt.h>
-
51#include <test/jtx/multisign.h>
-
52#include <test/jtx/noop.h>
-
53#include <test/jtx/offer.h>
-
54#include <test/jtx/owners.h>
-
55#include <test/jtx/paths.h>
-
56#include <test/jtx/pay.h>
-
57#include <test/jtx/permissioned_dex.h>
-
58#include <test/jtx/permissioned_domains.h>
-
59#include <test/jtx/prop.h>
-
60#include <test/jtx/quality.h>
-
61#include <test/jtx/rate.h>
-
62#include <test/jtx/regkey.h>
-
63#include <test/jtx/require.h>
-
64#include <test/jtx/requires.h>
-
65#include <test/jtx/rpc.h>
-
66#include <test/jtx/sendmax.h>
-
67#include <test/jtx/seq.h>
-
68#include <test/jtx/sig.h>
-
69#include <test/jtx/tag.h>
-
70#include <test/jtx/tags.h>
-
71#include <test/jtx/ter.h>
-
72#include <test/jtx/ticket.h>
-
73#include <test/jtx/token.h>
-
74#include <test/jtx/trust.h>
-
75#include <test/jtx/txflags.h>
-
76#include <test/jtx/utility.h>
-
77
-
78#include <xrpl/json/to_string.h>
-
79
-
80#endif
+
25#include <test/jtx/AMM.h>
+
26#include <test/jtx/Account.h>
+
27#include <test/jtx/Env.h>
+
28#include <test/jtx/Env_ss.h>
+
29#include <test/jtx/JTx.h>
+
30#include <test/jtx/TestHelpers.h>
+
31#include <test/jtx/account_txn_id.h>
+
32#include <test/jtx/acctdelete.h>
+
33#include <test/jtx/amount.h>
+
34#include <test/jtx/balance.h>
+
35#include <test/jtx/batch.h>
+
36#include <test/jtx/check.h>
+
37#include <test/jtx/credentials.h>
+
38#include <test/jtx/delegate.h>
+
39#include <test/jtx/delivermin.h>
+
40#include <test/jtx/deposit.h>
+
41#include <test/jtx/did.h>
+
42#include <test/jtx/domain.h>
+
43#include <test/jtx/escrow.h>
+
44#include <test/jtx/fee.h>
+
45#include <test/jtx/flags.h>
+
46#include <test/jtx/invoice_id.h>
+
47#include <test/jtx/jtx_json.h>
+
48#include <test/jtx/last_ledger_sequence.h>
+
49#include <test/jtx/ledgerStateFix.h>
+
50#include <test/jtx/memo.h>
+
51#include <test/jtx/mpt.h>
+
52#include <test/jtx/multisign.h>
+
53#include <test/jtx/noop.h>
+
54#include <test/jtx/offer.h>
+
55#include <test/jtx/owners.h>
+
56#include <test/jtx/paths.h>
+
57#include <test/jtx/pay.h>
+
58#include <test/jtx/permissioned_dex.h>
+
59#include <test/jtx/permissioned_domains.h>
+
60#include <test/jtx/prop.h>
+
61#include <test/jtx/quality.h>
+
62#include <test/jtx/rate.h>
+
63#include <test/jtx/regkey.h>
+
64#include <test/jtx/require.h>
+
65#include <test/jtx/requires.h>
+
66#include <test/jtx/rpc.h>
+
67#include <test/jtx/sendmax.h>
+
68#include <test/jtx/seq.h>
+
69#include <test/jtx/sig.h>
+
70#include <test/jtx/tag.h>
+
71#include <test/jtx/tags.h>
+
72#include <test/jtx/ter.h>
+
73#include <test/jtx/ticket.h>
+
74#include <test/jtx/token.h>
+
75#include <test/jtx/trust.h>
+
76#include <test/jtx/txflags.h>
+
77#include <test/jtx/utility.h>
+
78
+
79#include <xrpl/json/to_string.h>
+
80
+
81#endif