diff --git a/src/ripple/app/tx/impl/NFTokenAcceptOffer.cpp b/src/ripple/app/tx/impl/NFTokenAcceptOffer.cpp index c420bfc6197..61aa7e0629a 100644 --- a/src/ripple/app/tx/impl/NFTokenAcceptOffer.cpp +++ b/src/ripple/app/tx/impl/NFTokenAcceptOffer.cpp @@ -109,7 +109,7 @@ NFTokenAcceptOffer::preclaim(PreclaimContext const& ctx) // The two offers may not form a loop. A broker may not sell the // token to the current owner of the token. - if (ctx.view.rules().enabled(fixUnburnableNFToken) && + if (ctx.view.rules().enabled(fixNonFungibleTokensV1_2) && ((*bo)[sfOwner] == (*so)[sfOwner])) return tecCANT_ACCEPT_OWN_NFTOKEN_OFFER; @@ -121,37 +121,29 @@ NFTokenAcceptOffer::preclaim(PreclaimContext const& ctx) // If the buyer specified a destination if (auto const dest = bo->at(~sfDestination)) { - // fixUnburnableNFToken - if (ctx.view.rules().enabled(fixUnburnableNFToken)) + // Before this fix the destination could be either the seller or + // a broker. After, it must be whoever is submitting the tx. + if (ctx.view.rules().enabled(fixNonFungibleTokensV1_2)) { - // the destination may only be the account brokering the offer if (*dest != ctx.tx[sfAccount]) return tecNO_PERMISSION; } - else - { - // the destination must be the seller or the broker. - if (*dest != so->at(sfOwner) && *dest != ctx.tx[sfAccount]) - return tecNFTOKEN_BUY_SELL_MISMATCH; - } + else if (*dest != so->at(sfOwner) && *dest != ctx.tx[sfAccount]) + return tecNFTOKEN_BUY_SELL_MISMATCH; } // If the seller specified a destination if (auto const dest = so->at(~sfDestination)) { - // fixUnburnableNFToken - if (ctx.view.rules().enabled(fixUnburnableNFToken)) + // Before this fix the destination could be either the seller or + // a broker. After, it must be whoever is submitting the tx. + if (ctx.view.rules().enabled(fixNonFungibleTokensV1_2)) { - // the destination may only be the account brokering the offer if (*dest != ctx.tx[sfAccount]) return tecNO_PERMISSION; } - else - { - // the destination must be the buyer or the broker. - if (*dest != bo->at(sfOwner) && *dest != ctx.tx[sfAccount]) - return tecNFTOKEN_BUY_SELL_MISMATCH; - } + else if (*dest != bo->at(sfOwner) && *dest != ctx.tx[sfAccount]) + return tecNFTOKEN_BUY_SELL_MISMATCH; } // The broker can specify an amount that represents their cut; if they @@ -200,7 +192,7 @@ NFTokenAcceptOffer::preclaim(PreclaimContext const& ctx) // After this amendment, we allow an IOU issuer to buy an NFT with their // own currency auto const needed = bo->at(sfAmount); - if (ctx.view.rules().enabled(fixUnburnableNFToken)) + if (ctx.view.rules().enabled(fixNonFungibleTokensV1_2)) { if (accountFunds( ctx.view, (*bo)[sfOwner], needed, fhZERO_IF_FROZEN, ctx.j) < @@ -243,7 +235,7 @@ NFTokenAcceptOffer::preclaim(PreclaimContext const& ctx) // The account offering to buy must have funds: auto const needed = so->at(sfAmount); - if (!ctx.view.rules().enabled(fixUnburnableNFToken)) + if (!ctx.view.rules().enabled(fixNonFungibleTokensV1_2)) { if (accountHolds( ctx.view, @@ -298,7 +290,7 @@ NFTokenAcceptOffer::pay( // their own currency, we know that something went wrong. This was // originally found in the context of IOU transfer fees. Since there are // several payouts in this tx, just confirm that the end state is OK. - if (!view().rules().enabled(fixUnburnableNFToken)) + if (!view().rules().enabled(fixNonFungibleTokensV1_2)) return result; if (result != tesSUCCESS) return result; diff --git a/src/ripple/app/tx/impl/NFTokenBurn.cpp b/src/ripple/app/tx/impl/NFTokenBurn.cpp index e8693c7c6fb..99acfd61dca 100644 --- a/src/ripple/app/tx/impl/NFTokenBurn.cpp +++ b/src/ripple/app/tx/impl/NFTokenBurn.cpp @@ -77,7 +77,7 @@ NFTokenBurn::preclaim(PreclaimContext const& ctx) } } - if (!ctx.view.rules().enabled(fixUnburnableNFToken)) + if (!ctx.view.rules().enabled(fixNonFungibleTokensV1_2)) { // If there are too many offers, then burning the token would produce // too much metadata. Disallow burning a token with too many offers. @@ -109,7 +109,7 @@ NFTokenBurn::doApply() view().update(issuer); } - if (ctx_.view().rules().enabled(fixUnburnableNFToken)) + if (ctx_.view().rules().enabled(fixNonFungibleTokensV1_2)) { // Delete up to 500 offers in total. // Because the number of sell offers is likely to be less than diff --git a/src/ripple/app/tx/impl/NFTokenCreateOffer.cpp b/src/ripple/app/tx/impl/NFTokenCreateOffer.cpp index ff8668e4488..6db31c69892 100644 --- a/src/ripple/app/tx/impl/NFTokenCreateOffer.cpp +++ b/src/ripple/app/tx/impl/NFTokenCreateOffer.cpp @@ -155,7 +155,7 @@ NFTokenCreateOffer::preclaim(PreclaimContext const& ctx) { // After this amendment, we allow an IOU issuer to make a buy offer // using their own currency. - if (ctx.view.rules().enabled(fixUnburnableNFToken)) + if (ctx.view.rules().enabled(fixNonFungibleTokensV1_2)) { if (accountFunds( ctx.view, diff --git a/src/ripple/protocol/Feature.h b/src/ripple/protocol/Feature.h index 0bdfd224dda..d53d992d242 100644 --- a/src/ripple/protocol/Feature.h +++ b/src/ripple/protocol/Feature.h @@ -343,7 +343,7 @@ extern uint256 const featureImmediateOfferKilled; extern uint256 const featureDisallowIncoming; extern uint256 const featureXRPFees; extern uint256 const fixUniversalNumber; -extern uint256 const fixUnburnableNFToken; +extern uint256 const fixNonFungibleTokensV1_2; } // namespace ripple diff --git a/src/ripple/protocol/impl/Feature.cpp b/src/ripple/protocol/impl/Feature.cpp index f021ea4674d..4fb79e4cc48 100644 --- a/src/ripple/protocol/impl/Feature.cpp +++ b/src/ripple/protocol/impl/Feature.cpp @@ -453,7 +453,7 @@ REGISTER_FEATURE(ImmediateOfferKilled, Supported::yes, DefaultVote::no) REGISTER_FEATURE(DisallowIncoming, Supported::yes, DefaultVote::no); REGISTER_FEATURE(XRPFees, Supported::yes, DefaultVote::no); REGISTER_FIX (fixUniversalNumber, Supported::yes, DefaultVote::no); -REGISTER_FIX (fixUnburnableNFToken, Supported::yes, DefaultVote::no); +REGISTER_FIX (fixNonFungibleTokensV1_2, Supported::yes, DefaultVote::no); // The following amendments have been active for at least two years. Their // pre-amendment code has been removed and the identifiers are deprecated. diff --git a/src/test/app/NFTokenBurn_test.cpp b/src/test/app/NFTokenBurn_test.cpp index 4896932acd2..096fd5ce1e8 100644 --- a/src/test/app/NFTokenBurn_test.cpp +++ b/src/test/app/NFTokenBurn_test.cpp @@ -524,8 +524,8 @@ class NFTokenBurn_test : public beast::unit_test::suite using namespace test::jtx; // Test what happens if a NFT is unburnable when there are - // more than 500 offers, before fixUnburnableNFToken goes live - if (!features[fixUnburnableNFToken]) + // more than 500 offers, before fixNonFungibleTokensV1_2 goes live + if (!features[fixNonFungibleTokensV1_2]) { Env env{*this, features}; @@ -620,10 +620,10 @@ class NFTokenBurn_test : public beast::unit_test::suite } // Test that up to 499 buy/sell offers will be removed when NFT is - // burned after fixUnburnableNFToken is enabled. This is to test that we - // can successfully remove all offers if the number of offers is less - // than 500. - if (features[fixUnburnableNFToken]) + // burned after fixNonFungibleTokensV1_2 is enabled. This is to test + // that we can successfully remove all offers if the number of offers is + // less than 500. + if (features[fixNonFungibleTokensV1_2]) { Env env{*this, features}; @@ -673,8 +673,8 @@ class NFTokenBurn_test : public beast::unit_test::suite } // Test that up to 500 buy offers are removed when NFT is burned - // after fixUnburnableNFToken is enabled - if (features[fixUnburnableNFToken]) + // after fixNonFungibleTokensV1_2 is enabled + if (features[fixNonFungibleTokensV1_2]) { Env env{*this, features}; @@ -718,8 +718,8 @@ class NFTokenBurn_test : public beast::unit_test::suite } // Test that up to 500 buy/sell offers are removed when NFT is burned - // after fixUnburnableNFToken is enabled - if (features[fixUnburnableNFToken]) + // after fixNonFungibleTokensV1_2 is enabled + if (features[fixNonFungibleTokensV1_2]) { Env env{*this, features}; @@ -786,8 +786,8 @@ class NFTokenBurn_test : public beast::unit_test::suite FeatureBitset const all{supported_amendments()}; FeatureBitset const fixNFTDir{fixNFTokenDirV1}; - testWithFeats(all - fixUnburnableNFToken - fixNFTDir); - testWithFeats(all - fixUnburnableNFToken); + testWithFeats(all - fixNonFungibleTokensV1_2 - fixNFTDir); + testWithFeats(all - fixNonFungibleTokensV1_2); testWithFeats(all); } }; diff --git a/src/test/app/NFToken_test.cpp b/src/test/app/NFToken_test.cpp index d581a6d0d90..40202e07dce 100644 --- a/src/test/app/NFToken_test.cpp +++ b/src/test/app/NFToken_test.cpp @@ -2881,7 +2881,7 @@ class NFToken_test : public beast::unit_test::suite { // issuer cannot broker the offers, because they are not the // Destination. - TER const expectTer = features[fixUnburnableNFToken] + TER const expectTer = features[fixNonFungibleTokensV1_2] ? tecNO_PERMISSION : tecNFTOKEN_BUY_SELL_MISMATCH; env(token::brokerOffers( @@ -2931,7 +2931,7 @@ class NFToken_test : public beast::unit_test::suite { // Cannot broker offers when the sell destination is not the // buyer. - TER const expectTer = features[fixUnburnableNFToken] + TER const expectTer = features[fixNonFungibleTokensV1_2] ? tecNO_PERMISSION : tecNFTOKEN_BUY_SELL_MISMATCH; env(token::brokerOffers( @@ -2945,7 +2945,7 @@ class NFToken_test : public beast::unit_test::suite // amendment switch: When enabled the broker fails, when // disabled the broker succeeds if the destination is the buyer. - TER const eexpectTer = features[fixUnburnableNFToken] + TER const eexpectTer = features[fixNonFungibleTokensV1_2] ? tecNO_PERMISSION : TER(tesSUCCESS); env(token::brokerOffers( @@ -2953,7 +2953,7 @@ class NFToken_test : public beast::unit_test::suite ter(eexpectTer)); env.close(); - if (features[fixUnburnableNFToken]) + if (features[fixNonFungibleTokensV1_2]) // Buyer is successful with acceptOffer. env(token::acceptBuyOffer(buyer, offerMinterToBuyer)); env.close(); @@ -2994,7 +2994,7 @@ class NFToken_test : public beast::unit_test::suite { // Cannot broker offers when the sell destination is not the // buyer or the broker. - TER const expectTer = features[fixUnburnableNFToken] + TER const expectTer = features[fixNonFungibleTokensV1_2] ? tecNO_PERMISSION : tecNFTOKEN_BUY_SELL_MISMATCH; env(token::brokerOffers( @@ -3861,7 +3861,8 @@ class NFToken_test : public beast::unit_test::suite using namespace test::jtx; for (auto const& tweakedFeatures : - {features - fixUnburnableNFToken, features | fixUnburnableNFToken}) + {features - fixNonFungibleTokensV1_2, + features | fixNonFungibleTokensV1_2}) { Env env{*this, tweakedFeatures}; @@ -4400,7 +4401,7 @@ class NFToken_test : public beast::unit_test::suite token::owner(minter)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) { env(token::brokerOffers( broker, buyOfferIndex, minterOfferIndex), @@ -4946,12 +4947,12 @@ class NFToken_test : public beast::unit_test::suite IOU const gwXAU(gw["XAU"]); // Test both with and without fixNFTokenNegOffer and - // fixUnburnableNFToken. Need to turn off fixUnburnableNFToken as well - // because that amendment came later and addressed the acceptance - // side of this issue. + // fixNonFungibleTokensV1_2. Need to turn off fixNonFungibleTokensV1_2 + // as well because that amendment came later and addressed the + // acceptance side of this issue. for (auto const& tweakedFeatures : {features - fixNFTokenNegOffer - featureNonFungibleTokensV1_1 - - fixUnburnableNFToken, + fixNonFungibleTokensV1_2, features - fixNFTokenNegOffer - featureNonFungibleTokensV1_1, features | fixNFTokenNegOffer}) { @@ -5042,7 +5043,7 @@ class NFToken_test : public beast::unit_test::suite } { // 1. If fixNFTokenNegOffer is enabled get tecOBJECT_NOT_FOUND - // 2. If it is not enabled, but fixUnburnableNFToken is + // 2. If it is not enabled, but fixNonFungibleTokensV1_2 is // enabled, get tecOBJECT_NOT_FOUND. // 3. If neither are enabled, get tesSUCCESS. TER const offerAcceptTER = tweakedFeatures[fixNFTokenNegOffer] @@ -5184,7 +5185,8 @@ class NFToken_test : public beast::unit_test::suite testcase("Payments with IOU transfer fees"); for (auto const& tweakedFeatures : - {features - fixUnburnableNFToken, features | fixUnburnableNFToken}) + {features - fixNonFungibleTokensV1_2, + features | fixNonFungibleTokensV1_2}) { Env env{*this, tweakedFeatures}; @@ -5336,13 +5338,13 @@ class NFToken_test : public beast::unit_test::suite auto const nftID = mintNFT(minter); auto const offerID = createSellOffer(minter, nftID, gwXAU(1000)); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tecINSUFFICIENT_FUNDS) : static_cast(tesSUCCESS); env(token::acceptSellOffer(buyer, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) expectInitialState(); else { @@ -5360,13 +5362,13 @@ class NFToken_test : public beast::unit_test::suite auto const nftID = mintNFT(minter); auto const offerID = createBuyOffer(buyer, minter, nftID, gwXAU(1000)); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tecINSUFFICIENT_FUNDS) : static_cast(tesSUCCESS); env(token::acceptBuyOffer(minter, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) expectInitialState(); else { @@ -5384,13 +5386,13 @@ class NFToken_test : public beast::unit_test::suite reinitializeTrustLineBalances(); auto const nftID = mintNFT(minter); auto const offerID = createSellOffer(minter, nftID, gwXAU(995)); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tecINSUFFICIENT_FUNDS) : static_cast(tesSUCCESS); env(token::acceptSellOffer(buyer, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) expectInitialState(); else { @@ -5408,13 +5410,13 @@ class NFToken_test : public beast::unit_test::suite auto const nftID = mintNFT(minter); auto const offerID = createBuyOffer(buyer, minter, nftID, gwXAU(995)); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tecINSUFFICIENT_FUNDS) : static_cast(tesSUCCESS); env(token::acceptBuyOffer(minter, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) expectInitialState(); else { @@ -5509,13 +5511,13 @@ class NFToken_test : public beast::unit_test::suite auto const nftID = mintNFT(minter); auto const offerID = createSellOffer(minter, nftID, gwXAU(1000)); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tesSUCCESS) : static_cast(tecINSUFFICIENT_FUNDS); env(token::acceptSellOffer(gw, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) { BEAST_EXPECT(env.balance(minter, gwXAU) == gwXAU(1000)); BEAST_EXPECT( @@ -5530,18 +5532,18 @@ class NFToken_test : public beast::unit_test::suite reinitializeTrustLineBalances(); auto const nftID = mintNFT(minter); - auto const offerTER = tweakedFeatures[fixUnburnableNFToken] + auto const offerTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tesSUCCESS) : static_cast(tecUNFUNDED_OFFER); auto const offerID = createBuyOffer(gw, minter, nftID, gwXAU(1000), {offerTER}); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tesSUCCESS) : static_cast(tecOBJECT_NOT_FOUND); env(token::acceptBuyOffer(minter, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) { BEAST_EXPECT(env.balance(minter, gwXAU) == gwXAU(1000)); BEAST_EXPECT( @@ -5557,13 +5559,13 @@ class NFToken_test : public beast::unit_test::suite auto const nftID = mintNFT(minter); auto const offerID = createSellOffer(minter, nftID, gwXAU(5000)); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tesSUCCESS) : static_cast(tecINSUFFICIENT_FUNDS); env(token::acceptSellOffer(gw, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) { BEAST_EXPECT(env.balance(minter, gwXAU) == gwXAU(5000)); BEAST_EXPECT( @@ -5578,18 +5580,18 @@ class NFToken_test : public beast::unit_test::suite reinitializeTrustLineBalances(); auto const nftID = mintNFT(minter); - auto const offerTER = tweakedFeatures[fixUnburnableNFToken] + auto const offerTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tesSUCCESS) : static_cast(tecUNFUNDED_OFFER); auto const offerID = createBuyOffer(gw, minter, nftID, gwXAU(5000), {offerTER}); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tesSUCCESS) : static_cast(tecOBJECT_NOT_FOUND); env(token::acceptBuyOffer(minter, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) { BEAST_EXPECT(env.balance(minter, gwXAU) == gwXAU(5000)); BEAST_EXPECT( @@ -5731,13 +5733,13 @@ class NFToken_test : public beast::unit_test::suite // now we can do a secondary sale auto const offerID = createSellOffer(secondarySeller, nftID, gwXAU(1000)); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tecINSUFFICIENT_FUNDS) : static_cast(tesSUCCESS); env(token::acceptSellOffer(buyer, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) expectInitialState(); else { @@ -5767,14 +5769,14 @@ class NFToken_test : public beast::unit_test::suite // now we can do a secondary sale auto const offerID = createBuyOffer(buyer, secondarySeller, nftID, gwXAU(1000)); - auto const sellTER = tweakedFeatures[fixUnburnableNFToken] + auto const sellTER = tweakedFeatures[fixNonFungibleTokensV1_2] ? static_cast(tecINSUFFICIENT_FUNDS) : static_cast(tesSUCCESS); env(token::acceptBuyOffer(secondarySeller, offerID), ter(sellTER)); env.close(); - if (tweakedFeatures[fixUnburnableNFToken]) + if (tweakedFeatures[fixNonFungibleTokensV1_2]) expectInitialState(); else { @@ -5940,7 +5942,7 @@ class NFToken_test : public beast::unit_test::suite // the NFToken being bought and returned to the original owner and // the broker pocketing the profit. // - // This unit test verifies that the fixUnburnableNFToken amendment + // This unit test verifies that the fixNonFungibleTokensV1_2 amendment // fixes that bug. testcase("Brokered sale to self"); @@ -6006,7 +6008,7 @@ class NFToken_test : public beast::unit_test::suite BEAST_EXPECT(nftCount(env, bob) == 1); auto const bobsPriorBalance = env.balance(bob); auto const brokersPriorBalance = env.balance(broker); - TER expectTer = features[fixUnburnableNFToken] + TER expectTer = features[fixNonFungibleTokensV1_2] ? TER(tecCANT_ACCEPT_OWN_NFTOKEN_OFFER) : TER(tesSUCCESS); env(token::brokerOffers(broker, bobBuyOfferIndex, bobSellOfferIndex), @@ -6077,13 +6079,13 @@ class NFToken_test : public beast::unit_test::suite FeatureBitset const all{supported_amendments()}; FeatureBitset const fixNFTDir{fixNFTokenDirV1}; - testWithFeats(all - fixNFTDir - fixUnburnableNFToken); - testWithFeats(all - disallowIncoming - fixUnburnableNFToken); - testWithFeats(all - fixUnburnableNFToken); + testWithFeats(all - fixNFTDir - fixNonFungibleTokensV1_2); + testWithFeats(all - disallowIncoming - fixNonFungibleTokensV1_2); + testWithFeats(all - fixNonFungibleTokensV1_2); testWithFeats(all); } }; BEAST_DEFINE_TESTSUITE_PRIO(NFToken, tx, ripple, 2); -} // namespace ripple \ No newline at end of file +} // namespace ripple