Skip to content

Commit

Permalink
transfer_all tests, change in burning logic to allow anybody to burn …
Browse files Browse the repository at this point in the history
…if allowed by owner
  • Loading branch information
marc0olo committed Jul 13, 2023
1 parent 3855f71 commit fe986ee
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 15 deletions.
10 changes: 8 additions & 2 deletions development/smart-contracts/contracts/AENSWrapping.aes
Expand Up @@ -30,7 +30,7 @@ main contract AENSWrapping : IAEX141, IAENSWrapping =
, emergency_reward: int
, emergency_reward_block_window: int
, can_receive_from_others: bool
, burnable_if_empty: bool }
, burnable_if_expired_or_empty: bool }

record state =
{ owner: address
Expand Down Expand Up @@ -557,6 +557,11 @@ main contract AENSWrapping : IAEX141, IAENSWrapping =

// internal helper functions

function require_burnable_if_expired_or_empty(nft_id: int, owner: address) =
switch(get_nft_config(nft_id, owner))
None => () // allow burning if no config is set
Some(cfg) => require(cfg.burnable_if_expired_or_empty, "BURNING_NOT_ALLOWED")

function require_matching_pointer_limit(pointers: map(string, AENS.pointee)) =
require(Map.size(pointers) =< 32, "POINTER_LIMIT_EXCEEDED")

Expand Down Expand Up @@ -674,8 +679,9 @@ main contract AENSWrapping : IAEX141, IAENSWrapping =
put(state{ approvals = Map.delete(token_id, state.approvals) })

stateful function __burn_single(token_id: int) =
let owner = require_authorized(token_id)
let owner = require_exists(token_id)
require_expired_if_wrapped(token_id)
require_burnable_if_expired_or_empty(token_id, owner)
__remove_approval(token_id)
put(state{ balances[owner] @balance = balance - 1
, total_supply = state.total_supply - 1
Expand Down
Expand Up @@ -30,7 +30,7 @@ main contract AENSWrappingCustomTTL : IAEX141, IAENSWrapping =
, emergency_reward: int
, emergency_reward_block_window: int
, can_receive_from_others: bool
, burnable_if_empty: bool }
, burnable_if_expired_or_empty: bool }

record state =
{ owner: address
Expand Down Expand Up @@ -557,6 +557,11 @@ main contract AENSWrappingCustomTTL : IAEX141, IAENSWrapping =

// internal helper functions

function require_burnable_if_expired_or_empty(nft_id: int, owner: address) =
switch(get_nft_config(nft_id, owner))
None => () // allow burning if no config is set
Some(cfg) => require(cfg.burnable_if_expired_or_empty, "BURNING_NOT_ALLOWED")

function require_matching_pointer_limit(pointers: map(string, AENS.pointee)) =
require(Map.size(pointers) =< 32, "POINTER_LIMIT_EXCEEDED")

Expand Down Expand Up @@ -674,8 +679,9 @@ main contract AENSWrappingCustomTTL : IAEX141, IAENSWrapping =
put(state{ approvals = Map.delete(token_id, state.approvals) })

stateful function __burn_single(token_id: int) =
let owner = require_authorized(token_id)
let owner = require_exists(token_id)
require_expired_if_wrapped(token_id)
require_burnable_if_expired_or_empty(token_id, owner)
__remove_approval(token_id)
put(state{ balances[owner] @balance = balance - 1
, total_supply = state.total_supply - 1
Expand Down
35 changes: 24 additions & 11 deletions development/smart-contracts/test/aensWrappingTest.js
Expand Up @@ -58,7 +58,7 @@ describe('AENSWrapping', () => {
emergency_reward: 1_000_000n,
emergency_reward_block_window: 179_900n,
can_receive_from_others: true,
burnable_if_empty: false
burnable_if_expired_or_empty: false
}

before(async () => {
Expand Down Expand Up @@ -657,7 +657,7 @@ describe('AENSWrapping', () => {
emergency_reward: 1_000n,
emergency_reward_block_window: 1n,
can_receive_from_others: true,
burnable_if_empty: true
burnable_if_expired_or_empty: true
}
await contract.set_nft_config(1, nftConfig);

Expand Down Expand Up @@ -1191,10 +1191,6 @@ describe('AENSWrapping', () => {
contract.burn(tokenId + 1n))
.to.be.rejectedWith(`Invocation failed: "TOKEN_NOT_EXISTS"`);

await expect(
contract.burn(tokenId, { onAccount: otherAccount }))
.to.be.rejectedWith(`Invocation failed: "ONLY_OWNER_APPROVED_OR_OPERATOR_CALL_ALLOWED"`);

const wrapSingleTestName = "wrapSingleTestName.chain";
const preClaimTx = await aeSdk.aensPreclaim(wrapSingleTestName);
await aeSdk.aensClaim(wrapSingleTestName, preClaimTx.salt);
Expand All @@ -1204,6 +1200,17 @@ describe('AENSWrapping', () => {
await expect(
contract.burn(tokenId))
.to.be.rejectedWith(`Invocation failed: "WRAPPED_NAMES_NOT_EXPIRED"`);

// set global config to disallow burning of empty NFTs
await contract.set_global_config(globalConfig);
const tokenIdToBurn = (await contract.mint(aeSdk.selectedAddress)).decodedResult;
await expect(
contract.burn(tokenIdToBurn))
.to.be.rejectedWith(`Invocation failed: "BURNING_NOT_ALLOWED"`);

// passes after removing global config even if executed from other account
await contract.remove_global_config();
await contract.burn(tokenIdToBurn, { onAccount: otherAccount });
});

it('wrap_and_mint', async () => {
Expand Down Expand Up @@ -1259,7 +1266,7 @@ describe('AENSWrapping', () => {
.to.be.rejectedWith(`Invocation failed: "POINTER_LIMIT_EXCEEDED"`);
});

it('transfer_single & transfer_multiple', async () => {
it('transfer_single, transfer_multiple & transfer_all', async () => {
await claimNames(aensNames);
const namesDelegationSigs = await getDelegationSignatures(aensNames, contractId);
const sourceTokenId = (await contract.wrap_and_mint(namesDelegationSigs)).decodedResult;
Expand All @@ -1285,18 +1292,24 @@ describe('AENSWrapping', () => {
emergency_reward: 1_000n,
emergency_reward_block_window: 1n,
can_receive_from_others: false,
burnable_if_empty: false
burnable_if_expired_or_empty: false
}
// mint second target nft and set nft config to disallow receiving names and overrule global cfg
const secondTargetNftId = (await contract.mint(otherAccount.address, undefined, undefined, { onAccount: otherAccount })).decodedResult;
const secondTargetNftId = (await contract.mint(otherAccount.address, undefined, undefined, { onAccount: otherAccount })).decodedResult;
await contract.set_nft_config(secondTargetNftId, nftConfig, { onAccount: otherAccount });

await expect(
contract.transfer_multiple(sourceTokenId, secondTargetNftId, aensNames.slice(1)))
.to.be.rejectedWith(`Invocation failed: "RECEIVING_NAME_NOT_ALLOWED"`);

// passes because firstTargetNft can still receive
await contract.transfer_multiple(sourceTokenId, firstTargetNftId, aensNames.slice(1));
const emptySourceNftId = (await contract.mint(aeSdk.selectedAddress)).decodedResult;

await expect(
contract.transfer_all(emptySourceNftId, firstTargetNftId, aensNames.slice(1)))
.to.be.rejectedWith(`Invocation failed: "NO_NAMES_WRAPPED"`);

// passes because sourceTokenId has names wrapped and firstTargetNft can still receive
await contract.transfer_all(sourceTokenId, firstTargetNftId, aensNames.slice(1));
});
});

Expand Down

0 comments on commit fe986ee

Please sign in to comment.