1205        using namespace test::jtx;
 
 1209            {{
"permissioned domain with no rules."}},
 
 1213                slePd->setAccountID(sfOwner, 
A1);
 
 1214                slePd->setFieldU32(sfSequence, 10);
 
 1216                ac.view().insert(slePd);
 
 1223        testcase << 
"PermissionedDomain 2";
 
 1227            {{
"permissioned domain bad credentials size " +
 
 1232                slePd->setAccountID(sfOwner, 
A1);
 
 1233                slePd->setFieldU32(sfSequence, 10);
 
 1235                STArray credentials(sfAcceptedCredentials, tooBig);
 
 1239                    cred.setAccountID(sfIssuer, 
A2);
 
 1244                        Slice(credType.c_str(), credType.size()));
 
 1247                slePd->setFieldArray(sfAcceptedCredentials, credentials);
 
 1248                ac.view().insert(slePd);
 
 1255        testcase << 
"PermissionedDomain 3";
 
 1257            {{
"permissioned domain credentials aren't sorted"}},
 
 1261                slePd->setAccountID(sfOwner, 
A1);
 
 1262                slePd->setFieldU32(sfSequence, 10);
 
 1264                STArray credentials(sfAcceptedCredentials, 2);
 
 1268                    cred.setAccountID(sfIssuer, 
A2);
 
 1273                        Slice(credType.c_str(), credType.size()));
 
 1276                slePd->setFieldArray(sfAcceptedCredentials, credentials);
 
 1277                ac.view().insert(slePd);
 
 1284        testcase << 
"PermissionedDomain 4";
 
 1286            {{
"permissioned domain credentials aren't unique"}},
 
 1290                slePd->setAccountID(sfOwner, 
A1);
 
 1291                slePd->setFieldU32(sfSequence, 10);
 
 1293                STArray credentials(sfAcceptedCredentials, 2);
 
 1297                    cred.setAccountID(sfIssuer, 
A2);
 
 1298                    cred.setFieldVL(sfCredentialType, 
Slice(
"cred_type", 9));
 
 1301                slePd->setFieldArray(sfAcceptedCredentials, credentials);
 
 1302                ac.view().insert(slePd);
 
 1309        testcase << 
"PermissionedDomain Set 1";
 
 1311            {{
"permissioned domain with no rules."}},
 
 1321                    STArray credentials(sfAcceptedCredentials, 2);
 
 1322                    slePd->setFieldArray(sfAcceptedCredentials, credentials);
 
 1323                    ac.view().update(slePd);
 
 1332        testcase << 
"PermissionedDomain Set 2";
 
 1334            {{
"permissioned domain bad credentials size " +
 
 1345                    STArray credentials(sfAcceptedCredentials, tooBig);
 
 1350                        cred.setAccountID(sfIssuer, 
A2);
 
 1354                            Slice(credType.c_str(), credType.size()));
 
 1358                    slePd->setFieldArray(sfAcceptedCredentials, credentials);
 
 1359                    ac.view().update(slePd);
 
 1368        testcase << 
"PermissionedDomain Set 3";
 
 1370            {{
"permissioned domain credentials aren't sorted"}},
 
 1380                    STArray credentials(sfAcceptedCredentials, 2);
 
 1384                        cred.setAccountID(sfIssuer, 
A2);
 
 1389                            Slice(credType.c_str(), credType.size()));
 
 1393                    slePd->setFieldArray(sfAcceptedCredentials, credentials);
 
 1394                    ac.view().update(slePd);
 
 1403        testcase << 
"PermissionedDomain Set 4";
 
 1405            {{
"permissioned domain credentials aren't unique"}},
 
 1415                    STArray credentials(sfAcceptedCredentials, 2);
 
 1419                        cred.setAccountID(sfIssuer, 
A2);
 
 1421                            sfCredentialType, 
