|
48 | 48 | import static com.hedera.services.bdd.spec.transactions.token.TokenMovement.movingUnique;
|
49 | 49 | import static com.hedera.services.bdd.spec.transactions.token.TokenMovement.movingUniqueWithAllowance;
|
50 | 50 | import static com.hedera.services.bdd.spec.transactions.token.TokenMovement.movingWithAllowance;
|
| 51 | +import static com.hedera.services.bdd.spec.utilops.UtilVerbs.emptyChildRecordsCheck; |
51 | 52 | import static com.hedera.services.bdd.spec.utilops.UtilVerbs.newKeyNamed;
|
52 | 53 | import static com.hedera.services.bdd.spec.utilops.UtilVerbs.sourcing;
|
53 | 54 | import static com.hedera.services.bdd.spec.utilops.UtilVerbs.validateChargedUsdWithin;
|
|
67 | 68 | import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.NFT_IN_FUNGIBLE_TOKEN_ALLOWANCES;
|
68 | 69 | import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.PAYER_ACCOUNT_NOT_FOUND;
|
69 | 70 | import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.SENDER_DOES_NOT_OWN_NFT_SERIAL_NO;
|
| 71 | +import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.SPENDER_ACCOUNT_SAME_AS_OWNER; |
70 | 72 | import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.SPENDER_DOES_NOT_HAVE_ALLOWANCE;
|
| 73 | +import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.SUCCESS; |
71 | 74 | import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.TOKEN_NOT_ASSOCIATED_TO_ACCOUNT;
|
72 | 75 | import static com.hederahashgraph.api.proto.java.TokenType.FUNGIBLE_COMMON;
|
73 | 76 | import static com.hederahashgraph.api.proto.java.TokenType.NON_FUNGIBLE_UNIQUE;
|
@@ -156,7 +159,8 @@ public List<HapiSpec> getSpecsInSuite() {
|
156 | 159 | scheduledCryptoApproveAllowanceWorks(),
|
157 | 160 | canDeleteAllowanceFromDeletedSpender(),
|
158 | 161 | cannotPayForAnyTransactionWithContractAccount(),
|
159 |
| - transferringMissingNftViaApprovalFailsWithInvalidNftId()); |
| 162 | + transferringMissingNftViaApprovalFailsWithInvalidNftId(), |
| 163 | + approveNegativeCases()); |
160 | 164 | }
|
161 | 165 |
|
162 | 166 | @HapiTest
|
@@ -1678,6 +1682,81 @@ final HapiSpec scheduledCryptoApproveAllowanceWorks() {
|
1678 | 1682 | getAccountBalance(RECEIVER).hasTinyBars(15 * ONE_HBAR));
|
1679 | 1683 | }
|
1680 | 1684 |
|
| 1685 | + @HapiTest |
| 1686 | + final HapiSpec approveNegativeCases() { |
| 1687 | + final var tryApprovingTheSender = "tryApprovingTheSender"; |
| 1688 | + final var tryApprovingAboveBalance = "tryApprovingAboveBalance"; |
| 1689 | + final var tryApprovingNFTToOwner = "tryApprovingNFTToOwner"; |
| 1690 | + final var tryApprovingNFTWithInvalidSerial = "tryApprovingNFTWithInvalidSerial"; |
| 1691 | + return defaultHapiSpec("approveNegativeCases") |
| 1692 | + .given( |
| 1693 | + newKeyNamed(SUPPLY_KEY), |
| 1694 | + cryptoCreate(OWNER).balance(ONE_HUNDRED_HBARS).maxAutomaticTokenAssociations(10), |
| 1695 | + cryptoCreate(SPENDER).balance(ONE_HUNDRED_HBARS), |
| 1696 | + cryptoCreate(TOKEN_TREASURY) |
| 1697 | + .balance(100 * ONE_HUNDRED_HBARS) |
| 1698 | + .maxAutomaticTokenAssociations(10), |
| 1699 | + tokenCreate(FUNGIBLE_TOKEN) |
| 1700 | + .supplyType(TokenSupplyType.FINITE) |
| 1701 | + .tokenType(FUNGIBLE_COMMON) |
| 1702 | + .supplyKey(SUPPLY_KEY) |
| 1703 | + .treasury(TOKEN_TREASURY) |
| 1704 | + .maxSupply(10000) |
| 1705 | + .initialSupply(5000), |
| 1706 | + tokenCreate(NON_FUNGIBLE_TOKEN) |
| 1707 | + .supplyType(TokenSupplyType.FINITE) |
| 1708 | + .tokenType(NON_FUNGIBLE_UNIQUE) |
| 1709 | + .treasury(TOKEN_TREASURY) |
| 1710 | + .maxSupply(12L) |
| 1711 | + .supplyKey(SUPPLY_KEY) |
| 1712 | + .initialSupply(0L), |
| 1713 | + mintToken(FUNGIBLE_TOKEN, 500L).via(FUNGIBLE_TOKEN_MINT_TXN), |
| 1714 | + mintToken( |
| 1715 | + NON_FUNGIBLE_TOKEN, |
| 1716 | + List.of( |
| 1717 | + ByteString.copyFromUtf8("1"), |
| 1718 | + ByteString.copyFromUtf8("2"), |
| 1719 | + ByteString.copyFromUtf8("3"))), |
| 1720 | + tokenAssociate(OWNER, FUNGIBLE_TOKEN, NON_FUNGIBLE_TOKEN), |
| 1721 | + cryptoTransfer( |
| 1722 | + moving(500L, FUNGIBLE_TOKEN).between(TOKEN_TREASURY, OWNER), |
| 1723 | + movingUnique(NON_FUNGIBLE_TOKEN, 1L, 2L, 3L).between(TOKEN_TREASURY, OWNER))) |
| 1724 | + .when( |
| 1725 | + cryptoApproveAllowance() |
| 1726 | + .payingWith(DEFAULT_PAYER) |
| 1727 | + .addTokenAllowance(OWNER, FUNGIBLE_TOKEN, OWNER, 100L) |
| 1728 | + .signedBy(DEFAULT_PAYER, OWNER) |
| 1729 | + .hasKnownStatus(SUCCESS) |
| 1730 | + .via(tryApprovingTheSender), |
| 1731 | + cryptoApproveAllowance() |
| 1732 | + .payingWith(DEFAULT_PAYER) |
| 1733 | + .addTokenAllowance(OWNER, FUNGIBLE_TOKEN, SPENDER, 1000L) |
| 1734 | + .signedBy(DEFAULT_PAYER, OWNER) |
| 1735 | + .hasKnownStatus(SUCCESS) |
| 1736 | + .via(tryApprovingAboveBalance), |
| 1737 | + cryptoApproveAllowance() |
| 1738 | + .payingWith(DEFAULT_PAYER) |
| 1739 | + .addNftAllowance(OWNER, NON_FUNGIBLE_TOKEN, OWNER, false, List.of(1L)) |
| 1740 | + .signedBy(DEFAULT_PAYER, OWNER) |
| 1741 | + .hasKnownStatus(SPENDER_ACCOUNT_SAME_AS_OWNER) |
| 1742 | + .via(tryApprovingNFTToOwner), |
| 1743 | + cryptoApproveAllowance() |
| 1744 | + .payingWith(DEFAULT_PAYER) |
| 1745 | + .addNftAllowance(OWNER, NON_FUNGIBLE_TOKEN, SPENDER, false, List.of(1L, 2L, 3L, 4L)) |
| 1746 | + .signedBy(DEFAULT_PAYER, OWNER) |
| 1747 | + .hasKnownStatus(INVALID_TOKEN_NFT_SERIAL_NUMBER) |
| 1748 | + .via(tryApprovingNFTWithInvalidSerial)) |
| 1749 | + .then( |
| 1750 | + emptyChildRecordsCheck(tryApprovingTheSender, SUCCESS), |
| 1751 | + emptyChildRecordsCheck(tryApprovingAboveBalance, SUCCESS), |
| 1752 | + emptyChildRecordsCheck(tryApprovingNFTToOwner, SPENDER_ACCOUNT_SAME_AS_OWNER), |
| 1753 | + emptyChildRecordsCheck(tryApprovingNFTWithInvalidSerial, INVALID_TOKEN_NFT_SERIAL_NUMBER), |
| 1754 | + getAccountBalance(OWNER).hasTokenBalance(FUNGIBLE_TOKEN, 500L), |
| 1755 | + getAccountBalance(SPENDER).hasTokenBalance(FUNGIBLE_TOKEN, 0L), |
| 1756 | + getAccountBalance(OWNER).hasTokenBalance(NON_FUNGIBLE_TOKEN, 3L), |
| 1757 | + getAccountBalance(SPENDER).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0L)); |
| 1758 | + } |
| 1759 | + |
1681 | 1760 | @Override
|
1682 | 1761 | protected Logger getResultsLogger() {
|
1683 | 1762 | return log;
|
|
0 commit comments