Slice(
"cred_type", 9));
 
 1424                    slePd->setFieldArray(sfAcceptedCredentials, credentials);
 
 1425                    ac.view().update(slePd);
 
 
 1728        using namespace test::jtx;
 
 1730        struct AccountAmount
 
 1746        auto constexpr adjust = [&](
ApplyView& ac,
 
 1749            auto sleVault = ac.
peek(keylet);
 
 1753            auto const mptIssuanceID = (*sleVault)[sfShareMPTID];
 
 1759            if (args.lossUnrealized)
 
 1760                (*sleVault)[sfLossUnrealized] = *args.lossUnrealized;
 
 1761            if (args.assetsMaximum)
 
 1762                (*sleVault)[sfAssetsMaximum] = *args.assetsMaximum;
 
 1765            if (args.assetsTotal)
 
 1766                (*sleVault)[sfAssetsTotal] =
 
 1767                    *(*sleVault)[sfAssetsTotal] + *args.assetsTotal;
 
 1768            if (args.assetsAvailable)
 
 1769                (*sleVault)[sfAssetsAvailable] =
 
 1770                    *(*sleVault)[sfAssetsAvailable] + *args.assetsAvailable;
 
 1773            if (args.sharesTotal)
 
 1775                (*sleShares)[sfOutstandingAmount] =
 
 1776                    *(*sleShares)[sfOutstandingAmount] + *args.sharesTotal;
 
 1780            auto const assets = *(*sleVault)[sfAsset];
 
 1781            auto const pseudoId = *(*sleVault)[sfAccount];
 
 1782            if (args.vaultAssets)
 
 1784                if (assets.native())
 
 1787                    if (!slePseudoAccount)
 
 1789                    (*slePseudoAccount)[sfBalance] =
 
 1790                        *(*slePseudoAccount)[sfBalance] + *args.vaultAssets;
 
 1791                    ac.
update(slePseudoAccount);
 
 1795                    auto const mptId = assets.get<
MPTIssue>().getMptID();
 
 1799                    (*sleMPToken)[sfMPTAmount] =
 
 1800                        *(*sleMPToken)[sfMPTAmount] + *args.vaultAssets;
 
 1807            if (args.accountAssets)
 
 1809                auto const& pair = *args.accountAssets;
 
 1810                if (assets.native())
 
 1815                    (*sleAccount)[sfBalance] =
 
 1816                        *(*sleAccount)[sfBalance] + pair.amount;
 
 1821                    auto const mptID = assets.get<
MPTIssue>().getMptID();
 
 1826                    (*sleMPToken)[sfMPTAmount] =
 
 1827                        *(*sleMPToken)[sfMPTAmount] + pair.amount;
 
 1834            if (args.accountShares)
 
 1836                auto const& pair = *args.accountShares;
 
 1841                (*sleMPToken)[sfMPTAmount] =
 
 1842                    *(*sleMPToken)[sfMPTAmount] + pair.amount;
 
 1848        constexpr auto args =
 
 1849            [](
AccountID id, 
int adjustment, 
auto fn) -> Adjustments {
 
 1850            Adjustments sample = {
 
 1851                .assetsTotal = adjustment,
 
 1852                .assetsAvailable = adjustment,
 
 1853                .lossUnrealized = 0,
 
 1854                .sharesTotal = adjustment,
 
 1855                .vaultAssets = adjustment,
 
 1857                AccountAmount{id, -adjustment},
 
 1859                AccountAmount{id, adjustment}};
 
 1866        auto const precloseXrp =
 
 1868            env.fund(
XRP(1000), A3, A4);
 
 1871                vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 1874                {.depositor = A1, .id = keylet.key, .amount = XRP(10)}));
 
 1876                {.depositor = A2, .id = keylet.key, .amount = XRP(10)}));
 
 1878                {.depositor = A3, .id = keylet.key, .amount = XRP(10)}));
 
 1882        testcase << 
"Vault general checks";
 
 1884            {
"vault deletion succeeded without deleting a vault"},
 
 1887                auto sleVault = ac.view().
peek(keylet);
 
 1890                ac.view().
update(sleVault);
 
 1898                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 1904            {
"vault updated by a wrong transaction type"},
 
 1907                auto sleVault = ac.view().
peek(keylet);
 
 1910                ac.view().
erase(sleVault);
 
 1918                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 1924            {
"vault updated by a wrong transaction type"},
 
 1927                auto sleVault = ac.view().
peek(keylet);
 
 1930                ac.view().
update(sleVault);
 
 1938                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 1944            {
"vault updated by a wrong transaction type"},
 
 1946                auto const sequence = ac.view().
seq();
 
 1949                auto const vaultPage = ac.view().
dirInsert(
 
 1953                sleVault->setFieldU64(sfOwnerNode, *vaultPage);
 
 1954                ac.view().
insert(sleVault);
 
 1962            {
"vault deleted by a wrong transaction type"},
 
 1965                auto sleVault = ac.view().
peek(keylet);
 
 1968                ac.view().
erase(sleVault);
 
 1976                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 1982            {
"vault operation updated more than single vault"},
 
 1986                    auto sleVault = ac.view().
peek(keylet);
 
 1989                    ac.view().
erase(sleVault);
 
 1993                    auto sleVault = ac.view().
peek(keylet);
 
 1996                    ac.view().
erase(sleVault);
 
 2007                        vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2012                        vault.create({.owner = 
A2, .asset = 
xrpIssue()});
 
 2019            {
"vault operation updated more than single vault"},
 
 2021                auto const sequence = ac.view().
seq();
 
 2022                auto const insertVault = [&](
Account const A) {
 
 2025                    auto const vaultPage = ac.view().
dirInsert(
 
 2029                    sleVault->setFieldU64(sfOwnerNode, *vaultPage);
 
 2030                    ac.view().
insert(sleVault);
 
 2041            {
"deleted vault must also delete shares"},
 
 2044                auto sleVault = ac.view().
peek(keylet);
 
 2047                ac.view().
erase(sleVault);
 
 2055                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2061            {
"deleted vault must have no shares outstanding",
 
 2062             "deleted vault must have no assets outstanding",
 
 2063             "deleted vault must have no assets available"},
 
 2066                auto sleVault = ac.view().
peek(keylet);
 
 2069                auto sleShares = ac.view().
peek(
 
 2073                ac.view().
erase(sleVault);
 
 2074                ac.view().
erase(sleShares);
 
 2083                    vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2086                    {.depositor = A1, .id = keylet.key, .amount = XRP(10)}));
 
 2091            {
"vault operation succeeded without modifying a vault"},
 
 2094                auto sleVault = ac.view().
peek(keylet);
 
 2097                auto sleShares = ac.view().
peek(
 
 2103                sleShares->setFieldH256(sfDomainID, 
uint256(13));
 
 2104                ac.view().
update(sleShares);
 
 2114            {
"vault operation succeeded without modifying a vault"},
 
 2123                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2129            {
"vault operation succeeded without modifying a vault"},
 
 2138                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2144            {
"vault operation succeeded without modifying a vault"},
 
 2153                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2159            {
"vault operation succeeded without modifying a vault"},
 
 2168                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2174            {
"vault operation succeeded without modifying a vault"},
 
 2183                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2189            {
"updated vault must have shares"},
 
 2192                auto sleVault = ac.view().
peek(keylet);
 
 2195                (*sleVault)[sfAssetsMaximum] = 200;
 
 2196                ac.view().
update(sleVault);
 
 2198                auto sleShares = ac.view().
peek(
 
 2202                ac.view().
erase(sleShares);
 
 2210                auto [tx, _] = vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2216            {
"vault operation succeeded without updating shares",
 
 2217             "assets available must not be greater than assets outstanding"},
 
 2220                auto sleVault = ac.view().
peek(keylet);
 
 2223                (*sleVault)[sfAssetsTotal] = 9;
 
 2224                ac.view().
update(sleVault);
 
 2233                    vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2236                    {.depositor = A1, .id = keylet.key, .amount = XRP(10)}));
 
 2241            {
"set must not change assets outstanding",
 
 2242             "set must not change assets available",
 
 2243             "set must not change shares outstanding",
 
 2244             "set must not change vault balance",
 
 2245             "assets available must be positive",
 
 2246             "assets available must not be greater than assets outstanding",
 
 2247             "assets outstanding must be positive"},
 
 2250                auto sleVault = ac.view().
peek(keylet);
 
 2253                auto slePseudoAccount =
 
 2255                if (!slePseudoAccount)
 
 2257                (*slePseudoAccount)[sfBalance] =
 
 2258                    *(*slePseudoAccount)[sfBalance] - 10;
 
 2259                ac.view().
update(slePseudoAccount);
 
 2265                (*sleA4)[sfBalance] = *(*sleA4)[sfBalance] + 10;
 
 2271                    args(
A2.id(), 0, [&](Adjustments& sample) {
 
 2272                        sample.assetsAvailable = (DROPS_PER_XRP * -100).value();
 
 2273                        sample.assetsTotal = (DROPS_PER_XRP * -200).value();
 
 2274                        sample.sharesTotal = -1;
 
 2284            {
"violation of vault immutable data"},
 
 2287                auto sleVault = ac.view().
peek(keylet);
 
 2290                sleVault->setFieldIssue(
 
 2292                ac.view().
update(sleVault);
 
 2301            {
"violation of vault immutable data"},
 
 2304                auto sleVault = ac.view().
peek(keylet);
 
 2307                sleVault->setAccountID(sfAccount, 
A2.id());
 
 2308                ac.view().
update(sleVault);
 
 2317            {
"violation of vault immutable data"},
 
 2320                auto sleVault = ac.view().
peek(keylet);
 
 2323                (*sleVault)[sfShareMPTID] = 
MPTID(42);
 
 2324                ac.view().
update(sleVault);
 
 2333            {
"vault transaction must not change loss unrealized",
 
 2334             "set must not change assets outstanding"},
 
 2340                    args(
A2.id(), 0, [&](Adjustments& sample) {
 
 2341                        sample.lossUnrealized = 13;
 
 2342                        sample.assetsTotal = 20;
 
 2352            {
"loss unrealized must not exceed the difference " 
 2353             "between assets outstanding and available",
 
 2354             "vault transaction must not change loss unrealized"},
 
 2360                    args(
A2.id(), 100, [&](Adjustments& sample) {
 
 2361                        sample.lossUnrealized = 13;
 
 2375            {
"set assets outstanding must not exceed assets maximum"},
 
 2381                    args(
A2.id(), 0, [&](Adjustments& sample) {
 
 2382                        sample.assetsMaximum = 1;
 
 2392            {
"assets maximum must be positive"},
 
 2398                    args(
A2.id(), 0, [&](Adjustments& sample) {
 
 2399                        sample.assetsMaximum = -1;
 
 2409            {
"set must not change shares outstanding",
 
 2410             "updated zero sized vault must have no assets outstanding",
 
 2411             "updated zero sized vault must have no assets available"},
 
 2414                auto sleVault = ac.view().
peek(keylet);
 
 2417                ac.view().
update(sleVault);
 
 2418                auto sleShares = ac.view().
peek(
 
 2422                (*sleShares)[sfOutstandingAmount] = 0;
 
 2423                ac.view().
update(sleShares);
 
 2433            {
"updated shares must not exceed maximum"},
 
 2436                auto sleVault = ac.view().
peek(keylet);
 
 2439                auto sleShares = ac.view().
peek(
 
 2443                (*sleShares)[sfMaximumAmount] = 10;
 
 2444                ac.view().
update(sleShares);
 
 2447                    ac.view(), keylet, args(
A2.id(), 10, [](Adjustments&) {}));
 
 2456            {
"updated shares must not exceed maximum"},
 
 2460                    ac.view(), keylet, args(
A2.id(), 10, [](Adjustments&) {}));
 
 2462                auto sleVault = ac.view().
peek(keylet);
 
 2465                auto sleShares = ac.view().
peek(
 
 2470                ac.view().
update(sleShares);
 
 2482                "created vault must be empty",
 
 2483                "updated zero sized vault must have no assets outstanding",
 
 2484                "create operation must not have updated a vault",
 
 2488                auto sleVault = ac.view().
peek(keylet);
 
 2491                (*sleVault)[sfAssetsTotal] = 9;
 
 2492                ac.view().
update(sleVault);
 
 2501                    vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2508                "created vault must be empty",
 
 2509                "updated zero sized vault must have no assets available",
 
 2510                "assets available must not be greater than assets outstanding",
 
 2511                "create operation must not have updated a vault",
 
 2515                auto sleVault = ac.view().
peek(keylet);
 
 2518                (*sleVault)[sfAssetsAvailable] = 9;
 
 2519                ac.view().
update(sleVault);
 
 2528                    vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2535                "created vault must be empty",
 
 2536                "loss unrealized must not exceed the difference between assets " 
 2537                "outstanding and available",
 
 2538                "vault transaction must not change loss unrealized",
 
 2539                "create operation must not have updated a vault",
 
 2543                auto sleVault = ac.view().
peek(keylet);
 
 2546                (*sleVault)[sfLossUnrealized] = 1;
 
 2547                ac.view().
update(sleVault);
 
 2556                    vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2563                "created vault must be empty",
 
 2564                "create operation must not have updated a vault",
 
 2568                auto sleVault = ac.view().
peek(keylet);
 
 2571                auto sleShares = ac.view().
peek(
 
 2575                ac.view().
update(sleVault);
 
 2576                (*sleShares)[sfOutstandingAmount] = 9;
 
 2577                ac.view().
update(sleShares);
 
 2586                    vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2593                "assets maximum must be positive",
 
 2594                "create operation must not have updated a vault",
 
 2598                auto sleVault = ac.view().
peek(keylet);
 
 2601                (*sleVault)[sfAssetsMaximum] = 
Number(-1);
 
 2602                ac.view().
update(sleVault);
 
 2611                    vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2617            {
"create operation must not have updated a vault",
 
 2618             "shares issuer and vault pseudo-account must be the same",
 
 2619             "shares issuer must be a pseudo-account",
 
 2620             "shares issuer pseudo-account must point back to the vault"},
 
 2623                auto sleVault = ac.view().
peek(keylet);
 
 2626                auto sleShares = ac.view().
peek(
 
 2630                ac.view().
update(sleVault);
 
 2631                (*sleShares)[sfIssuer] = 
A1.id();
 
 2632                ac.view().
update(sleShares);
 
 2641                    vault.create({.owner = 
A1, .asset = 
xrpIssue()});
 
 2647            {
"vault created by a wrong transaction type",
 
 2648             "account root created illegally"},
 
 2653                auto const sequence = ac.view().
seq();
 
 2656                auto const vaultPage = ac.view().
dirInsert(
 
 2660                sleVault->setFieldU64(sfOwnerNode, *vaultPage);
 
 2667                sleAccount->setAccountID(sfAccount, pseudoId);
 
 2668                sleAccount->setFieldAmount(sfBalance, 
STAmount{});
 
 2673                sleAccount->setFieldU32(sfSequence, seqno);
 
 2674                sleAccount->setFieldU32(
 
 2677                sleAccount->setFieldH256(sfVaultID, vaultKeylet.key);
 
 2678                ac.view().
insert(sleAccount);
 
 2680                auto const sharesMptId = 
makeMptID(sequence, pseudoId);
 
 2683                auto const sharesPage = ac.view().
dirInsert(
 
 2687                sleShares->setFieldU64(sfOwnerNode, *sharesPage);
 
 2689                sleShares->at(sfFlags) = 0;
 
 2690                sleShares->at(sfIssuer) = pseudoId;
 
 2691                sleShares->at(sfOutstandingAmount) = 0;
 
 2692                sleShares->at(sfSequence) = sequence;
 
 2694                sleVault->at(sfAccount) = pseudoId;
 
 2695                sleVault->at(sfFlags) = 0;
 
 2696                sleVault->at(sfSequence) = sequence;
 
 2697                sleVault->at(sfOwner) = 
A1.id();
 
 2698                sleVault->at(sfAssetsTotal) = 
Number(0);
 
 2699                sleVault->at(sfAssetsAvailable) = 
Number(0);
 
 2700                sleVault->at(sfLossUnrealized) = 
Number(0);
 
 2701                sleVault->at(sfShareMPTID) = sharesMptId;
 
 2702                sleVault->at(sfWithdrawalPolicy) =
 
 2705                ac.view().
insert(sleVault);
 
 2706                ac.view().
insert(sleShares);
 
 2714            {
"shares issuer and vault pseudo-account must be the same",
 
 2715             "shares issuer pseudo-account must point back to the vault"},
 
 2717                auto const sequence = ac.view().
seq();
 
 2720                auto const vaultPage = ac.view().
dirInsert(
 
 2724                sleVault->setFieldU64(sfOwnerNode, *vaultPage);
 
 2731                sleAccount->setAccountID(sfAccount, pseudoId);
 
 2732                sleAccount->setFieldAmount(sfBalance, 
STAmount{});
 
 2737                sleAccount->setFieldU32(sfSequence, seqno);
 
 2738                sleAccount->setFieldU32(
 
 2743                sleAccount->setFieldH256(sfVaultID, 
uint256(42));
 
 2744                ac.view().
insert(sleAccount);
 
 2746                auto const sharesMptId = 
makeMptID(sequence, pseudoId);
 
 2749                auto const sharesPage = ac.view().
dirInsert(
 
 2753                sleShares->setFieldU64(sfOwnerNode, *sharesPage);
 
 2755                sleShares->at(sfFlags) = 0;
 
 2756                sleShares->at(sfIssuer) = pseudoId;
 
 2757                sleShares->at(sfOutstandingAmount) = 0;
 
 2758                sleShares->at(sfSequence) = sequence;
 
 2762                sleVault->at(sfAccount) = 
A2.id();
 
 2763                sleVault->at(sfFlags) = 0;
 
 2764                sleVault->at(sfSequence) = sequence;
 
 2765                sleVault->at(sfOwner) = 
A1.id();
 
 2766                sleVault->at(sfAssetsTotal) = 
Number(0);
 
 2767                sleVault->at(sfAssetsAvailable) = 
Number(0);
 
 2768                sleVault->at(sfLossUnrealized) = 
Number(0);
 
 2769                sleVault->at(sfShareMPTID) = sharesMptId;
 
 2770                sleVault->at(sfWithdrawalPolicy) =
 
 2773                ac.view().
insert(sleVault);
 
 2774                ac.view().
insert(sleShares);
 
 2782            {
"shares issuer and vault pseudo-account must be the same",
 
 2783             "shares issuer must exist"},
 
 2785                auto const sequence = ac.view().
seq();
 
 2788                auto const vaultPage = ac.view().
dirInsert(
 
 2792                sleVault->setFieldU64(sfOwnerNode, *vaultPage);
 
 2794                auto const sharesMptId = 
makeMptID(sequence, 
A2.id());
 
 2797                auto const sharesPage = ac.view().
dirInsert(
 
 2801                sleShares->setFieldU64(sfOwnerNode, *sharesPage);
 
 2803                sleShares->at(sfFlags) = 0;
 
 2806                sleShares->at(sfOutstandingAmount) = 0;
 
 2807                sleShares->at(sfSequence) = sequence;
 
 2809                sleVault->at(sfAccount) = 
A2.id();
 
 2810                sleVault->at(sfFlags) = 0;
 
 2811                sleVault->at(sfSequence) = sequence;
 
 2812                sleVault->at(sfOwner) = 
A1.id();
 
 2813                sleVault->at(sfAssetsTotal) = 
Number(0);
 
 2814                sleVault->at(sfAssetsAvailable) = 
Number(0);
 
 2815                sleVault->at(sfLossUnrealized) = 
Number(0);
 
 2816                sleVault->at(sfShareMPTID) = sharesMptId;
 
 2817                sleVault->at(sfWithdrawalPolicy) =
 
 2820                ac.view().
insert(sleVault);
 
 2821                ac.view().
insert(sleShares);
 
 2830            {
"deposit must change vault balance"},
 
 2836                    args(
A2.id(), 0, [](Adjustments& sample) {
 
 2837                        sample.vaultAssets.reset();
 
 2846            {
"deposit assets outstanding must not exceed assets maximum"},
 
 2852                    args(
A2.id(), 200, [&](Adjustments& sample) {
 
 2853                        sample.assetsMaximum = 1;
 
 2871            {
"deposit must increase vault balance",
 
 2872             "deposit must change depositor balance"},
 
 2880                (*sleA4)[sfBalance] = *(*sleA4)[sfBalance] + 10;
 
 2886                    args(A3.id(), -10, [&](Adjustments& sample) {
 
 2887                        sample.accountAssets->amount = -100;
 
 2895                    tx[sfAccount] = A3.id();
 
 2901            {
"deposit must increase vault balance",
 
 2902             "deposit must decrease depositor balance",
 
 2903             "deposit must change vault and depositor balance by equal amount",
 
 2904             "deposit and assets outstanding must add up",
 
 2905             "deposit and assets available must add up"},
 
 2913                (*sleA3)[sfBalance] = *(*sleA3)[sfBalance] + 10;
 
 2919                    args(
A2.id(), 10, [&](Adjustments& sample) {
 
 2920                        sample.vaultAssets = -20;
 
 2921                        sample.accountAssets->amount = 10;
 
 2933            {
"deposit must change depositor balance"},
 
 2941                (*sleA3)[sfBalance] = *(*sleA3)[sfBalance] - 10;
 
 2947                    args(
A2.id(), 10, [&](Adjustments& sample) {
 
 2948                        sample.accountAssets->amount = 0;
 
 2960            {
"deposit must change depositor shares"},
 
 2966                    args(
A2.id(), 10, [&](Adjustments& sample) {
 
 2967                        sample.accountShares.reset();
 
 2979            {
"deposit must change vault shares"},
 
 2986                    args(
A2.id(), 10, [](Adjustments& sample) {
 
 2987                        sample.sharesTotal = 0;
 
 2999            {
"deposit must increase depositor shares",
 
 3000             "deposit must change depositor and vault shares by equal amount",
 
 3001             "deposit must not change vault balance by more than deposited " 
 3008                    args(
A2.id(), 10, [&](Adjustments& sample) {
 
 3009                        sample.accountShares->amount = -5;
 
 3010                        sample.sharesTotal = -10;
 
 3022            {
"deposit and assets outstanding must add up"},
 
 3025                (*sleA3)[sfBalance] = *(*sleA3)[sfBalance] - 2000;
 
 3032                    args(
A2.id(), 10, [&](Adjustments& sample) {
 
 3033                        sample.assetsTotal = 11;
 
 3041                    tx[sfDelegate] = A3.id();
 
 3049            {
"deposit and assets outstanding must add up",
 
 3050             "deposit and assets available must add up"},
 
 3056                    args(
A2.id(), 10, [&](Adjustments& sample) {
 
 3057                        sample.assetsTotal = 7;
 
 3058                        sample.assetsAvailable = 7;
 
 3071            {
"withdrawal must change vault balance"},
 
 3077                    args(
A2.id(), 0, [](Adjustments& sample) {
 
 3078                        sample.vaultAssets.reset();
 
 3091            {
"withdrawal must change one destination balance"},
 
 3099                (*sleA4)[sfBalance] = *(*sleA4)[sfBalance] + 10;
 
 3105                    args(A3.id(), -10, [&](Adjustments& sample) {
 
 3106                        sample.accountAssets->amount = -100;
 
 3114                    tx[sfAccount] = A3.id();
 
 3122            {
"withdrawal must change vault and destination balance by " 
 3124             "withdrawal must decrease vault balance",
 
 3125             "withdrawal must increase destination balance",
 
 3126             "withdrawal and assets outstanding must add up",
 
 3127             "withdrawal and assets available must add up"},
 
 3135                (*sleA3)[sfBalance] = *(*sleA3)[sfBalance] + 10;
 
 3141                    args(
A2.id(), -10, [&](Adjustments& sample) {
 
 3142                        sample.vaultAssets = 10;
 
 3143                        sample.accountAssets->amount = -20;
 
 3153            {
"withdrawal must change one destination balance"},
 
 3159                        args(
A2.id(), -10, [&](Adjustments& sample) {
 
 3160                            *sample.vaultAssets -= 5;
 
 3166                (*sleA3)[sfBalance] = *(*sleA3)[sfBalance] + 5;
 
 3179            {
"withdrawal must change depositor shares"},
 
 3185                    args(
A2.id(), -10, [&](Adjustments& sample) {
 
 3186                        sample.accountShares.reset();
 
 3196            {
"withdrawal must change vault shares"},
 
 3202                    args(
A2.id(), -10, [](Adjustments& sample) {
 
 3203                        sample.sharesTotal = 0;
 
 3213            {
"withdrawal must decrease depositor shares",
 
 3214             "withdrawal must change depositor and vault shares by equal " 
 3221                    args(
A2.id(), -10, [&](Adjustments& sample) {
 
 3222                        sample.accountShares->amount = 5;
 
 3223                        sample.sharesTotal = 10;
 
 3233            {
"withdrawal and assets outstanding must add up",
 
 3234             "withdrawal and assets available must add up"},
 
 3240                    args(
A2.id(), -10, [&](Adjustments& sample) {
 
 3241                        sample.assetsTotal = -15;
 
 3242                        sample.assetsAvailable = -15;
 
 3252            {
"withdrawal and assets outstanding must add up"},
 
 3255                (*sleA3)[sfBalance] = *(*sleA3)[sfBalance] - 2000;
 
 3262                    args(
A2.id(), -10, [&](Adjustments& sample) {
 
 3263                        sample.assetsTotal = -7;
 
 3271                    tx[sfDelegate] = A3.id();
 
 3278        auto const precloseMpt =
 
 3280            env.fund(
XRP(1000), A3, A4);
 
 3285                jv[sfAccount] = A3.human();
 
 3286                jv[sfTransactionType] = jss::MPTokenIssuanceCreate;
 
 3292            auto const mptID = 
makeMptID(env.seq(A3) - 1, A3);
 
 3297                jv[sfAccount] = 
A1.human();
 
 3298                jv[sfTransactionType] = jss::MPTokenAuthorize;
 
 3299                jv[sfMPTokenIssuanceID] = 
to_string(mptID);
 
 3301                jv[sfAccount] = 
A2.human();
 
 3303                jv[sfAccount] = A4.human();
 
 3310                env(
pay(A3, 
A1, asset(1000)));
 
 3311                env(
pay(A3, 
A2, asset(1000)));
 
 3312                env(
pay(A3, A4, asset(1000)));
 
 3317            auto [tx, keylet] = vault.create({.owner = 
A1, .asset = asset});
 
 3320                {.depositor = A1, .id = keylet.key, .amount = asset(10)}));
 
 3322                {.depositor = A2, .id = keylet.key, .amount = asset(10)}));
 
 3324                {.depositor = A4, .id = keylet.key, .amount = asset(10)}));
 
 3329            {
"withdrawal must decrease depositor shares",
 
 3330             "withdrawal must change depositor and vault shares by equal " 
 3337                    args(
A2.id(), -10, [&](Adjustments& sample) {
 
 3338                        sample.accountShares->amount = 5;
 
 3344                [&](
STObject& tx) { tx[sfAccount] = A3.id(); }},
 
 3351            {
"clawback must change vault balance"},
 
 3357                    args(
A2.id(), -1, [&](Adjustments& sample) {
 
 3358                        sample.vaultAssets.reset();
 
 3364                [&](
STObject& tx) { tx[sfAccount] = A3.id(); }},
 
 3370            {
"clawback may only be performed by the asset issuer"},
 
 3376                    args(
A2.id(), 0, [&](Adjustments& sample) {}));
 
 3385            {
"clawback may only be performed by the asset issuer"},
 
 3391                    args(
A2.id(), 0, [&](Adjustments& sample) {}));
 
 3396                [&](
STObject& tx) { tx[sfAccount] = A4.id(); }},
 
 3401            {
"clawback must decrease vault balance",
 
 3402             "clawback must decrease holder shares",
 
 3403             "clawback must change vault shares"},
 
 3409                    args(A4.id(), 10, [&](Adjustments& sample) {
 
 3410                        sample.sharesTotal = 0;
 
 3417                    tx[sfAccount] = A3.id();
 
 3418                    tx[sfHolder] = A4.id();
 
 3424            {
"clawback must change holder shares"},
 
 3430                    args(A4.id(), -10, [&](Adjustments& sample) {
 
 3431                        sample.accountShares.reset();
 
 3438                    tx[sfAccount] = A3.id();
 
 3439                    tx[sfHolder] = A4.id();
 
 3445            {
"clawback must change holder and vault shares by equal amount",
 
 3446             "clawback and assets outstanding must add up",
 
 3447             "clawback and assets available must add up"},
 
 3453                    args(A4.id(), -10, [&](Adjustments& sample) {
 
 3454                        sample.accountShares->amount = -8;
 
 3455                        sample.assetsTotal = -7;
 
 3456                        sample.assetsAvailable = -7;
 
 3463                    tx[sfAccount] = A3.id();
 
 3464                    tx[sfHolder] = A4.id();